모든 git 서브 모듈의 최신 정보를 얻는 쉬운 방법


1846

우리는 git 서브 모듈을 사용하여 우리가 개발 한 다른 많은 라이브러리에 의존하는 두 개의 큰 프로젝트를 관리합니다. 각 라이브러리는 하위 프로젝트로 종속 프로젝트에 가져온 별도의 저장소입니다. 개발 과정에서 우리는 종종 모든 종속 서브 모듈의 최신 버전을 원합니다.

git에 이것을 수행하는 명령이 있습니까? 그렇지 않은 경우 Windows 배치 파일 또는 이와 유사한 파일은 어떻습니까?


git-deep 이 도움이 될 것입니다.
Mathew Kurian

9
@Brad 당신은 당신의 서브 모듈의 복사본을 마스터 프로젝트에서 명명 된 commit revs로 업데이트하길 원합니다; 또는 모든 하위 모듈에서 최신 HEAD 커밋을 가져 오시겠습니까? 여기에있는 대부분의 답변은 전자에 대한 것입니다. 많은 사람들이 후자를 원합니다.
chrisinmtown

답변:


2463

그것의 경우 처음으로 당신이 체크 아웃 사용할 필요 REPO --init첫 번째 :

git submodule update --init --recursive

들어 자식 1.8.2 이상, 옵션은 --remote원격 지사의 최신 팁 지원 업데이트에 추가되었습니다 :

git submodule update --recursive --remote

이것은 .gitmodules또는 .git/config파일에 지정된 "기본이 아닌"브랜치를 존중할 수있는 추가적인 이점이 있습니다 .

들어 자식 1.7.3 사용하거나 위의 (하지만 업데이트가 계속 적용 무엇 주위 개는 아래의) :

git submodule update --recursive

또는:

git pull --recurse-submodules

하위 커밋을 현재 커밋 대신 최신 커밋으로 가져 오려면 리포지토리가 가리 킵니다.

자세한 내용은 git-submodule (1) 을 참조하십시오


299
아마 git submodule update --recursive요즘 사용해야합니다 .
Jens Kohl

38
성능 개선 :git submodule foreach "(git checkout master; git pull)&"
Bogdan Gusiev

18
update는 각 하위 모듈을 지정된 개정판으로 업데이트하고 해당 리포지토리의 최신 버전으로 업데이트하지 않습니다.
Peter DeWeese

21
추가로, origin master일부 하위 모듈이 특정 하위 모듈의 다른 브랜치 또는 위치 이름을 추적하는 경우이 명령의 끝에 맹목적으로 고정 하면 예기치 않은 결과가 발생할 수 있습니다. 일부에게는 분명하지만 모든 사람에게는 해당되지 않습니다.
Nathan Hornby

31
모든 사람을 명확히하기 위해. git submodule update --recursive상위 리포지토리가 각 하위 모듈에 대해 저장 한 개정을 확인한 다음 각 하위 모듈에서 해당 개정을 확인합니다. 각 하위 모듈에 대한 최신 커밋을 가져 오지 않습니다 . git submodule foreach git pull origin master또는 git pull origin master --recurse-submodules각 하위 모듈을 원래 리포지토리에서 최신으로 업데이트하려는 경우 원하는 것입니다. 그래야만 하위 모듈의 업데이트 된 해시로 부모 리포지토리에서 보류중인 변경 사항을 얻게됩니다. 확인 하시고 잘 하셨어요.
Chev

636
git pull --recurse-submodules --jobs=10

1.8.5에서 처음 배운 기능 자식.

버그 가 수정 될 때까지 처음으로 실행해야합니다

자식 모듈 업데이트 --init --recursive


29
upvoted, 난이 사용 별명이 update_submodules = '자식 풀을 --recurse - 서브 모듈 && 자식 서브 모듈 갱신'
스티븐 C

3
하위 모듈을 이미 한 번 이상 뽑았지만 체크 아웃되지 않은 하위 모듈의 경우 gahooa의 답변을 참조하십시오.
Matt Browne

8
최상위 리포지토리가 지정한 버전으로 이동합니다. 머리를 당기지 않습니다. 예를 들어 TopRepo가 SubRepo에 HEAD 뒤에 버전 2를 지정하면 SubRepo가 2보다 뒤에있는 해당 버전으로 가져옵니다. 다른 답변은 SubRepo에서 HEAD를 가져옵니다.
Chris Moschini 2016 년

