Git Subtree 사용하기

2 분 소요

디자인 개편을 진행하며 핵심이 되는 디자인 엘리먼트와 제품 개발에 필요한 파일을 분리하여 핵심 디자인 파일을 여러 저장소에 포함시키고 싶었다.

문제 해결을 위해 git submodule과 subtree를 찾게 되었다.

Git Subtree란?

저장소가 분리된 파일들을 하나의 저장소에 포함시켜 개발을 진행하고 싶을 때 사용하면 유용하다.

다른 저장소(하위 저장소)의 파일들을 상위 저장소에 추가하는 과정 Submodule과 똑같지만, Subtree는 하위 저장소에서 가져온 파일을 상위 저장소에서 직접 수정하고 변경 내역을 하위 저장소에 반영하는것이 가능하다.

Git Subtree 사용하기

  • 서브트리를 사용할 상위 저장소: https://github.com/user-name/design-product
  • 서브트리로 추가될 하위 저장소: https://github.com/user-name/design-core

1. 서브트리로 사용할 원격 저장소 추가

상위 저장소에서 서브트리로 사용할 하위 저장소를 원격으로 추가한다.

팀원들과 협업을 해야하기 때문에 자신의 원격 저장소(origin)에 먼저 push한뒤 하위 저장소의 upstream에 PR로 머지하자는 규칙을 세웠다.

그래서 원격 저장소는 2개를 등록한다:

  • origin-core: 자신의 원격 저장소
  • upstream-core: 팀 원격 저장소
# $ git remote add <원격 저장소의 이름> <원격 저장소의 주소>
$ git remote add origin-core <원격 저장소의 주소>
$ git remote add upstream-core <원격 저장소의 주소>

저장되어 있는 원격 저장소 주소는 아래와 같이 확인할 수 있다

$ git remote -v
origin ...
upstrea ...
origin-core ...
upstream-core ...

2. 새로운 원격 저장소의 브랜치를 서브트리로 추가

# $ git subtree add --prefix <클론할 폴더> <원격 저장소의 이름> <브랜치 이름>
$ git subtree add -P src/core <원격 저장소의 주소> main

서브트리를 클론할 폴더를 지정한다. 그리고 원격 저장소의 이름 (remote에서 확인 가능한) 참조할 브랜치 이름을 지정하면 서브트리로 design-core 저장소가 추가된다.

클론할 폴더는 그때그때 필요에 따라 정하면 된다. 대부분 라이브러리로 쓰려는거라 lib 로 정한다고 한다.

가장 안정화된 브랜치를 참조해야하기 때문에 main 을 참조하도록 한다.

3. 서브트리를 원격에서 내려받기 (pull)

서브트리의 원격에 올라온 커밋을 내려받는다. 이 때는 팀원의 작업 내역이 모두 병합되어있는 upstrea-core 원격 저장소에서 내려받아야한다.

# $ git subtree pull --prefix <클론할 폴더> <원격 저장소의 이름> <브랜치 이름>
$ git subtree pull --prefix src/core upstream-core main

이 때, 병합 되고나면 에디터가 열리면서 커밋 메시지의 저장을 요구한다. :wq 로 저장하고 나온다.

평소 작업 방식대로 fetch 한 후 merge 할 수 없다.

subtree 명령어에서는 pull 만 지원하기 때문이다. 이 문서 참조

4. 서브트리를 원격에 올리기 (push)

상위 저장소에서 서브트리의 소스를 직접 수정하고 커밋한 후, 서브트리의 원격에 푸시할 수 있다.

이 때는 바로 Upstream에 반영하는것이 아니라 먼저 origin-core 에 올린다. 이후 PR을 통해 Upstream에 반영해야한다.

# 상위 저장소에서 변경 내역 작성
$ git add <서브트리 파일 경로>
$ git commit -m"<커밋 메시지>"
$ git push origin <branch>

# 서브트리 저장소로 상위 저장소에서 작업한 변경내역 올려주기
# $ git subtree push --prefix <서브트리 파일 경로> <원격 저장소의 이름> <브랜치 이름>
$ git subtree push --prefix lib origin-core main

잘 올라가고 나면 Github로 이동해 upstream/main 으로 Pull Request를 열어 머지한다.

git subtree 관련 조작은 저장소 최상위 폴더에서 이루어져야한다.

Git 명령어 NPM Script에 추가하기

서브트리를 수행하기 위한 명령어가 너무 긴 관계로, 실제 작업 환경에서는 스크립트로 작성해서 사용했다.

상위 저장소 트리 깔끔하게 유지하기

서브트리에서 파일을 받아오고 올리는 과정에서 변경내역이 너무 지저분해지는 문제가 있었다.

이는 --squash 옵션으로 해결할 수 있다.

하위 저장소의 여러 변경 내역을 하나의 커밋으로 합쳐서 머지해주기 때문에 상위 저장소의 트리가 깔끔하게 유지될 수 있다.

# $ git subtree pull -P <서브트리 파일 경로> <원격 저장소의 이름> <브랜치 이름> --squash
$ git subtree pull -P src/core upstream-core main --squash

References

태그:

카테고리:

업데이트: