얕은 자식 서브 모듈을 만드는 방법?


139

얕은 서브 모듈을 가질 수 있습니까? 나는 각각 긴 역사를 가진 여러 개의 서브 모듈을 가진 수퍼 프로젝트를 가지고 있기 때문에 모든 역사를 불필요하게 끌고 간다.

내가 찾은 것은 이 답변되지 않은 스레드 입니다.

이것을 구현하기 위해 git-submodule해킹 해야합니까 ?


1
" git submodule add/update"는 이제 서브 모듈 저장소를 얕게 복제 할 수 있습니다! 아래 내 답변
VonC

답변:


133

다가오는 git1.8.4 의 새로운 기능 (2013 년 7 월) :

" git submodule update"는 선택적으로 서브 모듈 저장소를 얕게 복제 할 수 있습니다.

(그리고 git 2.10 Q3 2016에서는이를 기록 할 수 있습니다 git config -f .gitmodules submodule.<name>.shallow true.
이 답변의 끝을 참조하십시오)

commit 275cd184d52b5b81cb89e4ec33e540fb2ae61c1f를 참조하십시오 .

추가 --depth 한 다음 복제 명령에 전달한다 "자식 서브 모듈"의 추가 및 업데이트 명령에 옵션을 선택합니다. 이것은 서브 모듈이 크며 최근 커밋에 관심이없는 경우에 유용합니다.

테스트가 추가되고 "서브 모듈 업데이트는 pwd에서 심볼릭 링크를 처리 할 수 ​​있습니다"의 나머지 테스트 파일에 맞게 일부 들여 쓰기 조정이 이루어졌습니다.

서명자 : Fredrik Gustafsson <iveqy@iveqy.com>
Acked-by : Jens Lehmann<Jens.Lehmann@web.de>

이것은 이것이 작동한다는 것을 의미합니다.

git submodule add --depth 1 -- repository path
git submodule update --depth -- [<path>...]

와:

--depth::

이 옵션은 addupdate명령에 유효 합니다.
지정된 수의 개정판으로 기록이 잘린 '얕은'복제본을 만듭니다.


atwyman 은 주석에 다음을 추가합니다 .

내가 알 수있는 한이 옵션은 master매우 밀접하게 추적되지 않는 하위 모듈에는 사용할 수 없습니다 . 깊이 1을 설정 submodule update하면 원하는 서브 모듈 커밋이 최신 마스터 인 경우에만 성공할 수 있습니다. 그렇지 않으면 " fatal: reference is not a tree"가 나타납니다 .

사실입니다.
즉, git 2.8 (2016 년 3 월)까지. 2.8을 사용하면 submodule update --depthSHA1에 원격 저장소 HEAD 중 하나에서 직접 연결할 수 있어도 성공할 수있는 기회가 한 번 더 있습니다.

Stefan Beller ( )의 commit fb43e31 (2016 년 2 월 24 일)을 참조하십시오 . 도움 : Junio ​​C Hamano ( ) . (의해 병합 - Junio C 하마노 -9671a76 커밋 2,016 26 이월)stefanbeller
gitster
gitster

하위 모듈 : sha1을 직접 가져 와서 필요한 sha1을 가져 오려고 더 열심히 시도

Gerrit에서 하위 모듈도 업데이트하는 변경 사항을 검토 할 때 일반적인 검토 방법은 패치를 로컬로 다운로드하여 선택하여 테스트하는 것입니다.
그러나 로컬에서 테스트 할 때 git submodule update서브 모듈의 해당 커밋이 아직 프로젝트 히스토리의 일부가 아니고 제안 된 변경 사항이므로 ' '이 (가) 올바른 서브 모듈 sha1을 가져 오지 못할 수 있습니다.

