필자가 공부한 내용을 정리한
repository
. 서로 다른 내용을submodule
을 통해 관리하고 있다.
일반적으로 하나의 repository
(이하 repo
) 에 해당 프로젝트의 모든 내용이 포함된다. 그러나 하나의 repo
로 관리하기 어려운 대형 프로젝트 역시 존재한다. 쉽게 shared library
(이하 slib
) 를 가져다 쓰는 경우를 생각해볼 수 있다. 가령 무지성으로 slib
의 내용을 싹싹 긁어다가 하나의 main repo
로 병합하여 관리한다고 생각해보자.
위 경우 두 가지 문제가 발생할 수 있다:
slib
의 업데이트가 이뤄졌을 때, 버전 관리가 매우 번거롭다. (왜 Why? main repo
와 commit logs
를 공유하기 때문에)main repo
의 변화에 맞춰 slib
의 내용이 변경될 경우, 이를 사용하는 다른 모든 repo
의 내용 역시 manually
하게 전부 변경 해야 함. 당연히 slib
의 내용은 main repo
의 종속적이므로 다른 repo
의 내용 역시 전부 manually
하게 직접 변경 해줘야 함. 이러한 문제 해결을 위해 git
은 submodule
이라는 개념을 지원한다. submodule
은 repository
안의 repository
를 허용한다. main repository
와 sub repository (submodule)
은 서로 독립적인 commit
을 가지며 각각 따로 관리되어질 수 있다.
git
의 submodule
기능을 detail
하게 기술할 예정이므로 바쁜 사람은 5. 요약
을 확인하길 바란다. submodule
의 동작방식이 궁금한 독자는 이하의 내용을 정독하면 좋을 것이다.
submodule
의 추가 설명을 위해 임시로 repository
를 만들어보려 한다:
test-submodule-main
: submodule
을 포함하는 main repository
test-submodule-lib1
: main repository
에서 사용되는 shared library
test-submodule-lib2
: main repository
에서 사용되는 shared library
main project
clonegit clone https://github.com/Cruzer-S/test-submodule-main.git
submodule
을 추가할 main repository
를 clone
했다.
submodule
추가하기git submodule add <remote repository>
# test 를 위한 command
git submodule add https://github.com/Cruzer-S/test-submodule-lib1.git
git submodule add https://github.com/Cruzer-S/test-submodule-lib2.git
git submodule add
명령어를 통해 main repository
에 submodule
을 쉽게 추가할 수 있다.
그럼 다음과 같이 새로운 파일이 세 개의 파일이 생성됨을 알 수 있다. 재미있는 점은 submodule add
를 통해 clone
된 submodules
는 directory
임에도 하나의 file
로 취급(일반적인 file
과는 속성 자체가 다르지만)되며 , submodule
내의 files
는 track
하지 않는다.
또한 submodule
의 정보를 가지는 .gitmodules
라는 파일이 생성된다.
git add .
git commit -m <commit message>
git push
# test 를 위한 command
git add .
git commit -m "add submodules: test-submodule-lib1, 2"
git push
이제 main project
의 변동사항을 commit
하면 된다.
github
에서 submodule
을 추가한 main repo
를 확인하면, 일반적인 directory
와 달리 화살표가 박혀있는 directory
로 표시되며, submodule
의 실제 repository
를 hyperlink
한다. @ (at sign)
뒤의 정보는 각 submodule
의 latest commit
을 의미한다.
submodule
을 포함한 project
clone submodule
을 포함한 project
를 clone
하게 되면 submodule
폴더가 텅 비어있게 된다. 이게 default behavior
이며, 실제 submodule
의 내용을 가져오기 위해선 로컬의 submodule
정보를 바탕으로 submodule
의 remote repository
데이터를 끌어와야 한다.
git submodule init
git submodule update
submodule init
명령어를 통해 submodule
을 위한 local
설정 파일을 구성하고, submodule update
를 통해 remote
데이터를 끌어온 후, 현재 main project
가 저장하고 있는 submodule
들의 commit
정보를 바탕으로 checkout
한다.
submodule init
후 .git/config
파일을 확인해보면 각각의 submodule
이 등록되어 있음을 확인할 수 있다.
git submodule update
명령어는 main project
의 현재 snapshot
에 박혀있는 submodule
의 commit
정보를 바탕으로 checkout
하는 명령어일 뿐이다.
그래서 git branch
명령어로 현재 branch
를 찍어보면 detached HEAD
로 나오는 모습을 볼 수 있다. 따라서 해당 branch
에서 작업하지 말고, main
으로 checkout
한 후에 작업을 진행하는 것이 좋다.
git checkout main
submodule
한번에 불러오기submodule
이 많다면 각각의 submodule
에 들어가서 checkout
하기가 쉽지 않다.
git submodule foreach git checkout main
이러한 경우, submodule foreach
명령어를 사용해서 각각의 submodule
에 대해 명령어를 일괄실행할 수 있다.
submodule
추가git submodule add <submodule repository>
submodule
불러오기git submodule init
git submodule update
submodule
일괄 checkout
git submodule foreach git checkout main
[사이트] https://git-scm.com/book/ko/v2/Git-도구-서브모듈
[사이트] https://pinedance.github.io/blog/2019/05/28/Git-Submodule
[사이트] https://stackoverflow.com/questions/44366417/what-is-the-point-of-git-submodule-init