Git 서브 모듈을 추가 할 때 브랜치 / 태그를 어떻게 지정할 수 있습니까? 후, 새로운 복제 된 저장소

어떻게 git submodule add -b작동합니까?

특정 브랜치가있는 서브 모듈을 추가 한 후, 새로운 복제 된 저장소 (after git submodule update --init)는 브랜치 자체가 아닌 특정 커밋에있게됩니다 ( git status서브 모듈의 “현재 브랜치에 없음”).

나는에 대한 정보 찾을 수없는 .gitmodules.git/config, 서브 모듈의 지점 또는 특정 커밋에 대한을 어떻게 수행 망할 놈의 그림을 알아?

또한 브랜치 대신 태그를 지정할 수 있습니까?

버전 1.6.5.2를 사용하고 있습니다.



답변

참고 : Git 1.8.2는 분기를 추적 할 수있는 가능성을 추가했습니다. 아래 답변 중 일부를 참조하십시오.


이것에 익숙해지면 약간 혼란 스럽지만 하위 모듈은 가지가 아닙니다. 그것들은 당신이 말했듯이 서브 모듈 저장소의 특정 커밋에 대한 포인터 일뿐입니다.

즉, 다른 사람이 저장소를 체크 아웃하거나 코드를 가져오고 하위 모듈 업데이트를 수행하면 하위 모듈이 해당 커밋에 대해 체크 아웃됩니다.

자주 변경되지 않는 서브 모듈에 유용합니다. 프로젝트의 모든 사람이 동일한 커밋에서 서브 모듈을 가질 수 있기 때문입니다.

서브 모듈을 특정 태그로 이동 시키려면 :

cd submodule_directory
git checkout v1.0
cd ..
git add submodule_directory
git commit -m "moved submodule to v1.0"
git push

그런 다음 submodule_directory를 해당 태그로 변경하려는 다른 개발자가이를 수행합니다.

git pull
git submodule update --init

git pull서브 모듈 디렉토리가 커밋하는 변경 git submodule update실제로 새 코드에 병합됩니다.


답변

여기에 실제로 다른 답변의 대기업 인 답변을 추가하고 싶지만 더 완벽 할 수 있습니다.

이 두 가지가있을 때 Git 서브 모듈이 있다는 것을 알고 있습니다.

  1. 다음 .gitmodules과 같은 항목이 있습니다.

    [submodule "SubmoduleTestRepo"]
        path = SubmoduleTestRepo
        url = https://github.com/jzaccone/SubmoduleTestRepo.git
    
  2. Git 저장소에 서브 모듈 오브젝트 (이 예제에서는 SubmoduleTestRepo)가 있습니다. GitHub 는 이것을 “서브 모듈”객체로 보여줍니다. 또는 git submodule status명령 줄에서 수행하십시오 . Git 하위 모듈 객체는 특별한 종류의 Git 객체이며 특정 커밋에 대한 SHA 정보를 보유합니다.

    를 수행 할 때마다 git submodule update서브 모듈이 커밋의 컨텐츠로 채워집니다. 의 정보로 인해 커밋을 찾을 수있는 위치를 알고 .gitmodules있습니다.

    이제 파일에 -b한 줄만 추가하면 .gitmodules됩니다. 따라서 동일한 예를 따르면 다음과 같습니다.

    [submodule "SubmoduleTestRepo"]
        path = SubmoduleTestRepo
        url = https://github.com/jzaccone/SubmoduleTestRepo.git
        branch = master
    

    참고 :.gitmodules 파일에서는 분기 이름 만 지원 되지만 SHA 및 TAG는 지원되지 않습니다! (대신에 각 모듈에 대한 브랜치 커밋은 git add .예를 들어 ” “를 사용하여 추적하고 업데이트 할 수 있으며 매번 파일 git add ./SubmoduleTestRepo을 변경할 필요가 없습니다 .gitmodules)

    서브 모듈 객체가 여전히 특정 커밋을 가리키고 있습니다. 이 -b옵션을 구입 하는 유일한 방법 --remote은 Vogella의 답변에 따라 업데이트에 플래그를 추가하는 기능입니다 .

    git submodule update --remote
    

    서브 모듈이 가리키는 커밋에 서브 모듈의 내용을 채우는 대신 마스터 브랜치의 최신 커밋으로 해당 커밋을 교체 한 다음 서브 모듈을 해당 커밋으로 채 웁니다. 이것은 djacobs7 답변으로 두 단계로 수행 할 수 있습니다. 서브 모듈 객체가 가리키는 커밋을 업데이트 했으므로 변경된 서브 모듈 객체를 Git 저장소에 커밋해야합니다.

    git submodule add -b지점으로 모든 것을 최신 상태로 유지하는 마술 같은 방법은 아닙니다. 단순히 .gitmodules파일에 분기에 대한 정보를 추가 하고 하위 모듈 개체를 지정된 분기의 최신 커밋으로 업데이트하여 채울 수있는 옵션을 제공합니다.