$sha1기본 페치의 일부가 아닌 경우 $sha1직접 페치를 시도합니다 . 그러나 일부 서버는 sha1에 의한 직접 가져 오기를 지원하지 않아 git-fetch빠르게 실패합니다.
여전히 누락 된 sha1이 체크 아웃 단계에서 나중에 실패로 이어 지므로 여기서 실패 할 수 있으므로 여기서 실패하면 얻을 수 있습니다.


MVG는 지적 코멘트에 하는 커밋 fb43e31 (자식 2.9 2016 2월)

나에게 보일 수있을 것입니다 fb43e31 커밋 요청을하여, 그래서 SHA1의 ID로 커밋없는 uploadpack.allowReachableSHA1InWantuploadpack.allowTipSHA1InWant서버의 설정은 아마이 작품의 여부에 영향을 미칠 것입니다.
나는 오늘 자식 목록에 게시물을 작성하여 얕은 서브 모듈을 사용하여 일부 시나리오, 즉 커밋도 태그 인 경우 어떻게 더 잘 작동 할 수 있는지 지적했다.
기다리고 보자.

이것이 fb43e31이 특정 SHA1에 대한 페치를 기본 분기에 대한 페치 후에 폴백으로 만든 이유라고 생각합니다.
그럼에도 불구하고“--depth 1”의 경우 조기에 중단하는 것이 합리적이라고 생각합니다. 나열된 ref가 요청 된 ref와 일치하지 않고 SHA1의 요청이 서버에서 지원되지 않으면 아무런 의미가 없습니다. 하위 모듈 요구 사항을 어느 쪽이든 만족시킬 수 없으므로 아무것도 가져 오지 않습니다.


2016 년 8 월 업데이트 (3 년 후)

Git 2.10 (2016 년 3 분기)을 사용하면

 git config -f .gitmodules submodule.<name>.shallow true

자세한 내용은 " 추가 무게가없는 Git 서브 모듈 "을 참조하십시오.


Git 2.13 (2017 년 2 분기 )은 Sebastian Schuberth ( )의 커밋 8d3047c (2017 년 4 월 19 일 )를 추가 합니다. ( 세바스티안 슈베르트와 합병)sschuberth
sschuberth -8d3047c 커밋 20 사월 2017)

이 서브 모듈의 복제는 얕은 복제 (역사 깊이가 1) 로 수행됩니다.

그러나 Ciro Santilli의견 과 세부 사항을 추가합니다 . 그의 답변에 대한 )을 추가합니다

shallow = trueon 은 대상 커밋이 브랜치에 의해 지시 된 경우에도,를 .gitmodules사용할 때 원격의 HEAD에 의해 추적 된 참조에만 영향을 미칩니다.--recurse-submodulesbranch = mybranch.gitmodules뿐만 아니라.


Git 2.20 (Q4 2018)은 서브 모듈 지원을 향상 시켰습니다.이 모듈은 blob에서 읽도록 업데이트되었습니다. HEAD:.gitmodules ..gitmodules 작업 트리에서 파일이 누락 .

참조 2b1257e 커밋 , 76e9bdc 커밋 (2018년 10월 25일), 및 b5c259f 커밋 , 23dd8f5 커밋 , b2faad4 커밋 , 2502ffc 커밋 , 996df4d 커밋 , d1b13df 커밋 , 45f5ef3 커밋 , bcbc780 커밋 에 의해 (2018년 10월 5일) 안토니오 Ospite을 ( ao2) .
(의해 병합 - Junio C 하마노 gitster-abb4824 커밋 2,018 13 년 11)

submodule: .gitmodules작업 트리에 없을 때 읽기 지원

.gitmodules파일이 작업 트리에 사용할 수없는 인덱스에서 현재 지점에서 콘텐츠를 사용해보십시오.
파일이 리포지토리의 일부이지만 어떤 이유로 파일이 체크 아웃되지 않은 경우 (예 : 스파 스 체크 아웃)가 여기에 해당합니다.

이렇게하면 최소한 ' git submodule'명령을 사용할 수 있습니다 .gitmodules 완전히 작업 트리를 채우지 않고 구성 파일을.

