힘내 하위 모듈 업데이트


242

Git 서브 모듈 업데이트 문서 에서 다음의 의미가 무엇인지 확실하지 않습니다 .

... --rebase또는 --merge지정 하지 않으면 하위 모듈 HEAD를 분리 합니다 ...

사물 은 어떻게 --rebase/ --merge변경합니까?

내 주요 사용 사례는 중앙 저장소를 여러 개 갖는 것인데, 하위 저장소를 통해 다른 저장소에 포함시킬 것입니다. 원래 위치 또는 내장 리포지토리 (하위 모듈을 통해 사용하는 리포지토리)에서 이러한 중앙 리포지토리를 개선하고 싶습니다.

  • 이러한 하위 모듈 내에서 일반 리포지토리에서와 같이 브랜치 / 수정을 만들고 푸시 / 풀을 사용할 수 있습니까?
  • 서브 태그 참조 커밋을 말 (태그 된) 1.0에서 1.1로 (원래 저장소의 헤드가 이미 2.0 임에도 불구하고) 어떻게 진행합니까?

"분리 된 헤드"주제에 대한 실제 예제 (서브 모듈과 관련이 없지만 여전히 여전히 stackoverflow.com/questions/964876/head-and-orighead-in-gitstackoverflow.com/questions/237408/… 참조) )
VonC

"주 프로젝트 내에서 서브 모듈의 내용을 수정할 수 없습니다": 예, true. 그리고 나는 명백한 모순 (수정할 수없는 서브 모듈, 여전히 메인 프로젝트 리포지토리에서 수정할 수 있습니다!)에 대해 약간의 설명을하기 위해 내 대답을 편집했습니다.
VonC

답변:


304

GitPro 페이지 는 자식 서브 모듈 업데이트의 결과를 훌륭하게 요약합니다.

를 실행 git submodule update하면 특정 버전의 프로젝트가 체크 아웃되지만 분기에는 포함되지 않습니다. 이를 헤드 분리라고합니다. 이는 HEAD 파일이 기호 참조가 아닌 커밋을 직접 가리키는 것을 의미합니다.
문제는 일반적으로 분리 된 헤드 환경에서 작업하기를 원하지 않는다는 것 입니다. 변경 사항을 잃기 쉽기 때문 입니다.
초기 하위 모듈 업데이트를 수행하고, 작업 할 분기를 만들지 않고 해당 하위 모듈 디렉토리에서 커밋 한 다음 그 동안 커밋하지 않고 슈퍼 프로젝트에서 git 하위 모듈 업데이트를 다시 실행하면 Git이 변경 사항을 알리지 않고 덮어 씁니다. 기술적으로는 작업을 잃지 않지만 지점을 가리 키지 않으므로 검색하기가 다소 어려울 수 있습니다.


2013 년 3 월 참고 :

" git submodule tracking latest " 에서 언급했듯이 , 이제 서브 모듈 (git1.8.2)은 분기를 추적 할 수 있습니다.

# add submodule to track master branch
git submodule add -b master [URL to Git repo];

# update your submodule
git submodule update --remote 
# or (with rebase)
git submodule update --rebase --remote

" git submodule update --remotevsgit pull "를 참조하십시오 .

MindTooth답변 은 수동 업데이트 (로컬 구성 없음)를 보여줍니다.

git submodule -q foreach git pull -q origin master

두 경우 모두 하위 모듈 참조 ( gitlink , 상위 repo 인덱스특수 항목) 가 변경 되며 기본 리포지토리에서 해당 참조를 추가, 커밋 및 푸시해야합니다.
다음에 해당 상위 저장소를 복제 할 때 새 SHA1 참조를 반영하도록 서브 모듈을 채 웁니다.

이 답변의 나머지 부분에서는 클래식 하위 모듈 기능 ( 고정 커밋에 대한 참조 , 하위 모듈 개념의 모든 요점)에 대해 자세히 설명합니다 .


이 문제를 피하려면 git checkout -b work 또는 이와 동등한 것으로 하위 모듈 디렉토리에서 작업 할 때 분기를 작성하십시오. 서브 모듈 업데이트를 두 번 수행해도 여전히 작업을 되돌릴 수 있지만 최소한 포인터를 다시 가져와야합니다.

하위 모듈이있는 분기를 전환하는 것도 까다로울 수 있습니다. 새 분기를 작성하고 거기에 하위 모듈을 추가 한 다음 해당 하위 모듈이없는 분기로 다시 전환하면 하위 모듈 디렉토리는 추적되지 않은 디렉토리로 계속 유지됩니다.


따라서 귀하의 질문에 답변하십시오 :

정기적 인 리포지토리에서와 같이 브랜치 / 수정을 생성하고 푸시 / 풀을 사용할 수 있습니까? 또는주의해야 할 사항이 있습니까?

브랜치를 만들고 수정을 푸시 할 수 있습니다.

