2.1깃 병합 전략들
merge, rebase와 cherry-pick 비교
TL;DR
추억의 쪽지 시험
새 회사의 프로젝트에 온보딩하며, 지금까지 해오던 것과 다른 깃 컨벤션을 배울 기회가 생겼다. 또, 기존과는 다른 브랜치 전략에서 협업하며 처음으로 써본 깃 병합 전략(cherry-pick
)도 있었다. 이번 기회에 서로 다른 깃 병합 전략들과 옵션들을 정리해본다.
1. merge, rebase와 cherry-pick
이 세 개는 모두 깃 브랜치(또는 커밋)를 합치는 방식들인데, 모두 그 동작법이 다르고 그에 따라 목적이 다르다.
우선 가장 많이 써본 merge는 두 개의 브랜치가 있을 때 두 브랜치의 끝을 합쳐서 새로운 merge commit
을 생성하는 방식이다.
예를 들어, main
브랜치가 있고 이 브랜치의 코드가 상용 배포된 상태라면 개발 시엔 develop
브랜치로 분기(git checkout -b develop
)해서 개발 후, main
브랜치로 돌아와 develop
브랜치를 병합한다.
bashgit merge develop

이 방식은 기본적으로는 히스토리를 있는 그대로 보존한다. 누가 언제 다른 브랜치에서 작업해서 언제 합쳤는지 추적이 가능하다.
merge는 가끔 별도의 merge commit 없이, 즉 3-way merge가 아닌 방식으로도 합칠 수 있다. 만약 새 브랜치와 base 브랜치가 있었는데, base 브랜치엔 커밋이 딱히 없었고 새 브랜치에만 커밋이 있었다면(즉, 공통 조상과 현재 브랜치 사이에 차이가 없어서, 포인터만 이동하면 되는 경우) 그냥 새 브랜치의 맨 마지막 커밋을 그냥 base 브랜치의 맨 마지막 상태로 보면 되는 것이다. 이걸 fast-forward
라고 부른다.

다만 병합 히스토리를 남기는 것이 동료들이 추적하거나 기록을 파악하는데 더 용이한 경우도 있다. 이런 경우엔 --no-ff
플래그로 fast forward를 막는 옵션을 설정할 수 있다. 참고로, 앞서 굳이 --ff
플래그를 달지 않았는데도 fast forward가 된 것은 이게 기본 설정이기 때문이다.
bashgit merge develop --no-ff
이렇게 merge하고 브랜치를 삭제하고 싶으면 git branch -d <브랜치명>
을 실행한다. 만약 merge되지 않은 브랜치지만 삭제하고 싶다면 -d
대신 -D
를 쓰면 된다.
--squash
를 쓰면 다른 브랜치의 많은 커밋을 하나의 커밋으로 합쳐서 반영할 수도 있다. 이때는 실제 merge
가 되진 않고 단일 커밋으로 준비가 되어, git commit
으로 반영을 해줘야 한다.
bashgit merge develop --squash
rebase는 깃을 병합하면서도 커밋들이 별도 브랜치에서 작업한게 아닌, 마치 base 브랜치에서 작업했던 것처럼 커밋을 다시 적용해 히스토리를 재작성하는 방식이다. 이를 위해서 우선 별도 브랜치로 checkout
한다음, 합쳐지고자 하는 base 브랜치에 rebase
한다.
bashgit checkout develop git rebase main

왜 굳이 merge
를 두고 rebase
로 합칠까? 이는 커밋들을 봤을때 이력 파악이 보다 쉽기 때문이다. 브랜치가 나뉘었다 합쳤다가 또 나뉘었다 합쳤다가...하는 것을 보다보면 정작 중요한 코드 변경 내역을 확인할 시간을 뺏긴다. rebase
는 하나의 브랜치에서 커밋 메시지와 코드의 변화를 보다 깔끔하게 파악하게 해준다.
즉, rebase
의 목적은 히스토리 정리다.
cherry-pick은 커밋 몇 개만 발췌해서 옮긴다. 이번에 나는 회사에서 팀원들이 장기 프로젝트인 언어 번역 작업을 하는 도중에 상용 웹페이지의 버그를 수정했어야 했다. 언어 번역 작업이 상당히 진행된 와중에, 상용에 버그를 수정하고 나니 해당 커밋들을 언어 번역 작업이 진행중인 브랜치에도 옮겨야 했다.
이 때 방법을 찾다가 알게된 것이 cherry-pick
이다. git log
로 옮겨야하는 커밋 해시들을 파악하고, 해당 브랜치에서 필요한 커밋들을 cherry-pick
해왔다.
bashgit checkout i18n git cherry-pick <hash1> <hash2> <hash3> ...