에 쓰기 .gitmodules 여전히 파일을 체크 아웃해야하므로 전화하기 전에 파일을 확인하십시오config_set_in_gitmodules_file_gently .

다음과 같은 경우에도 git-submodule.sh::cmd_add()" git submodule add"명령 의 결과 실패를 예상하기 위해 유사한 검사를 추가하십시오..gitmodules안전하게 쓸 수 없을 . 이렇게하면 명령이 저장소를 가짜 상태로 유지하지 못합니다 (예 : 서브 모듈 저장소가 복제되었지만.gitmodules 업데이트되지 않았습니다)config_set_in_gitmodules_file_gently 실패로 않았습니다).

또한 config_from_gitmodules()이제 전역 객체 저장소에 액세스하므로 전역 객체 저장소에 대한 동시 액세스로부터 함수를 호출하는 모든 코드 경로를 보호해야합니다.
현재이 경우에만 발생 builtin/grep.c::grep_submodules()하므로 전화 grep_read_lock() 관련된 코드를 하기 전에 호출하십시오.config_from_gitmodules() .

참고 :이 새로운 기능이 아직 제대로 작동하지 않는 드문 경우가 .gitmodules있습니다. 작업 트리에 없는 중첩 된 하위 모듈 .


참고 : Git 2.24 (Q4 2019)는 서브 모듈을 얕게 복제 할 때 가능한 segfault를 수정합니다.

Ali Utku Selen ( )의 commit ddb3c85 (2019 년 9 월 30 일)를 참조하십시오 . (가 합병 - Junio C 하마노 -678a9ca 커밋 2019 09 시월)auselen
gitster


힘내 2.25 (Q1 2020), git submodule update문서를 명확히합니다 .

Philippe Blain ( )의 commit f0e58b3 (2019 년 11 월 24 일)을 참조하십시오 . (의해 병합 - Junio C 하마노 -ef61045 커밋 2,019 05 십이)phil-blain
gitster

doc: 'git submodule update'가 누락 된 커밋을 가져옵니다.

도움 : Junio ​​C Hamano
도움 : Johannes Schindelin
서명 : Philippe Blain

수퍼 프로젝트에 기록 된 SHA-1을 찾을 수 없으면 ' git submoduleupdate' 는 서브 모듈 원격에서 새로운 커밋을 가져옵니다 . 이것은 문서에서 언급되지 않았습니다.


경고 : Git 2.25 (Q1 2020)에서는 " git clone --recurse-submodules"와 대체 객체 저장소 간의 상호 작용 이 잘못 설계되었습니다.

문서와 코드는 사용자가 실패를 볼 때보다 명확한 권장 사항을 작성하도록 배웠습니다.

Jonathan Tan ( )의 commit 4f3e57e , commit 10c64a0 (2019 년 12 월 02 일)을 참조하십시오 . ( Junio ​​C Hamano의해 병합 -- 커밋 5dd1d59 , 2019 년 12 월 10 일)jhowtan
gitster

submodule--helper: 치명적인 대체 오류에 대한 조언

작성자 : Jonathan Tan
Acked-by : Jeff King

에 일부 얕은 모듈이 정의 된 수퍼 프로젝트를 재귀 적으로 복제 한 .gitmodules다음 " --reference=<path>"로 다시 복제 하면 오류가 발생합니다. 예를 들면 다음과 같습니다.

git clone --recurse-submodules --branch=master -j8 \
  https://android.googlesource.com/platform/superproject \
  master
git clone --recurse-submodules --branch=master -j8 \
  https://android.googlesource.com/platform/superproject \
  --reference master master2

실패 :

fatal: submodule '<snip>' cannot add alternate: reference repository
'<snip>' is shallow

