신짱구의 개발일지

[Git] Submodule 실습 본문

DevTools/Git

[Git] Submodule 실습

신짱구개발자 2025. 2. 16. 19:16
더보기

1. Submodule 이란?

2. Submodule 동작 방식

3. Reference

Submodule이란?

프로젝트를 수행하다 보면 다른 프로젝트를 함께 사용해야 하는 경우가 종종 있다. 함께 사용할 다른 프로젝트는 외부에서 개발한 라이브러리라던가 내부 여러 프로젝트에서 공통으로 사용할 라이브러리일 수 있다. 이런 상황에서 자주 생기는 이슈는 두 프로젝트를 서로 별개로 다루면서도 그 중 하나를 다른 하나 안에서 사용할 수 있어야 한다는 것이다. 

 

Git의 서브모듈은 이런 문제를 다루는 도구이다. Git 저장소 안에 다른 Git 저장소를 디렉토리로 분리해 넣는 것이 서브모듈이다. 다른 독립된 Git 저장소를 Clone해서 내 Git 저장소 안에 포함할 수 있으며 각 저장소의 커밋은 독립적으로 관리한다. 

Submodule 동작 방식

Submodule의 동작 방식의 예시는 참고 문헌에 링크된 유튜브 영상을 기반으로 작성했다. 

현재 super, sub1, sub2 저장소가 생성되어 있고, sub1과 sub2의 디렉토리에는 1이라는 파일이 존재한다고 가정하자. 

1.  Submodule  추가

아래 명령어로 sub1의 저장소 주소를 먼저 찾는다. 

[sub1 Repo]
git remote -v

sub1 저장소를 super/lib 디렉토리에 클론한다. 

[super Repo]
git submodule add https://github.com/example/sub1.git lib

sub2 저장소를 super/module 디렉토리에 클론한다.

[super Repo]
git submodule add https://github.com/example/sub2.git module

클론 결과, super 디렉토리에 lib과 module 디렉토리 그리고, .gitmodules 파일이 생성된 것을 확인할 수 있다.

2. Submodule 추가 확인 (.gitmodules)

super/lib 그리고 sub1 저장소에서 git log 명령어를 입력하면 두 저장소 모두 같은 버전을 확인할 수 있다. 즉, 클론이 정상적으로 된 것이다.

git log --oneline

 

git status 명령어로 super 저장소에 어떤 변화가 있는지 확인하면, lib과 module 디렉토리 그리고, .gitmodules 파일이 새로 생성되었고 아직 commit 되기 전이라는 것을 알 수 있다. 

[super Repo]
git status

.gitmodules 파일은 저장소의 어떤 디렉토리에 어떤 다른 저장소가 클론되었는지 알 수 있다. 즉, submodule에 대한 연결 정보를 가지고 있다. 

[submodule "lib"]
	path = lib
    url = https://github.com/example/sub1.git
[submodule "module"]
	path = module
    url = https://github.com/example/sub2.git

3. Submodule 커밋

Submodule을 다른 사람에게 공유하기 위해 commit하고 원격 저장소에 push한다. 

[super Repo]
git commit -am "init submodule"
git push

4. Submodule 1개 업데이트

sub1 저장소에서 파일 1을 2로 변경하고, 원격 저장소에 push하여 업데이트한다.

[sub1 Repo]
mv 1 2;
git add .;
git commit -m 2;
git push;

5. 업데이트된 Submodule을 저장소에 적용

super 저장소에 적용하기 위해 루트에서 pull을 받을 수 없다. super 저장소에서 lib 디렉토리는 별도의 독립된 프로젝트이다. 그렇기 때문에 lib 디렉토리에서 git pull을 해야 적용이 된다. 즉, Submodule을 독립된 프로젝트라고 생각해야 한다.

[super/lib]
git pull

 

super 저장소에서 lib 디렉토리를 업데이트 했기 때문에 git status 명령어로 확인해보면 lib 디렉토리는 수정된 상태라는 것을 알 수 있다. 

