[git] 다양한 Merge 방법 (Merge, Squash and Merge, Rebase and Merge)
Merge
일반적으로 많이 사용되는 병합으로, 커밋 이력을 모두 남길 때 사용한다.
git checkout jangjjolkit
git merge my-branch
이 방식은 다시 Fast-Forward 방식과 Recursive 방식으로 나뉜다.
Fast-Forward
새로운 브랜치 my-branch가 jangjjolkit 브랜치로부터 분기된 이후 jangjjolkit 브랜치에 새로운 커밋이 올라오지 않았다면, my-branch 브랜치가 jangjjolkit 브랜치와 비교하여 최신의 브랜치라고 할 수 있다. 이런 경우 my-branch의 변경 이력을 그대로 jangjjolkit으로 가져올 수 있는데, 이를 Fast-Forward Merge라고 한다.
Recursive
my-branch가 jangjjolkit 브랜치에서 분기되고 jangjjolkit 브랜치에 새로운 커밋이 생겼다면, my-branch를 최신이라고 간주할 수 없다. 따라서 my-branch와 jangjjolkit 브랜치를 공통 부모로 한 새로운 Merge Commit을 생성하게 된다. 이러한 방법을 Recursive Merge라고 한다.
Fast-Forword Merge가 가능한 상태에서 git merge 명령어에 --no--ff 옵션을 주면 강제로 Merge Commit을 생성하게 할 수 있다.
Squash and Merge
Squash는 여러 개의 커밋을 하나의 커밋으로 합치는 것을 의미한다. (a, b, c를 합쳐서 새로운 커밋으로 만들고, Merge 대상 브랜치에 추가, 'a, b, c' 커밋은 parent를 Init 하나만 가짐)
Squash Merge는 병합할 브랜치의 모든 커밋을 하나의 커밋으로 Squash한 새로운 커밋을 Base 브랜치에 추가하는 방식으로 병합하는 것을 의미한다.
Squash를 하게 되면 모든 커밋 이력이 하나의 커밋으로 합쳐지고 사라진다는 점을 주의해야 한다.
git checkout jangjjolkit
git merge --squash my-branch
git commit -m "Squash and Merge"
Rebase And Merge
Rebase를 알아보기 전에 Base가 무엇인지 알아야 한다. my-branch가 jangjjolkit 브랜치의 Init 커밋에서 분기되었다고 하면 my-branch 브랜치의 Base는 Init 커밋이다.
그렇다면 Rebase란 무엇일까? 말 그대로 Base를 다시 설정한다는 의미이다. 그럼 Base를 어디로 다시 설정할까? my-branch 브랜치가 분기된 jangjjolkit 브랜치의 최신 커밋이다.
Rebase를 하면 커밋들의 Base가 변경되므로 Commit Hash 또한 변경될 수 있다. 이로 인해 Force Push를 해야할 경우도 있으니 주의해야 한다.
git checkout my-branch
git rebase jangjjolkit
git checkout jangjjolkit
git merge my-branch
명령 순서를 보면 알 수 있듯이 결과적으로 Fast-Forward Merge를 사용하는 것을 알 수 있다.
사용 시기
언제 어떤 방식을 사용해야 할까?
설명하기 전 브랜치의 종류에 대해서 정리해보겠다.
feature : 기능을 개발하는 브랜치
develop : 다음 출시 버전을 개발하는 브랜치
main : main 브랜치
feature → develop Merge
Squash and Merge가 유용하다. feature 브랜치에서 기능을 개발하기 위한 지저분한 커밋 내역을 하나의 커밋으로 묶어 develop 브랜치에 병합하면서, develop에는 기능 단위로 커밋이 추가되도록 정리할 수 있다.
또한 feature 브랜치는 develop 브랜치에 병합 후 제거되므로, Merge Commit을 남길 필요가 없다.
develop → main Merge
main 브랜치는 지금까지 작업한 모든 기능을 배포할 때 병합한다. develop 브랜치를 Squash and Merge하게 되면 커밋 이력이 모드 사라져, 특정 기능에서 문제가 생겼을 때 롤백할 수 없게 된다. main 브랜치 또한 Merge Commit을 남길 필요가 없다. 따라서 Rebase And Merge가 적합하다.
참고
https://www.geeksforgeeks.org/merge-strategies-in-git/