이 경우 또는 다른 수퍼 프로젝트의 대체물로 계산 된 대체물을 추가 할 수없는 경우 복제시 " submodule.alternateErrorStrategy"구성 옵션 구성 및 " --reference-if-able"대신 " " 사용 에 대해 조언하십시오 --reference.

자세한 내용은 다음과 같습니다.

Git 2.25 (Q1 2020)에서는 "git clone --recurse-submodules"와 대체 객체 저장소 간의 상호 작용이 잘못 설계되었습니다.

Doc: submodule.alternateErrorStrategy를 설명하십시오.

서명자 : Jonathan Tan
작성자 Acked-by : Jeff King

커밋 31224cbdc7 ( " clone: 재귀 및 참조 옵션 트리거 하위 모듈 대체", 2016-08-17, Git v2.11.0-rc0- 일괄 처리 # 1에 나열된 병합 ) 구성 옵션 " "및 "submodule.alternateLocationsubmodule.alternateErrorStrategy " .

수퍼 프로젝트에서 " submodule.alternateLocation"가 " "로 구성된 경우 superproject해당 수퍼 프로젝트의 하위 모듈이 복제 될 때마다 해당 하위 모듈의 유사한 대체 경로를 계산합니다.$GIT_DIR/objects/info/alternates 참조합니다.

" submodule.alternateErrorStrategy"옵션은 해당 대체를 참조 할 수없는 경우 발생하는 상황을 결정합니다.
그러나 해당 옵션이 "die"로 설정되지 않은 경우 ( 31224cbdc7 의 테스트에서 볼 수 있듯이) 대체가 지정되지 않은 것처럼 복제가 진행되는지는 확실하지 않습니다 .
따라서 적절하게 문서화하십시오.

설정 서브 모듈의 문서는 이제 포함 :

submodule.alternateErrorStrategy::

를 통해 계산 된 하위 모듈의 대체품으로 오류를 처리하는 방법을 지정합니다 submodule.alternateLocation.
가능한 값은 ignore, info, die.
기본값은 die입니다.
로 설정이 경우주의 ignoreinfo, 그리고 계산 된 대체에 오류가있는 경우, 복제 진행에는 대체 지정하지 않은 것처럼 .


2
와우 그것은 빠르다! 그건 그렇고 대답에 대한 Thx. 아, --depthshoudl도 논쟁을한다;)
Brice

3
나에게 보일 수있을 것입니다 fb43e31 커밋 요청을하여, 그래서 SHA1의 ID로 커밋없는 uploadpack.allowReachableSHA1InWantuploadpack.allowTipSHA1InWant서버의 설정은 아마이 작품의 여부에 영향을 미칠 것입니다. 필자는 커밋도 태그 인 경우 일부 시나리오에서 얕은 하위 모듈을 사용하여 어떻게 더 잘 작동 할 수 있는지 지적하면서 오늘 자식 목록에 게시물을 썼습니다 . 기다리고 보자.
MvG

2
얕은 옵션에 최근 추가로 .gitmodules는 않습니다 --depth 1밀접하게 마스터를 추적하지 않는 지점에 대한 옵션 작업을?
CMCDragonkai

2
@CiroSantilli 刘晓波 死 六四 事件 法轮功 정확성과 테스트에 감사드립니다. 가시성을 높이기 위해 답변에 귀하의 의견을 포함 시켰으며 귀하의 답변을 상향 조정했습니다.
VonC

2
현재 수행중인 방법이 무엇인지 명확하지 않습니다. 또한 누군가가 새로운 사본을 복제하거나 이러한 희소 한 하위 모듈 설정이 이러한 하위 모듈을 참조하는 저장소의 일부가 될 때마다이 모든 것이 필요한지 확실하지 않습니다 (예 : 각 새로운 복제 및 하위 모듈 업데이트로 인해 희소 한 하위 모듈 체크 아웃이 발생 함)
Pavel P

26

Git 2.9.0 은 하위 모듈 얕은 복제를 직접 지원하므로 이제 다음을 호출 할 수 있습니다.

