Git Subtree

오민영·2023년 2월 20일
1

Git

목록 보기
4/4

Git Subtree란?

Git Subtree는 상위 저장소에 파일을 직접 추가하고 트래킹한다. 자연히 서브트리의 파일 및 변경사항도 상위 저장소에 기록된다. 그리고 서브트리의 원격에 있는 소스와 상위 저장소에 있는 소스가 서로 달라도 subtree merge 기능을 사용해 양쪽의 변경사항을 모두 반영할 수 있다.

즉, 상위 저장소에서 서브트리를 직접 수정하고 서브트리의 원격에 푸시할 수 있다는것이 서브모듈과의 큰 차이점이다. 예를 들어 서브트리의 컴포넌트를 상위 저장소 프로젝트에서 사용할 때 버그를 발견했다면, 즉시 수정해서 커밋한 후 버그를 해결한 상태로 서브트리의 원격에 반영할 수 있다.

단점은, 서브트리를 추가한 모든 사용자가 서브트리의 내용을 자유롭게 변경해 원격에 푸시할 수 있다는 점이다. 프로젝트를 공동으로 진행할 때 어떤 사람이 작업한 feature-a 브랜치에서 작동하는 서브트리의 소스를 푸시했는데, 그것을 내려받은 다른 사람의 feature-b 브랜치에서는 오류가 발생할 수도 있다. 소규모 팀이라면 쉽게 대응 가능할 것이지만, 어찌되었든 공용 소스 코드 수정에 엄격한 기운을 세우는게 필요하다

(예시) Git Subtree 사용하기

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

$ git remote add design-core https://github.com/ohmy0418/design-core

$ git remote add <원격 저장소의 이름> <원격 저장소의 주소>

design-core 라는 이름으로 새로운 원격 저장소가 추가되었다.

$ git remote
origin
design-core

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

$ git subtree add --prefix <클론할 폴더> <원격 저장소의 이름> <브랜치 이름>

$ git subtree add -P src/style-core https://github.com/onlyeon/design-core main

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

design-core를 라이브러리처럼 사용하도록 추가하는거기 때문에 폴더명을 lib 로 지정하고, 가장 안정화된 브랜치를 참조해야하기 때문에 main 를 참조하도록 한다.

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

서브트리의 원격에 올라온 커밋을 내려받는다.

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

$ git subtree pull -prefix src/style-core core-upstream dev

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

평소 진행하던대로 fetch 한 후 merge 할 수 없다. subtree 명령어에서는 pull 만 지원하기 때문이다. 이 문서 참조

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

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

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

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

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

References


작업 하다 충돌이 발생한 경우

IDG에서 작업 완료시, IDC로 push 하기 전에 IDC의 변경내역을 pull 해주는 과정이 필요합니다. 그냥 Push 할 경우 다른 작업자가 올린 내용과 충돌이 발생할 수 있기 때문입니다.

  1. status 로 변경내역을 확인하고 add 로 추가, commit 을 남깁니다.
  2. git lg2 명령어로 현재 작업 내역이 어떻게 올라가 있는지 확인할 수 있습니다.
  3. npm run pull 로 IDC의 작업 내용을 가져옵니다.
  4. npm run push 로 IDG에서 작업한 내용을 올립니다.
  5. 원격 저장소에 가서 PR후,머지 합니다.

이제, IDG의 작업 내역을 Push 해 다른 작업자들과 공유하려 합니다. 이 저장소도 마찬가지로 push 하기 전에 upstream의 변경 내역을 pull 해주는 과정이 필요합니다.

이번에는 바로 pull로 병합시켜버리지 않고 fetch 로 가져온 후 merge 해보려 합니다.

  1. git fetch upstream 으로 upstream의 변경내역을 가져옵니다
  2. git lg2 로 변경 내역 등을 확인합니다
  3. git merge upstream/dev 로 dev 브랜치와 병합해줍니다
  4. 충돌 발생하면 충돌을 해결해줍니다

👣 Subtree push시 오류 해결

npm run push 시 아래와 같은 오류가 발생했다.

git push using:  core-origin setting
To https://github.com/ohmy0418/IRIS-Design-Core.git
 ! [rejected]        8c26801ea5237107348ae2f0370509e4ac451790 -> setting (non-fast-forward)
error: failed to push some refs to 'https://github.com/ohmy0418/IRIS-Design-Core.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

이 경우, 아래와 같은 명령어로 강제 push 한 이후로는 작업이 원활하게 진행된다.

git push core-origin `git subtree split --prefix src/style-core setting`:setting --force

참고 자료

Why can't I push this up-to-date Git subtree?

profile
이것저것 정리하는 공간

0개의 댓글