경고 ( Git Submodule Tutorial에서 ) : 서브 모듈 변경 사항을 참조하는 수퍼 프로젝트에 대한 변경 사항을 공개 (푸시)하기 전에 항상 서브 모듈 변경 사항을 공개 (푸시)하십시오. 하위 모듈 변경 사항을 게시하지 않으면 다른 사용자가 리포지토리를 복제 할 수 없습니다.

서브 태그 참조 커밋을 말 (태그) 1.0에서 1.1로 어떻게 진행합니까 (원래 repo의 헤드가 이미 2.0 임에도 불구하고)

" 하위 모듈 이해하기 " 페이지 가 도움이 될 수 있습니다

Git 서브 모듈은 두 개의 움직이는 부분을 사용하여 구현됩니다.

  • .gitmodules파일
  • 특별한 종류의 나무 객체.

이들은 함께 특정 저장소의 특정 개정판을 삼각 측량하여 프로젝트의 특정 위치로 체크 아웃합니다.


로부터 자식 서브 모듈 페이지

메인 프로젝트 내에서 서브 모듈의 내용을 수정할 수 없습니다

100 % 정확 : 서브 모듈을 수정할 수 없으며 커밋 중 하나만 참조하십시오.

이것이 메인 프로젝트 내에서 서브 모듈을 수정할 때 다음과 같은 이유입니다.

  • 하위 모듈 에서 (업스트림 모듈로) 커밋하고 푸시해야합니다.
  • 그런 다음 기본 프로젝트로 이동하여 다시 커밋하십시오 (주 프로젝트가 방금 생성하고 푸시 한 새로운 하위 모듈 커밋을 참조하기 위해)

하위 모듈을 사용하면 구성 요소 기반 접근 방식 개발 을 할 수 있습니다 . 여기서 주 프로젝트는 다른 구성 요소 (여기서는 "하위 모듈로 선언 된 다른 Git 리포지토리")의 특정 커밋 만 참조합니다.

하위 모듈은 주요 프로젝트 개발주기에 구속되지 않는 다른 Git 저장소에 대한 마커 (커밋)입니다.이 모듈 ( "다른"Git 저장소)은 독립적으로 발전 할 수 있습니다.
필요한 다른 커밋에서 다른 리포지토리를 선택하는 것은 메인 프로젝트에 달려 있습니다.

그러나 편의상 주 프로젝트에서 해당 하위 모듈 중 하나를 직접 수정하려면 먼저 Git을 사용하여 해당 하위 모듈 수정 사항을 원래 Git 저장소에 게시 한 다음 주 프로젝트를 참조하십시오. 상기 서브 모듈 의 새로운 버전.

그러나 주요 아이디어는 다음과 같습니다.

  • 자신의 수명주기가
  • 자신의 태그 세트를 가지고
  • 자체 개발

기본 프로젝트에서 참조하는 특정 커밋 목록은 구성을 정의합니다 (이것은 단순한 버전 제어 시스템을 포괄 하는 구성 관리의 모든 것입니다 )

메인 프로젝트 와 동시에 컴포넌트를 개발할 수 있다면 (메인 프로젝트를 수정하면 서브 디렉토리를 수정해야하고 그 반대도 마찬가지이므로) 더 이상 "서브 모듈"이 될 것입니다. 하위 트리 병합 (또한 cvs에서 분산 리포지토리로 레거시 코드베이스 전송 질문에 나와 있음 ), 두 Git 리포지토리 의 내역을 연결합니다.

그것이 Git 서브 모듈의 본질을 이해하는 데 도움이됩니까?


77
와. 신입생이 그들의 svn : externals를 고수하는 것을 두려워하기에 충분할 정도로 기본적으로 간단한 것에 대한 그 긴 설명이 충분해야한다. ;-)
conny

2
@conny :하지만 " git 서브 모듈이 svn externals와 호환되지 않는 이유는 무엇입니까? " 에서 자세히 설명했듯이 서브 모듈은 근본적으로 다르며 호환되지 않습니다 svn:externals.
VonC

1
죄송합니다, 내 자신의 질문에 대답하기 위해, 서브 모듈에 cd'ing을 수집하고 git checkout sha 또는 git pull / fetch가 잘 수행됩니다. 그런 다음 로컬 저장소에서 업데이트를 커밋하십시오.
Henrik

2
@hced : 다음을 사용하여 한 번에 모든 하위 모듈을 칠 수도 있습니다git submodule foreach
Dav Clark

1
.. 아직받지 못했습니다. 웹 어딘가에 더 쉬운 설명이 있습니까?
eugene

135

각 하위 모듈을 업데이트하려면 리포지토리의 루트에서 다음 명령을 호출 할 수 있습니다.

git submodule -q foreach git pull -q origin master

-q 옵션을 제거 하여 전체 프로세스를 따를 수 있습니다 .


15
git submodule update --init --recursive루트에서 방금 실행 하면 모든 것을 재귀 적으로 가져 와서 아직 그렇지 않은 경우 초기화합니다.
Sam Soffes

10
@SamSoffes 완전히 다른 목적으로 사용됩니다. 서브 모듈을 업데이트하면 현재 커밋 할 때 서브 모듈을 체크 아웃합니다 (최신 커밋 일 필요는 없음). 위 답변의 솔루션은 각 하위 모듈의 커밋을 출발지 / 마스터의 최신 HEAD로 업데이트합니다.
indragie

7
나의 새로운 방법git submodule update --rebase --remote
MindTooth

19

--rebasevs. --merge옵션 을 해결하려면 :

수퍼 리포지토리 A와 하위 모듈 B가 있고 하위 모듈 B에서 일부 작업을 수행하려고한다고 가정합시다.

git submodule update

HEAD-less 상태이므로이 시점에서 수행 한 커밋은 복구하기가 어렵습니다. 하위 모듈 B의 새 분기에 대한 작업을 시작했습니다.

cd B
git checkout -b bestIdeaForBEver
<do work>

한편, 프로젝트 A의 다른 누군가는 최신 버전의 B가 실제로 A에게 가치가 있다고 결정했습니다. 습관적으로, 가장 최근의 변경 사항을 병합하고 하위 모듈을 업데이트하십시오.

<in A>
git merge develop
git submodule update

아뇨! 아마도 B는 B의 새로운 팁 또는 다른 커밋과 관련된 SHA를 가리키고 있기 때문에 다시 헤드리스 상태로 돌아 왔습니다. 당신이 가지고 있다면 :

git merge develop
git submodule update --rebase

Fast-forwarded bestIdeaForBEver to b798edfdsf1191f8b140ea325685c4da19a9d437.
Submodule path 'B': rebased into 'b798ecsdf71191f8b140ea325685c4da19a9d437'

이제 B에 대한 최고의 아이디어는 새로운 커밋에 기반을 두 었으며, 더 중요한 것은 여전히 ​​헤드리스 상태가 아닌 B의 개발 브랜치에 있다는 것입니다.

(는 --mergeafterUpdateSHA 위에 변경 사항을 리베이스 반대로, 당신의 작업 지점에 afterUpdateSHA에 beforeUpdateSHA 변경 사항을 병합합니다.)


7

Git 1.8.2에는 새로운 동작 옵션 인이 기능 --remote을 통해 정확하게이 동작을 수행 할 수 있습니다. 달리는

git submodule update --rebase --remote

각 하위 모듈의 업스트림에서 최신 변경 사항을 가져 와서 리베이스하고 하위 모듈의 최신 개정을 확인합니다. 으로 문서의 풋 그것은 :

--먼

이 옵션은 update 명령에만 유효합니다. 수퍼 프로젝트의 기록 된 SHA-1을 사용하여 서브 모듈을 업데이트하는 대신 서브 모듈의 원격 추적 브랜치 상태를 사용하십시오.

이것은 git pull각 하위 모듈에서 실행하는 것과 동일하며 일반적으로 정확히 원하는 것입니다.

(이 답변 에서 복사되었습니다 .)


잘 정립되고 정답이있는 오래된 질문에 대답하기로 결정한 경우, 늦은 시간에 새 답변을 추가하면 크레딧을 얻지 못할 수 있습니다. 독특한 새로운 정보가 있거나 다른 답변이 모두 잘못되었다고 확신하는 경우, 반드시 새로운 답변을 추가하되, 질문이 일반적으로 제기 된 후 오랫동안 동일한 기본 정보를 제공하는 '아직 다른 답변'을 얻으십시오. ' 당신은 많은 신용을 얻습니다. 이것이 무엇을하는지에 대한 설명은 없습니다 – 외부 문서에 대한 링크조차도 충분하지 않습니다.
Jonathan Leffler

2
다른 답변 이이 명령을 가지고 있지 않기 때문에 "아직 다른 대답"은 아닙니다 (나를 잘못 증명합니다). 다른 답변은 저에게 효과가 없었습니다.이 의견 은 그렇게 했으므로 원래 소유자에게 신용을 제공하면서 답변으로 게시하기로 결정했습니다. 따라서 downvote 제거를 고려하십시오.
Iulian Onofrei

있다 코멘트 에 의해 MindTooth 이 그들이 지금 무엇을 말하는 2015은. 이것이 무엇을하는지에 대한 설명은 없습니다 (MindTooth에 대해서는 언급하고 있지만 그 의미가 무엇인지에 대한 실제 설명은 없습니다. 왜 이것이 좋은 생각인지 말하지 않습니다. 당신은 어떤 경고도주지 않습니다. 내 생각에 이것은 해결하는 것보다 더 많은 질문을 제기하기 때문에 유용한 답변이 아닙니다.
Jonathan Leffler

1
그로 인해 작동 하지 않고 작동 한다는 것을 의미 했습니다. 더 많은 사람들이이 답변을 볼 수 있다면, 그것이 효과가 있기 때문에 기쁠 것 입니다. 이와 같은 경우 대부분의 사람들은 구현 방법이 아닌 git 하위 모듈을 업데이트하는 명령을 알고 싶어합니다.
Iulian Onofrei

내가 잘못을 증명 또한,에 대한 답변 편집 stackoverflow.com/questions/1979167/git-submodule-update/...~~V을 !
Iulian Onofrei
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.