수정된 파일이 문제가 없다는 것을 확인하고 변화된 Submodule을 commit하고 push한다. 

[super Repo]
git commit -am "update sub1 2"
git push

6. Submodule 2개 업데이트

sub1 저장소에서 파일 2를 3으로 변경한다. 

[sub1 Repo]
mv 2 3;
git add .;
git commit -m 3;
git push;

sub2 저장소에서 파일 1을 2로 변경한다.

[sub2 Repo]
mv 1 2;
git add .;
git commit -m 2;
git push;

7. 업데이트된 다수의 Submodule 저장소 업데이트 

1개 업데이트 했을 때처럼 super 저장소에서 lib과 module 디렉토리 각각을 pull 받는 것은 Submodule이 많아질 경우 비효율적이다. 업데이트 해야할 Submodule이 다수일 경우, git submodule update 명령어가 유용하다. 

 

--remote 옵션이 붙은 경우는 submodule들의 원격 저장소의 최신을 지역 저장소의 최신으로 업데이트 시킨다. 

[super Repo]
git submodule update --remote

--remote 옵션이 없는 경우는 super 프로젝트의 마지막으로 커밋된 버전으로 변경된다. 

[super Repo]
git submodule update

8. 로컬 저장소와 원격 저장소의 Submodule의 버전 확인

git submodule summary는 커밋되지 않은 Submodule들을 확인할 수 있다. 결과로 나오는 파일들이 아직 커밋되지 않았다는 의미이다. 

git submodule summary

git submodule 명령어를 통해서도 변경되었는지 확인할 수 있다. 앞에 +가 붙으면 커밋이 안된 것이고 +가 없으면 이미 커밋된 것이다,

git submodule

9. Submodule 내에 Submodule이 존재할 때 저장소 업데이트

--recursive 옵션은 Submodule 내에 또 다른 Submodule이 존재할 수 있다. 그런 경우, 하위에 있는 모든 Submodule을 동시에 업데이트할 수 있다. 

[super Repo]
git submodule update --remote --recursive

10. 저장소의 Submodule들의 로그 출력

super 저장소에서 아래 명령어를 입력하면, lib과 module 디렉토리에 연결된 Submodule들의 로그를 확인할 수 있다.

[super Repo]
git submodule foreach git log --online

11. Submodule이 존재하는 저장소 복제 시 유의사항

super 저장소를 상위 경로에서 다시 클론하면 하위 Submodule들도 같이 복제되지 않는다. 그 이유는 프로젝트에 Submodule이 수백개가 있고 각각의 Submodule이 또 수백 개의 Submodule을 가지고 있어 용량이 굉장히 크다고 가정하자. 이 경우 버그 하나 fetch하려고 임시로 프로젝트의 모든 부분이 복제되면 굉장히 비효율적일 것이다. 

그러하여 Submodule이 존재하는 저장소를 복제할 때 기본적으로는 하위 Submodule은 복제되지 않기 때문에 아래 명령어로 명시해줘야 한다. 

[super2 Repo]
git submodule init lib module

Reference

https://git-scm.com/book/ko/v2/Git-%EB%8F%84%EA%B5%AC-%EC%84%9C%EB%B8%8C%EB%AA%A8%EB%93%88

 

Git - 서브모듈

gitmodules 파일에 있는 URL은 조건에 맞는 사람이면 누구든지 Clone 하고 Fetch 할 수 있도록 접근할 수 있어야 한다. 예를 들어 다른 사람이 Pull을 하는 URL과 라이브러리의 작업을 Push 하는 URL이 서로

git-scm.com

 

https://www.youtube.com/watch?v=TAe4uZqYt6c

 

'DevTools > Git' 카테고리의 다른 글

[Git] Git Commit 기록에서 민감한 정보 지우기  (0) 2024.11.14
[Git] Commit 취소  (1) 2024.09.13