11
둘 것을 참고 git pull --recurse-submodulesgit submodule update --recursive않습니다 하지 초기화 새로 서브 모듈을 추가하지 않습니다. 그것들을 초기화하려면 다음을 실행해야합니다 git submodule update --recursive --init. 매뉴얼 에서 인용 : 서브 모듈이 아직 초기화되지 않고 .gitmodules에 저장된 설정을 사용하려는 경우 --init 옵션을 사용하여 서브 모듈을 자동으로 초기화 할 수 있습니다.
patryk.beza

1
git submodule update --recursive --remote저장된 SHA-1 대신 하위 모듈을 원격 최신 개정으로 업데이트 하는 힌트를 추가 할 수도 있습니다 .
Hanno S.

386

초기화시 다음 명령을 실행하십시오.

git submodule update --init --recursive

git repo 디렉토리 내에서 가장 잘 작동합니다.

하위 모듈을 포함한 모든 최신 정보가 표시됩니다.

설명

git - the base command to perform any git command
    submodule - Inspects, updates and manages submodules.
        update - Update the registered submodules to match what the superproject
        expects by cloning missing submodules and updating the working tree of the
        submodules. The "updating" can be done in several ways depending on command
        line options and the value of submodule.<name>.update configuration variable.
            --init without the explicit init step if you do not intend to customize
            any submodule locations.
            --recursive is specified, this command will recurse into the registered
            submodules, and update any nested submodules within.

이 후에는 다음을 실행할 수 있습니다.

git submodule update --recursive

git repo 디렉토리 내에서 가장 잘 작동합니다.

하위 모듈을 포함한 모든 최신 정보가 표시됩니다.


10
그렇습니다-가장 높은 투표 응답은 '09 년에 가장 좋은 방법이었습니다. 그러나 지금은 훨씬 간단하고 직관적입니다.
마이클 스캇 커스버트

2
감사 @MichaelScottCuthbert, 나도 확실히 다른 삼년이 명령 미친 것이야
ABC123

5
그럼에도 불구하고 하위 모듈에서 최신 버전을 체크 아웃하지 않고 부모가 추적하는 최신 버전 만 체크 아웃합니다.
Nathan Osman

4
@NathanOsman은 당신이 원하는 것입니다 ... 부모 개정 추적을 따르지 않으면 깨진 코드로 끝날 것입니다. 부모의 관리자 인 경우 직접 업데이트하고 커밋 할 수 있습니다.
abc123

2
예,하지만 제 이해로는 OP가 원하는 것이 아닙니다.
Nathan Osman

305

참고 : 이것은 2009 년 이후이며 지금은 좋았지 만 지금은 더 나은 옵션이 있습니다.

우리는 이것을 사용합니다. 라는 git-pup:

#!/bin/bash
# Exists to fully update the git repo that you are sitting in...

git pull && git submodule init && git submodule update && git submodule status

적절한 bin 디렉토리 (/ usr / local / bin)에 넣으십시오. Windows의 경우 구문을 수정해야 작동 할 수 있습니다. :)

최신 정보:

원래의 저자가 모든 서브 모듈의 모든 HEAD를 가져 오는 것에 대한 의견에 응답하여 좋은 질문입니다.

나는 git이것이 내부적으로 이것에 대한 명령을 가지고 있지 않다고 확신합니다 . 그렇게하려면 HEAD가 서브 모듈에 실제로 어떤 것인지 식별해야합니다. master가장 최신의 지점 이라고 말하는 것만 큼 간단 할 수 있습니다 ...

그런 다음 다음을 수행하는 간단한 스크립트를 작성하십시오.

  1. git submodule status"수정 된"리포지토리를 확인하십시오 . 출력 라인의 첫 문자는 이것을 나타냅니다. 하위 리포지토리가 수정 된 경우 진행하지 않을 수 있습니다.
  2. 나열된 각 저장소에 대해 해당 디렉토리로 cd하고를 실행하십시오 git checkout master && git pull. 오류를 확인하십시오.
  3. 마지막으로, 서브 모듈의 현재 상태를 나타 내기 위해 사용자에게 디스플레이를 인쇄하는 것이 좋습니다.

