본문 바로가기
목차
utils/git and github

새로 remote 에 추가된 submodule 을 local 에 반영하기

by ds31x 2025. 7. 11.
728x90
반응형

 

이 문서에서는 다음을 가정함

  • 현재 local repository는 remote repository에 submodule을 추가하기 전에 clone된 상태임.
  • 이 local repository에서 remote repository의 submodule등을 반영하기 위한 절차를 설명한다.

1. 현재 상황.

  • 현 local repository는 이전에 git clone으로 생성된 것임.
  • 예: ~/workspace/myproj (이를 parent repository라고 부름: submodule에 대해)

이 local repository가 바라보는 remote repsoitory에서 다음의 경로에 submodule이 새로 추가됨

  • 예: lib/mylib

이를 local repository에서 반영하고자 함.


참고: 이미 submodule가 있는 상태(init은 이루어짐)에서 최신상태로 갱신만 필요한 경우

만약 이미 local repository에 submodule이 적용되어 있는 상태(이전에 init이 된 상태)에서
submodule의 최신 commit을 적용하는 경우라면 다음의 명령어로 충분함.

# parent repository로 이동
cd ~/workspace/myproj

# submodule의 최신 커밋 가져오기
git submodule update --remote --merge
# --init 을 사용하는 경우, parent repository가 참조하는 submodule의 commit으로 동기화.
# 현재 parent repository가 참조하는 submodule의 commit 확인은 
# git ls tree <submodule의_상대경로> 를 사용
# 실행하는 위치에 따른 <submodule의_상대경로> 를 넣어주면 확인 가능: 2-7절 확인할 것

# commit pointer가 변경된 submodule 반영
git add lib/mylib
git commit -m "Update submodule to latest commit
  • 이 방식은 .gitmodules에 모든 submodule들을 한번에 처리함.
    • .gitmodules에 등록된 각 submodule에 대해
    • 지정된 remote 브랜치(branch = xxx)에서 
    • 최신 commit을 fetch.
    • 현 submodule 디렉토리에 merge (or fast-forward) 반영함.
  • .gitmodules의 각 submodule에 branch가 지정되어야 명시적으로 정확히 동작.
    • 없는 경우, origin/main 또는 origin/master 브랜치 처럼 origin/HEAD가 가리키는 branch를 사용.
  • 3,4 번째 줄과 git addcommit을 통해 parent repository에도 변경을 기록:  commit pointer (SHA1) 변경 기록.

submodule의 branch가 명확하지 않으면 다음으로 확인할 것:

# submodule의 디렉토리로 이동.
cd lib/mylib
# 원격 origin의 branch 확인.
git remote show origin
  • parent repository (=main repository)의 root directory에 있는 .gimodules 에 기재된 경우가 대부분인.

만약, submodules의 각각의 디렉토리에서 pull을 하여 수동으로 업데이트를 따로 했다면,

(즉, 각 submodule 별로 따로 업데이트를 한 경우를 의미함)

parent respository에 해당 변경된 commit 에 대한 pointer를 갱신하도록 다음 을 수행한다.

# parent repository로 이동
cd ~/workspace/myproj
git add lib/mylib # submodule 디렉토리를 add하여 staging.
git commit -m "Update submodule to latest commit"

 


2. submodule을 추가 및 반영하기 위한 처리순서

2-1. parent repository 의 root directory로 이동.

cd ~/workspace/myproject
  • 바로 .gitmodules 가 존재함.

 


2-2. 최신 변경사항 가져오기.

submodule이 추가되면서 생긴 .gitmodules를 가져오기 위한 단계.

git pull --recurse-submodule
  • .gitmodules와 submodule 경로에 대한 gitlink가 local repository에 반영됨.
  • --recurse-submodules은 기존에 init가 되어있는 submodule 들을 갱신하는 옵션임.
    • 이전에 init한 submodule이 없는 경우엔 필요없음.
    • 이 문서가 가정한 현재 상황은 새로운 submodule이 remote repository에만 추가된 상황이므로 필요.

2-3. 실제 submodule (gitlink) 디렉토리 초기화 및 clone

앞서의 단계는 parent repository에 .gitmodules만을 가져온 것으로 아직 실제 submoduel의 디렉토리 등이 없음.
이 역시 일종의 저장소이므로 init을 해야만 함.

git submodule update --init --recursive
  • .gitmodules에 정의된 submodule의 정보를 바탕으로 실제 directory를 clone수행.
    • 실제로는 submodule의 remote repository를 clone 하는 것임.
    • --init 는 현재 parent repository가 참조하는 submodule의 commit 을 가져옴.
    • --update 의 경우엔 submodule저장소의 해당 브랜치의 최신 commit 을 가져옴.
  • --recursivenetsted submodule까지 재귀적으로 처리함을 의미함.
  • git submodule update에 의해 생성된 상태는 detached HEAD임.
    • parent repository에서는 submodule을 해당 프로젝트의 특정 commit으로 고정시키는게 기본임.
      • detached HEAD 를 유지하는 경우는 parent repository에서 해당 submodule을 사용만 할 뿐,
      • 변경 및 수정을 하지 않는 경우에는 그냥 두어도 상관없음 (오히려 안전) 
    • 이는 해당 submodule의 프로젝트의 branch와 연결되어 있지 않으므로 add 나 commit을 해선 안됨
      • 즉, submodule 원격 저장소의 내용을 그대로 쓰기만 하는 상태임. 

 