git clone url://to/source/repository --recursive --shallow-submodules

2
이 옵션은 대부분의 약속이지만, 분기 또는 태그 중 하나에 의해 추적되지 않습니다 커밋 자식 2.14.1 서브 모듈에 실패 stackoverflow.com/a/47374702/895245
郝海东冠状病六四事件法轮功치로 틸리

1
@CiroSantilli 刘晓波 死 六四 事件 法轮功 git 서버도 업데이트하세요
KindDragon

덕분에, 나는 서버없이 로컬 테스트, 내가 :-) 업데이트 할 수 없습니다 GitHub의에 한
치로 틸리郝海东冠状病六四事件法轮功

1
git 2.20을 사용하는 것과 동일한 문제가 있는데 하위 모듈이 분기의 끝에 있지 않으면 작동하지 않습니다.
Zitrax

16

Ryan의 대답에 따라 모든 하위 모듈을 반복하고 얕은 복제를 수행하는이 간단한 스크립트를 만들 수있었습니다.

#!/bin/bash
git submodule init
for i in $(git submodule | sed -e 's/.* //'); do
    spath=$(git config -f .gitmodules --get submodule.$i.path)
    surl=$(git config -f .gitmodules --get submodule.$i.url)
    git clone --depth 1 $surl $spath
done
git submodule update

나는 fatal: reference is not a tree: 88fb67b07621dfed054d8d75fd50672fb26349df각 서브 모듈에 대해
knocte


1
@knocte : 2010 년에 답을 썼습니다. 상황이 바뀌 었습니다. 모든 사람이 자신의 답변을 모두 유지할 것을 기대할 수는 없습니다. 현재 유효한 답변을 수락 된 것으로 표시했습니다.
Mauricio Scheffer

13
@knocte 이것이 Stackoverflow에 기여하지 않은 이유 중 하나입니다. 사람들은 이러한 비현실적인 기대를 가지고 있습니다. 내 1637 답변 중 하나를 유지하는 것은 전일제 일 것입니다. 그리고 의견도 있습니다. 그 의견도 유지해야한다고 생각합니까? 날짜를 살펴보십시오. 그것이 날짜입니다. List 대신 ArrayList를 사용하는 코드로 2002 년부터 일부 .NET 블로그를 읽는다면 그것을 사용 하시겠습니까? 작성자가 자신의 게시물을 업데이트하도록 요구 하시겠습니까? 여기에도 같은 원칙이 적용됩니다.
Mauricio Scheffer

1
s / statusquo / progress /
knocte

8

git-submodule "source"를 통해 git submodule add이미 저장소가있는 서브 모듈을 처리 할 수있는 것처럼 보입니다 . 이 경우 ...

$ git clone $remote1 $repo
$ cd $repo
$ git clone --depth 5 $remotesub1 $sub1
$ git submodule add $remotesub1 $sub1
#repeat as necessary...

필요한 커밋이 서브 모듈 저장소에 있는지 확인하고 적절한 --depth를 설정했는지 확인하십시오.

편집 : 여러 수동 하위 모듈 클론을 사용하고 단일 업데이트를 수행 할 수 있습니다.

$ git clone $remote1 $repo
$ cd $repo
$ git clone --depth 5 $remotesub1 $sub1
#repeat as necessary...
$ git submodule update

5
이제 git 1.8.0의 경우 더 이상 저장소 내부의 저장소를 복제 할 수 없습니다. 따라서이 솔루션은 더 이상 작동하지 않습니다.
Bohr

7