이 스타일은 실제로 자식 서브 모듈이 설계된 것이 아니라고 언급하고 싶습니다. 일반적으로 "LibraryX"의 버전이 "2.32"라고 말하고 "업그레이드"할 때까지 계속 유지합니다.

즉, 설명 된 스크립트로 수행하는 작업이지만 더 자동으로 수행됩니다. 관리가 필요합니다!

업데이트 2 :

Windows 플랫폼을 사용하는 경우 Python을 사용하여 이러한 영역에서 매우 유용한 스크립트를 구현할 수 있습니다. 유닉스 / 리눅스를 사용하고 있다면 bash 스크립트 만 제안합니다.

설명이 필요하십니까? 의견을 게시하십시오.


나는 그것이 내가 원하는 것이라고 생각하지 않습니다. 그것은 슈퍼 프로젝트가 마지막으로 커밋 된 서브 모듈의 버전을 끌어 당기지 않을 것입니다. 모든 하위 모듈의 헤드 버전을 가져오고 싶습니다.
브래드 로빈슨

3
이것은 훌륭하게 작동하며 서브 모듈을 업데이트 할뿐만 아니라 필요한 경우 처음으로 가져 오는데도 효과적입니다.
Matt Browne

"현재 지점에 대한 추적 정보가 없습니다. 병합 할 지점을 지정하십시오."라는 메시지가 나타납니다. 내가 무엇을 시도하든 : /
Nathan Hornby

9
별명을 작성하지 않으시겠습니까? 스크립팅없이 git config --global alias.pup '!git pull && git submodule init && git submodule update && git submodule status'사용하십시오 git pup.
fracz

어떤 이유로 git 1.9.1을 사용하더라도 git submodule init서브 모듈이 포함 된 첫 번째 풀 후에 수행해야 하므로 모든 것이 올바르게 작동하기 시작했습니다.
벤 Usman

164

헨릭이 올바른 길을 가고 있습니다. 'foreach'명령은 임의의 쉘 스크립트를 실행할 수 있습니다. 최신 정보를 얻는 두 가지 옵션은 다음과 같습니다.

git submodule foreach git pull origin master

과,

git submodule foreach /path/to/some/cool/script.sh

초기화 된 모든 서브 모듈 을 반복 하고 주어진 명령을 실행합니다.


144

다음은 Windows에서 나를 위해 일했습니다.

git submodule init
git submodule update

6
이것은 OP가 요구 한 것이 아닙니다. 관련 서브 모듈 커밋으로 만 업데이트되고 최신 서브 커밋으로 업데이트되지 않습니다.
Patrick

52
그러나 이것은 풀 서브 모듈에 나는 REPO를 체크 아웃 처음으로 자식을 가지고이 페이지에있는 유일한 일
theheadofabroom