답변

(2019 년 2 분기 Git 2.22 도입 git submodule set-branch --branch aBranch -- <submodule_path>)

참고 당신이 경우 기존의 서브 모듈 되지 않은 아직 지점을 추적 (다음을, 당신은 자식 1.8.2+이있는 경우 ) :

  • 부모 리포지토리가 하위 모듈이 이제 분기를 추적한다는 것을 알고 있어야합니다.

    cd /path/to/your/parent/repo
    git config -f .gitmodules submodule.<path>.branch <branch>
    
  • 서브 모듈이 실제로 해당 분기의 최신 버전인지 확인하십시오.

    cd path/to/your/submodule
    git checkout -b branch --track origin/branch
      # if the master branch already exist:
      git branch -u origin/master master
    

        
( “원산지”의 이름으로 되 REPO 상류 원격 서브 모듈.로부터 클로닝되었다 해당 서브 모듈을 표시 안에. 일반적으로, 그것이 ‘원점’)
git remote -v

  • 부모 저장소에 하위 모듈의 새로운 상태를 기록하는 것을 잊지 마십시오.

    cd /path/to/your/parent/repo
    git add path/to/your/submodule
    git commit -m "Make submodule tracking a branch"
    
  • 해당 서브 모듈에 대한 후속 업데이트는 다음 --remote옵션 을 사용해야합니다 .

    # update your submodule
    # --remote will also fetch and ensure that
    # the latest commit from the branch is used
    git submodule update --remote
    
    # to avoid fetching use
    git submodule update --remote --no-fetch
    

참고로 힘내 2.10+ (Q3 2016), 당신은 ‘사용할 수있는 .지점 이름으로’

브랜치의 이름은 다음과 같이 기록 submodule.<name>.branch.gitmodules대한 update --remote. 하위 모듈의 분기 이름이 현재 저장소의 현재 분기와 동일한 이름을 나타 내기 위해
특수 값 .인를 사용합니다 .

그러나 LubosD의 의견따르면

를 사용 git checkout하여 수행 할 분기 이름이 ” .“인 경우 커밋되지 않은 작업이 종료됩니다! 대신
사용하십시오 git switch.

이는 Git 2.23 (2019 년 8 월) 이상을 의미합니다.

혼란스러워git checkout


분기에 따라 모든 하위 모듈을 업데이트하려는 경우 :

    git submodule update --recursive --remote

댄 카메론 (Dan Cameron)그의 답변 에서 언급 한 것처럼 , 업데이트 된 각 서브 모듈에 대한 결과는 거의 항상 분리 된 HEAD가 입니다.

( Clintm의 노트 코멘트에 당신이 실행하는 경우, git submodule update --remote그 결과 SHA1는 서브 모듈에 현재 분기와 같은, 그것은 아무것도 할 떠나 서브 모듈을 여전히 “그 지점에”이 아닌 분리 된 머리 상태에 있지 않습니다. )

브랜치가 실제로 체크 아웃되도록 (그리고 부모 리포지토리의 서브 모듈을 나타내는 특수 항목 의 SHA1을 수정하지 않도록 )하기 위해 다음과 같이 제안합니다.

git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; git switch $branch'

각 하위 모듈은 여전히 ​​동일한 SHA1을 참조하지만 새 커밋을 수행하는 경우 하위 모듈이 추적하려는 분기에서 참조하므로 해당 커밋을 푸시 할 수 있습니다.
하위 모듈 내에서 푸시 한 후에는 상위 리포지토리로 돌아가서 수정 된 하위 모듈에 대해 새 SHA1을 추가, 커밋 및 푸시하는 것을 잊지 마십시오.

사용주의 $toplevel추천, 코멘트에 의해 알렉산더 포그 레브 냑을 . 커밋 f030c96
$toplevel : git1.7.2에서 2010 년 5 월에 도입되었습니다 .

최상위 디렉토리의 절대 경로를 포함합니다 (있는 곳 .gitmodules).

dtmland주석에 추가합니다 :

foreach 스크립트는 분기를 따르지 않는 하위 모듈을 체크 아웃하지 못합니다.
그러나이 명령은 다음 두 가지를 모두 제공합니다.

 git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; [ "$branch" = "" ] && git checkout master || git switch $branch' –

같은 명령이지만 읽기 쉽습니다.