Git 2.14.1 기준 버그 / 예기치 못한 / 불쾌한 행동 요약

  1. shallow = true에서 대상 커밋이 지점에서 가리키는 경우에도 원격 하위 모듈 중 필요한 커밋을 가리키는 경우 .gitmodules에만 영향을 미칩니다 .git clone --recurse-submodulesHEADbranch = mybranch.gitmodules 뿐만 아니라.

    현지 테스트 스크립트 . GitHub 2017-11에서 동일한 동작 HEAD은 기본 분기 저장소 설정에 의해 제어됩니다.

    git clone --recurse-submodules https://github.com/cirosantilli/test-shallow-submodule-top-branch-shallow
    cd test-shallow-submodule-top-branch-shallow/mod
    git log
    # Multiple commits, not shallow.
    
  2. git clone --recurse-submodules --shallow-submodules 메시지가있는 분기 또는 태그가 커밋을 참조하지 않으면 실패합니다. error: Server does not allow request for unadvertised object .

    현지 테스트 스크립트 . GitHub에서 동일한 동작 :

    git clone --recurse-submodules --shallow-submodules https://github.com/cirosantilli/test-shallow-submodule-top-sha
    # error
    

    나는 또한 메일 링리스트 ( https://marc.info/?l=git&m=151863590026582&w=2)를 물었고 다음 과 같이 답장했다 :

    이론적으로 이것은 쉬워야한다. :)

    실제로 불행히도 그렇게 많지 않습니다. 복제는 지점의 최신 팁 (일반적으로 마스터)을 가져 오기 때문입니다. 복제본에는 원하는 정확한 sha1을 지정하는 메커니즘이 없습니다.

    와이어 프로토콜은 정확한 sha1 요청을 지원하므로 다루어야합니다. (주의 : 서버 운영자가 github이 AFAICT하지 않은 uploadpack.allowReachableSHA1InWant를 활성화 한 경우에만 작동합니다)

    git-fetch를 사용하면 임의의 sha1을 가져올 수 있으므로 해결 방법으로 "git submodule update"를 사용하여 재귀 복제 후 페치를 실행할 수 있습니다. 초기 복제 후 페치를 사용합니다.

TODO 테스트 : allowReachableSHA1InWant.


하위 모듈에 대해 분리 된 HEAD 커밋 해시를 체크 아웃하는 간단한 방법이없고 다운 스트림 사용자 git clone --recursive가 해당 커밋 만 가져 오는 것처럼 보입니다 .
CMCDragonkai

3

서브 모듈의 표준 위치가 원격입니까? 그렇다면 한 번 복제해도 괜찮습니까? 다시 말해, 빈번한 서브 모듈 (재) 클론의 낭비되는 대역폭으로 인해 얕은 클론을 원하십니까?

얕은 디스크를 사용하여 로컬 디스크 공간을 절약하려면 Ryan Graham의 대답이 좋은 방법으로 보입니다. 저장소가 얕도록 수동으로 저장소를 복제하십시오. 유용하다고 생각되면 git submodule지원 하도록 조정 하십시오. 목록으로 이메일 보내기 요청 십시오 (구현 조언, 인터페이스에 대한 제안 등). 내 의견으로는, 사람들은 Git을 건설적인 방식으로 향상시키고 자하는 잠재적 인 기여자들을 상당히지지하고 있습니다.

각 서브 모듈의 전체 복제를 한 번 수행하고 (그리고 나중에 최신 상태로 유지하기 위해 가져 오는 경우), 로컬 객체 저장소 (예 : Git 1.6.4 이상에 있음) --reference옵션을 사용하여 시도 할 수 있습니다 git submodule update만들 --mirror정규 서브 모듈 저장소의 클론을 한 후 사용 --reference)이 지역 클론 지점으로 서브 모듈에. 사용하기 전에 git clone --reference/ 에 대해 읽어보십시오 . 미러 참조와 관련하여 유일하게 발생할 수있는 문제는 빨리 감기가 아닌 업데이트를 가져 오는 경우입니다 (참조 로그를 활성화하고 만료 창을 확장하여 문제를 일으킬 수있는 중단 된 커밋을 유지하는 데 도움이 될 수 있음). 당신은 문제가 없어야합니다git clone --shared--reference

  • 로컬 서브 모듈 커밋을하지 않거나
  • 정식 리포지토리가 게시 할 수있는 비 빨리 감기에 의해 커밋 된 커밋은 로컬 하위 모듈 커밋의 조상이 아니거나
  • 정식 하위 모듈 리포지토리에 게시 될 수있는 빠른 내용을 기반으로 로컬 하위 모듈 커밋을 다시 기반으로 유지하는 데 부지런합니다.

