git submodule 중첩된 깃 사용하기

  • 깃 아래 깃..!

상황

1
2
3
4
5
super
├── client
│ └── 1
└── server
└── 1
  • 이런 구조의 프로젝트가 있다
  • super에서 git init 하여 프로젝트를 관리하다 보면
  • 깃 히스토리가 client 내용, server 내용이 합쳐져 있다
  • 구분하기 위해 커밋 메시지를 적을 때도 어떻게 적어야 할지 망설이게 된다
  • 그래서 super, client, server에 모두 git init하고
  • super에서는 client와 server를 gitignore에 추가하고 사용해봤는데,
  • 이것도 좋은 방법은 아닌 것 같았다
  • 그래서 nested git repository 라는 키워드로 검색했고 submodule 이라는 것을 사용하면 된다는 것을 알게 되었다
  • submodule을 사용하면 super 디렉터리에서 명령어 하나로 하위의 서브모듈 깃 프로젝트를 업데이트(pull) 할 수 있다

공부

  • 생활코딩님의 강의를 보고 공부했다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 전제조건
// 명령어를 실행하는 위치는 super 디렉터리이다
// submodule로 추가할 프로젝트(client, server)는 모두 git init으로 초기화된 깃 프로젝트이며 원격 저장소에 올라가 있어야 한다

// submodule 추가 // 처음 super에 서브모듈을 추가하는 과정이다
git submodule add {repo url} 디렉터리명

// 이후 다른 컴퓨터에서 super를 클론하는 경우
git clone {super-repo-url} // git clone https://github.com/chinsun9/super.git

// 하위 서브 모듈은 클론되지 않는다
// 서브 모듈도 가져오기
git submodule init
git submodule update

// 위 명령은 하위 모든 서브 모듈을 가져온다
// 특정 서브 모듈만 가져오고 싶다면
git submodule init {submodule명}
  • super에서는 하위 서브모듈의 변경을 감지하고,
  • 하위 모듈의 해시(특정 버전을 가리키는)를 기억하는 방식으로 관리된다
  • git submodule update 명령을 사용하여 super에서 저장하고 있는 특정 버전의 하위 모듈로 업데이트한다
  • git submodule update --remote 명령을 사용하여 각 하위 모듈을 최신 상태로 업데이트할 수 있다
  • 여러 컴퓨터에서 작업할 때 super를 클론하고 git pull && git submodule update 명령으로 한 번에 가져올 수 있겠다!

발생한 문제

1
2
3
4
5
6
git submodule update --remote

fatal: Needed a single revision
Unable to find current https://github.com/chinsun9/my-submodule/master revision in submodule path 'lib'
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
  • git submodule update --remote 명령을 실행하니 이런 에러가 발생했다
  • 나는 submodule을 알기 전에 그냥 하위에 또 다른 깃 디렉터리를 사용하고 있었는데,
  • 그 상태 그대로 submodule add하고 사용했더니 위 에러가 발생했다
  • 해결방법은 기존 하위 레포를 삭제하고 다시 git submodule update --remote를 실행한다
1
2
rm -rf lib/
git submodule update --remote
  • 혹시 특정 브랜치에 대해 가져오고 싶으면 .gitmodules 파일을 열고 branch 값을 명시해준다
1
2
3
4
5
6
7
8
9
10
// 수정 전
[submodule "client"]
path = client
url = https://github.com/chinsun9/my-submodule

// 수정 후
[submodule "client"]
path = client
branch = mybranchname // 추가됨!
url = https://github.com/chinsun9/my-submodule

참고