detached HEAD 상태 해제를 해서 parent repository에서 submodule 디렉토리 내의 파일 수정을 submodule의 저장소에 반영하고 싶다면 다음을 진행.


2-4. 실제 submodule의 directory로 이동

cd lib/mylib

2-5. submodule의 detached HEAD상태 해제를 위한 branch 전환.

git switch main # or master 등의 실제 사용하는 branch)
  • 다시한번 애기하지만, submodule update로 내려온 상태는 보통 detached HEAD임.
  • git switch를 통해 branch로 전환해줘야 함.
  • submodule 프로젝트의 remote repository에 있는 branch를 지정함 (parent repository의 branch 아님)
  • submodule의 디렉토리에서 git branch -r을 통해 가능한 remote branch 들의 list로 확인 후 지정하면 보다 안전함.

현재 parent repository의 submodule에서 참조하고있는 branch는 다음으로 확인 가능하니,
이를 확인하고 해당 branch로 switch하는것이 좋음:

git config -f ../../.gitmodules --get submodule.lib/mylib.branch
  • 위에서 ../../ 현재 위치에서 parent repository의 root directory를 가리키는 상대 경로임: 그냥 에디터로 확인해도 되긴함.
  • 이는 .gitmodules파일에서 해당 submodule에 branch=...항목의 값을 출력함.
  • .gitmoduels파일의 branch항목은 git submodule update --remote 시 해당 branch를 대상으로 처리되게 함.

현재 .gitmodules에 지정된 branch가 없을 수도 있음.
이 경우엔 프로젝트에 맞게 branch를 지정(위의 switch한 브랜치임)하고, .gitmodules파일에 다음과 같이 추가해줌.

[submodule "lib/mylib"]
    path = lib/mylib
    url = https://github.com/example/mylib.git
    branch = main # 사용하는 branch를 정확히 기재.

 

이후 parent repository(상위저장소, 메인저장소)의 root로 이동하여 다음을 수행.

git submoduel sync
  • .gitmodules의 파일 내용을 읽어서
  • .git/config의 파일에서 submodule 관련 설정을 동기화함.

다음의 명령어로 확인하여 같아야만 함 (parent repository의 root directory에서 수행한 것임).

git config -f .gitmodules --get submodule.lib/mylib.branch
git config --get submodule.lib/mylib.branch
  • 다르다면, git submodule sync.gitmodules내용으로 .git/config파일을 동기화할 것.

2-6. submodule의 최신 commit가져오기.

git pull
  • submodule의 remote repository의 해당 branch의 최신 commit을 가져옴.
  • git switch는 branch만을 변경할 뿐, 해당 branch의 최신 commit을 가져오지 않음.

2-7. parent repository에 submodule의 commit상태를 반영.

# parent repository에 속한 경로로 이동
# submodule 에 속한 directory만 아니면 됨.
cd ../../
git add lib/mylib
git commit -m "Update submodule to latest commit"
  • parent repository는 submodule의 내용은 저장하지 않으나,
  • submodule의 commit pointer는 저장하기 때문에
  • 이를 반영해야 함.

submodule은 parent repository에서 또 다른 git repository를 참조하는 방식이기 때문에,
parent repository는 submodule에 대해 다음의 정보만을 저장 및 추적 관리함.

  • submodule 의 parent repository내의 디렉토리 경로 및 URL (예: lib/mylib)
    • 이는 .gitmoduels 파일에 저장됨.
  • 해당 submoduel 이 가리키는 commit의 SHA (=pointer)
    • git tree 에 저장됨. (git ls-tree HEAD lib/mylib로 확인 가능)

2-8. 다음으로 submodule 에서 바뀐 commit을 확인 가능함.

git log -p --submodule
  • -p : --patch 를 의미하며, commit의 변경사항(diff)를 함께 표시 (출력이 보통 길게 나오므로 pager 이용할 것)
    •  git log -p --submodule | less 와 같이 페이저로 읽어야 편함(나가려면 :q)
  • --submodule :  출력에 submodule 관련 부분에 특별히 Submodule 이라는 단어로 시작하게 표시를 함.
  • 단, parent repository에서 수행해야 함. 
더보기

같이보면 좋은 자료들

2024.05.20 - [utils/git and github] - [Git] Git Summary (작성중)

 

[Git] Git Summary (작성중)

git이란2024.05.20 - [utils/git and github] - Git : 소개 git 설치 후 해줘야 하는 작업들[Git] git 설치 후 우선 해줘야 하는 작업들 (tistory.com)local repository 초기화2024.05.20 - [utils/git and github] - [Git] init : local repo

ds31x.tistory.com


 

728x90

'utils > git and github' 카테고리의 다른 글

git difftool 과 git mergetool  (1) 2025.07.22
SSH Agent 사용법  (2) 2025.07.21
[git] How to Add a New Remote Branch to Your Local Repository  (0) 2024.12.26
[Git] rebase: Tutorial  (0) 2024.05.28
[Git] pager 옵션 조정-상세  (0) 2024.05.27