이런 식으로 작업하고 작업 트리에서 로컬 하위 모듈 커밋을 수행 할 가능성이있는 경우 체크 아웃 된 하위 모듈에서 참조하는 중요한 객체가 아닌 자동화 된 시스템을 만드는 것이 좋습니다. 미러 리포지토리에 매달린 상태 (있는 경우 발견 된 리포지토리에 복사)

등 그리고, git clone맨 페이지는 말한다, 사용하지 않는 --reference당신이이 의미를 이해하지 않는 경우.

# Full clone (mirror), done once.
git clone --mirror $sub1_url $path_to_mirrors/$sub1_name.git
git clone --mirror $sub2_url $path_to_mirrors/$sub2_name.git

# Reference the full clones any time you initialize a submodule
git clone $super_url super
cd super
git submodule update --init --reference $path_to_mirrors/$sub1_name.git $sub1_path_in_super
git submodule update --init --reference $path_to_mirrors/$sub2_name.git $sub2_path_in_super

# To avoid extra packs in each of the superprojects' submodules,
#   update the mirror clones before any pull/merge in super-projects.
for p in $path_to_mirrors/*.git; do GIT_DIR="$p" git fetch; done

cd super
git pull             # merges in new versions of submodules
git submodule update # update sub refs, checkout new versions,
                     #   but no download since they reference the updated mirrors

또는, 대신 로컬 미러를 하위 모듈의 소스로 사용 --reference하는 기본 하드 링크 기능과 함께 미러 클론을 사용할 수 있습니다 git clone. 새로운 수퍼 프로젝트 클론 에서 로컬 미러를 가리 키도록 git submodule init서브 모듈 URL을 편집 .git/config한 다음 수행하십시오.git submodule update. 하드 링크를 얻으려면 기존의 체크 아웃 된 하위 모듈을 복제해야합니다. 미러로 한 번만 다운로드 한 다음 체크 아웃 된 하위 모듈로 로컬에서 가져와 대역폭을 절약 할 수 있습니다. 하드 링크는 디스크 공간을 절약합니다 (페치가 체크 아웃 된 서브 모듈 객체 저장소의 여러 인스턴스에 걸쳐 페치가 누적되고 복제되는 경향이 있지만, 체크 아웃 된 서브 모듈을 미러에서 정기적으로 복제하여 디스크 공간 절약을 다시 확보 할 수 있습니다) 하드 링크).


2

블리드 엣지에서 실행되지 않을 때 약간 다른 버전을 만들었습니다. 모든 프로젝트가 아닙니다. 표준 하위 모듈 추가가 작동하지 않거나 위의 스크립트가 작동하지 않았습니다. 따라서 태그 참조에 대한 해시 조회를 추가했으며 태그 참조가 없으면 전체 복제본으로 돌아갑니다.

#!/bin/bash
git submodule init
git submodule | while read hash name junk; do
    spath=$(git config -f .gitmodules --get submodule.$name.path)
    surl=$(git config -f .gitmodules --get submodule.$name.url)
    sbr=$(git ls-remote --tags $surl | sed -r "/${hash:1}/ s|^.*tags/([^^]+).*\$|\1|p;d")
    if [ -z $sbr ]; then
        git clone $surl $spath
    else
        git clone -b $sbr --depth 1 --single-branch $surl $spath
    fi
done
git submodule update 

2

특정 개정 / 변경 세트로 git 저장소를 복제하는 방법에 대한 참조 ?

하위 모듈 참조가 마스터에서 멀어 질 때 문제가없는 간단한 스크립트를 작성했습니다

git submodule foreach --recursive 'git rev-parse HEAD | xargs -I {} git fetch origin {} && git reset --hard FETCH_HEAD'

이 문장은 참조 된 하위 모듈 버전을 가져옵니다.

빠르지 만 서브 모듈에서 편집 내용을 커밋 할 수는 없습니다 ( https://stackoverflow.com/a/17937889/3156509 전에 얕은 부분을 가져와야합니다 )

전부:

#!/bin/bash
git submodule init
git submodule foreach --recursive 'git rev-parse HEAD | xargs -I {} git fetch origin {} && git reset --hard FETCH_HEAD'
git submodule update --recursive

1

하위 모듈의 얕은 복제는 특정 개정 / 변경 세트에서 스냅 샷하기 때문에 완벽합니다. 웹 사이트에서 zip을 쉽게 다운로드 할 수 있으므로 스크립트를 사용해 보았습니다.

#!/bin/bash
git submodule deinit --all -f
for value in $(git submodule | perl -pe 's/.*(\w{40})\s([^\s]+).*/\1:\2/'); do
  mysha=${value%:*}
  mysub=${value#*:}
  myurl=$(grep -A2 -Pi "path = $mysub" .gitmodules | grep -Pio '(?<=url =).*/[^.]+')
  mydir=$(dirname $mysub)
  wget $myurl/archive/$mysha.zip
  unzip $mysha.zip -d $mydir
  test -d $mysub && rm -rf $mysub
  mv $mydir/*-$mysha $mysub
  rm $mysha.zip
done
git submodule init

git submodule deinit --all -f 스크립트를 재사용 할 수있는 서브 모듈 트리를 지 웁니다.

git submodule에서 40 개의 문자 sha1과 그에 해당하는 경로를 검색합니다 .gitmodules. I는 콜론으로 구분 정보를 연결할로 값을 구분 변수 변환을 채용하는 펄을 사용 mysha하고 mysub.

sha1을 다운로드하고 urlin.gitmodules 를 상호 연관시키는 경로가 필요하기 때문에 이는 중요한 키 입니다.

일반적인 하위 모듈 항목이 주어지면 :

[submodule "label"]
    path = localpath
    url = https://github.com/repository.git

myurl키를 path =누른 다음 값을 얻기 위해 2 줄을 찾습니다. 이 방법은 일관되게 작동하지 않으며 수정이 필요할 수 있습니다. url grep .git은 last /와 일치하는 모든 유형 참조 를 제거합니다 ..

mydir디렉토리에서 하위 모듈 이름으로 이어지는 mysub최종 결과 는 빼기 /name입니다.

다음은 wget다운로드 가능한 zip 아카이브 URL 형식입니다. 향후 변경 될 수 있습니다.

mydir서브 모듈 경로에 지정된 서브 디렉토리가 될 파일의 압축을 푸십시오 . 결과 폴더는 url- 의 마지막 요소가 sha1됩니다.

서브 모듈 경로에 지정된 서브 디렉토리가 있는지 확인하고 추출 된 폴더의 이름을 바꿀 수 있도록 제거하십시오.

mv sha1을 포함하는 추출 된 폴더의 이름을 올바른 서브 모듈 경로로 바꾸십시오.

다운로드 한 zip 파일을 삭제하십시오.

서브 모듈 초기화

이것은 솔루션이 아니라 WIP 개념 증명입니다. 작동하면 지정된 변경 세트에서 하위 모듈의 얕은 복제가 생성됩니다.

저장소가 서브 모듈을 다른 커밋으로 옮기면 업데이트 할 스크립트를 다시 실행하십시오.

이와 같은 스크립트가 유용 할 수있는 유일한 시간은 소스 프로젝트의 비협조적인 로컬 빌드입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.