git submodule foreach -q --recursive \
    'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; \
     [ "$branch" = "" ] && \
     git checkout master || git switch $branch' –

umläute 을 세련 dtmland 단순화 된 버전의 명령 코멘트에 :

git submodule foreach -q --recursive 'git switch $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'

여러 줄 :

git submodule foreach -q --recursive \
  'git switch \
  $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'

Git 2.26 (Q1 2020) 이전에는 서브 모듈에서 업데이트를 재귀 적으로 가져 오도록 지시 된 페치는 필연적으로 많은 양의 출력을 생성하며 오류 메시지를 찾기 어렵게됩니다.

이 명령은 작업이 끝날 때 오류가 발생한 하위 모듈을 열거하도록 지시되었습니다 .

Emily Shaffer ( )의 commit 0222540 (2020 년 1 월 16 일)을 참조하십시오 . (의해 병합 Junio C 하마노 – b5c71cc 커밋 05 이월 2020)nasamuffin
gitster

fetch: 서브 모듈 페치 중 실패 강조

에 의해 서명 : 에밀리 셰퍼

많은 서브 모듈이있을 때 서브 모듈 페치가 실패하는 경우, 하나 이상의 페치가 다시 실패하면 단독 실패 서브 모듈 페치의 오류가 다른 서브 모듈의 활동에 묻 힙니다 fetch-by-oid.
늦게 오류를 불러내 어 사용자가 무언가 잘못되었다는 것을 알 수 있도록합니다 .

주위 fetch_finish()run_processes_parallel,mutexing에 의해 동 기적으로 만 호출 되기 때문에 필요하지 않습니다 submodules_with_errors.


답변

Git 1.8.2는 분기를 추적 할 수있는 가능성을 추가했습니다.

# add submodule to track master branch
git submodule add -b branch_name URL_to_Git_repo optional_directory_rename

# update your submodule
git submodule update --remote

Git 서브 모듈 참조


답변

Git 서브 모듈을 사용하는 방법의 예.

  1. 새로운 리포지토리 생성
  2. 그런 다음 다른 저장소를 하위 모듈로 복제하십시오.
  3. 그런 다음 하위 모듈에 V3.1.2라는 태그를 사용합니다.
  4. 그리고 우리는 커밋합니다.

그리고 그것은 다음과 같이 조금 보입니다 :

git init
vi README
git add README
git commit
git submodule add git://github.com/XXXXX/xxx.yyyy.git stm32_std_lib
git status

git submodule init
git submodule update

cd stm32_std_lib/
git reset --hard V3.1.2
cd ..
git commit -a

git submodule status

어쩌면 도움이됩니까 (분기가 아닌 태그를 사용하더라도)?


답변

내 경험상 수퍼 프로젝트에서 분기를 전환하거나 향후 체크 아웃하면 하위 모듈이 올바르게 추가되고 추적되는지 여부에 관계없이 하위 모듈의 HEAD가 분리됩니다 (예 : @ djacobs7 및 @Johnny Z 답변).

그리고 수동으로 또는 스크립트 git 서브 모듈 foreach를 통해 올바른 분기를 수동으로 체크 아웃하는 대신 사용할 수 있습니다.

그러면 하위 속성 구성 파일에서 분기 속성을 확인하고 설정된 분기를 체크 아웃합니다.

git submodule foreach -q --recursive 'branch="$(git config -f <path>.gitmodules submodule.$name.branch)"; git checkout $branch'


답변

Git 서브 모듈은 약간 이상하다. 항상 “분리 된 헤드”모드에있다. 예상 한대로 분기의 최신 커밋으로 업데이트되지 않는다.

그래도 생각할 때 의미가 있습니다. submodule bar로 foo 저장소를 작성한다고 가정 해 봅시다 . 변경 사항을 푸시하고 저장소 foo 에서 commit a7402be를 체크 아웃하도록 지시합니다 .

그런 다음 누군가 복제본을 만들기 전에 저장소 표시 줄을 변경했다고 상상해보십시오 .

저장소 foo 에서 커밋 a7402be를 체크 아웃하면 내가 푸시 한 것과 동일한 코드가 필요합니다. 그렇기 때문에 서브 모듈이 명시 적으로 지시 한 다음 새로운 커밋을 할 때까지 서브 모듈이 업데이트되지 않는 이유입니다.

개인적으로 하위 모듈은 Git에서 가장 혼란스러운 부분이라고 생각합니다. 내가 할 수있는 것보다 서브 모듈을 더 잘 설명 할 수있는 곳이 많이 있습니다. Scott Chacon의 Pro Git 을 추천 합니다.