2
git submodule update --init --recursive (특히 해당 서브 모듈이 새로운 클론의
RestKit 인 경우

33

편집 :

의견에서 ( philfreo에 의해 ) 최신 버전이 필요하다고 지적했습니다 . 최신 버전이 필요한 중첩 서브 모듈이있는 경우 :

git submodule foreach --recursive git pull

----- 아래의 오래된 주석 -----

이것이 공식적인 방법이 아닙니까?

git submodule update --init

매번 사용합니다. 지금까지 아무런 문제가 없습니다.

편집하다:

방금 다음을 사용할 수 있음을 발견했습니다.

git submodule foreach --recursive git submodule update --init 

또한 모든 하위 모듈, 즉 종속성을 재귀 적으로 가져옵니다.


5
당신의 대답은 OP의 질문에 대답하지 않습니다,하지만 당신은 그냥 말할 수있는 제안 한 것을 할git submodule update --init --recursive
philfreo

2
최신 버전이 필요합니다. 중첩 된 하위 모듈이있는 경우 유용 할 수 있습니다. git submodule foreach --recursive git pull
antitoxic

1
그러나 실제로 아무것도 다운로드하지 못했습니다. "git submodule update --init --recursive"는 저에게 효과적이었습니다.
BrainSlugs83

33

하위 모듈의 기본 분기가 아닌 경우 master , 전체 Git 하위 모듈 업그레이드를 자동화하는 방법입니다.

git submodule init
git submodule update
git submodule foreach 'git fetch origin; git checkout $(git rev-parse --abbrev-ref HEAD); git reset --hard origin/$(git rev-parse --abbrev-ref HEAD); git submodule update --recursive; git clean -dfx'

많은 질문에 대한 많은 답변
중에서이

30

처음으로

복제 및 초기화 하위 모듈

git clone git@github.com:speedovation/kiwi-resources.git resources
git submodule init

쉬다

개발하는 동안 단지 서브 모듈을 잡아 당기고 업데이트하십시오.

git pull --recurse-submodules  && git submodule update --recursive

원래 Git 서브 모듈을 최신 커밋으로 업데이트

git submodule foreach git pull origin master

선호하는 방법은 아래에 있어야합니다

git submodule update --remote --merge

참고 : 마지막 두 명령의 동작은 동일합니다


실수로 서브 모듈이없는 git clone을했고 다른 모든 옵션이 작동하지 않았습니다. 아무도 서브 모듈을 복제하지 않았습니다. 당신을 사용 git submodule update하여 트릭을했습니다. 이제 복제 첫 번째 단계에서 누락 된 하위 모듈 데이터를 다운로드하고 있습니다. 감사합니다. 나는 자식에 좋은 아니에요 : C
m3nda

이 anser는 실제로 여기에 질문을하기에 아주 좋은 대답입니다. 왜 ".. --recursive-submodules .."그리고 "... update ..." 그리고 심지어 ".. .foreach ... "나중에 최신 커밋을 얻으려면? 이 모든 것이 전혀 GIT처럼 보이지 않습니다! "업데이트"는 무엇이며 왜 각 모듈을 수동으로 가져와야합니까? "... --recurse-submodules .."가하는 일이 아닌가요? 힌트가 있습니까?
Peter Branforn

20

어떤 버전의 git이 작동하는지 모르겠지만 그것이 당신이 찾고있는 것입니다.

git submodule update --recursive

git pull루트 리포지토리도 업데이트하는 데 사용합니다 .

git pull && git submodule update --recursive

10

위의 답변은 좋지만 git-hooks를 사용하여 이것을 쉽게 만들었지 만 git 2.14 에서는 git config submodule.recursegit 저장소로 가져올 때 하위 모듈을 업데이트하도록 true로 설정할 수 있습니다 .

이것은 모든 서브 모듈이 브랜치에있는 경우 변경 사항을 푸시하는 부작용이 있지만 그 동작이 필요한 경우 이미 작업을 수행 할 수 있습니다.

다음을 사용하여 수행 할 수 있습니다.

git config submodule.recurse true

불행히도 git submodule init서브 모듈이 아직 초기화되지 않은 경우에도 여전히이 옵션을 사용해야 합니다.
펠렛

5

Windows 용 Git 2.6.3 :

git submodule update --rebase --remote


그것은 나를 위해 일한 유일한 사람입니다. 서브 모듈 포인터가 더 이상 리모컨에없는 버전을 가리 키기 때문에 초기화하거나 업데이트 할 수도 없었습니다
Pavel P

4

리포지토리의 최상위 레벨에서 :

git submodule foreach git checkout develop
git submodule foreach git pull

모든 브랜치를 개발하고 최신 버전으로 전환합니다.


2
git 2.7에서는 작동하지 않습니다.
Bruno Haible

트리의 모든 프로젝트 참조를 추가하는 Everything sln 파일과 같은 것이 있습니까? 또한 어떤 오류가 보입니까? gitignore 파일도 확인할 수 있습니까
Srayan Guhathakurta

1
git submodule foreach git pull origin master가져오고 싶은 지점을 추가해야했습니다. 그 외에는 완벽하게 작동했습니다.
Torxed

3

나는 gahooa대답을 위 의 내용으로 수정 하여이 작업을 수행했습니다 .

자식과 통합 [alias]...

부모 프로젝트에 다음과 같은 것이있는 경우 .gitmodules:

[submodule "opt/submodules/solarized"]
    path = opt/submodules/solarized
    url = git@github.com:altercation/solarized.git
[submodule "opt/submodules/intellij-colors-solarized"]
    path = opt/submodules/intellij-colors-solarized
    url = git@github.com:jkaving/intellij-colors-solarized.git

.gitconfig 안에 이와 같은 것을 추가하십시오.

[alias]
    updatesubs = "!sh -c \"git submodule init && git submodule update && git submodule status\" "

그런 다음 서브 모듈을 업데이트하려면 다음을 실행하십시오.

git updatesubs

나는이 내에서의를 환경 설정의 repo .


3

지금해야 할 일은 간단합니다 git checkout

이 전역 구성을 통해 활성화하십시오. git config --global submodule.recurse true


2

서브 모듈이든 아니든 모든 자식 리포지토리에서 가져 오는 명령 줄은 다음과 같습니다.

ROOT=$(git rev-parse --show-toplevel 2> /dev/null)
find "$ROOT" -name .git -type d -execdir git pull -v ';'

당신이 당신의 최고 자식 저장소에서 실행하는 경우 교체 할 수 있습니다 "$ROOT"..


1

이 작업을 수행하려면 스크립트를 작성해야한다고 생각합니다. 솔직히 말해서, 나는 그래서 당신이 사용할 수있는 그것을 할 파이썬을 설치할 수 os.walkcd각 디렉토리에 적절한 명령을 실행합니다. python 또는 배치 이외의 다른 스크립팅 언어를 사용하면 스크립트를 수정하지 않고도 하위 프로젝트를 쉽게 추가 / 제거 할 수 있습니다.


1

비고 : 너무 쉬운 방법은 아니지만 실행 가능하며 고유 한 전문가가 있습니다.

만약 HEAD리포지토리의 리비전과 HEAD모든 서브 모듈 중 s 만을 복제하고자한다면 (즉, "트렁크"체크 아웃), 다음 Lua 스크립트를 사용할 수 있습니다 . 때로는 간단한 명령 git submodule update --init --recursive --remote --no-fetch --depth=1으로 복구 할 수없는 git오류가 발생할 수 있습니다 . 이 경우 디렉토리의 하위 디렉토리를 정리하고 명령을 .git/modules사용하여 수동으로 하위 모듈을 복제해야 git clone --separate-git-dir합니다. 유일한 복잡성은 수퍼 프로젝트 트리에서 URL , .git서브 모듈 디렉토리 경로 및 서브 모듈 경로 를 찾는 것 입니다.

참고 : 스크립트는 https://github.com/boostorg/boost.git리포지토리에 대해서만 테스트 됩니다. 특징 : 모든 서브 모듈은 동일한 호스트에서 호스팅 .gitmodules되며 상대 URL 만 포함합니다 .

-- mkdir boost ; cd boost ; lua ../git-submodules-clone-HEAD.lua https://github.com/boostorg/boost.git .
local module_url = arg[1] or 'https://github.com/boostorg/boost.git'
local module = arg[2] or module_url:match('.+/([_%d%a]+)%.git')
local branch = arg[3] or 'master'
function execute(command)
    print('# ' .. command)
    return os.execute(command)
end
-- execute('rm -rf ' .. module)
if not execute('git clone --single-branch --branch master --depth=1 ' .. module_url .. ' ' .. module) then
    io.stderr:write('can\'t clone repository from ' .. module_url .. ' to ' .. module .. '\n')
    return 1
end
-- cd $module ; git submodule update --init --recursive --remote --no-fetch --depth=1
execute('mkdir -p ' .. module .. '/.git/modules')
assert(io.input(module .. '/.gitmodules'))
local lines = {}
for line in io.lines() do
    table.insert(lines, line)
end
local submodule
local path
local submodule_url
for _, line in ipairs(lines) do
    local submodule_ = line:match('^%[submodule %"([_%d%a]-)%"%]$')
    if submodule_ then
        submodule = submodule_
        path = nil
        submodule_url = nil
    else
        local path_ = line:match('^%s*path = (.+)$')
        if path_ then
            path = path_
        else
            submodule_url = line:match('^%s*url = (.+)$')
        end
        if submodule and path and submodule_url then
            -- execute('rm -rf ' .. path)
            local git_dir = module .. '/.git/modules/' .. path:match('^.-/(.+)$')
            -- execute('rm -rf ' .. git_dir)
            execute('mkdir -p $(dirname "' .. git_dir .. '")')
            if not execute('git clone --depth=1 --single-branch --branch=' .. branch .. ' --separate-git-dir ' .. git_dir .. ' ' .. module_url .. '/' .. submodule_url .. ' ' .. module .. '/' .. path) then
                io.stderr:write('can\'t clone submodule ' .. submodule .. '\n')
                return 1
            end
            path = nil
            submodule_url = nil
        end
    end
end
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.