오늘은 merge의 종류들 중 rebase&merge와 squash&merge에 대해 알아보려고 합니다!
PR을 올리고 해당 PR을 merge를 할 수 있는 방식에는 총 3가지가 있습니다.
- merge
- Squash and merge
- Rebase and merge
merge
그냥 가장 일반적인 merge입니다. 아무런 설정도 하지 않았을 때 default 값이죠.
NHN Cloud meetup자료에 잘 설명된 그림이 있어서 가져와 보았습니다.
일반 merge를 하게 될 경우에는 브랜치에서 커밋된 a->b->c 친구들을 참조하는 새로운 커밋 노드인 m이 생성됩니다. 이 m이라는 커밋 노드는 parent로 init과 c를 가지게 됩니다.
Squash and Merge
다음은 Squash and Merge입니다. 음..Squash라는 단어는 "밀치고 들어가다, 헤치고 들어가다" 라는 뜻을 지니고 있나봐요.
실제로 동작하는 방식이 그런 단어의 의미를 잘 살리고 있는지는 모르겠지만 그림을 보면..
브랜치에서 커밋된 a->b->c 친구들을 한데 모아 놓은 커밋이 새롭게 생성되며 머지가 됩니다. 이 때 이 커밋은 parent로 init만을 가지게 됩니다.
squash는 처음 공부하는거니까 실습을 해보았어요.
예를들어 만약, 아래와 같이 커밋된 3개의 기록이 Squash and Merge를 통해 merge해 줄 경우
다음과 같이 하나의 커밋내에 3개의 커밋이 함께 기록됩니다.
Rebase and Merge
rebase가 그나마 익숙하죠..? 이전 글에서도 알아보았듯 rebase 는 브랜치의 시작점을 똑 떼어서 붙이는 느낌입니다.
브랜치에서 커밋된 a->b->c 친구들을 그대로 옮기는 방식입니다. 그렇기 때문에 새로운 커밋이 추가되지않으며 브랜치가 없었다는 듯 linear한 history를 보실 수 있습니다.
그럼 각 merge를 언제 사용?
저는 보통 git flow를 따르면서 협업을 하는데 그럴경우 master
, develop
, feat
, hotfix
브랜치를 파게 될 거에요.
master
는 정말 최최최종, develop
은 PR을 approved받고 merge한 경우, feat
은 실제로 개발할 때 직접적인 커밋을 위해 사용하는 브랜치, hotfix
는 버그 잡는 용이겠죠? 이렇게 나뉘어져 있다고 가정했을 때,
develop
-feat
브랜치 간 merge- 사용: Squash and Merge
- 이유: feat 브랜치는 말그대로 실시간 개발용 브랜치이기 때문에 커밋 히스토리가 복잡한 경향이 있어요. 때문에 그러한 복잡한 커밋들을 모두 묶어 하나의 새로운 커밋으로 남기고, 그 하나만을 develop 브랜치에서 관리하는 편이 더 수월하답니다. 또한, Rebase를 사용하게 되면 어느 지점부터 새로운 브랜치의 작업인지 구분이 사라지기 때문에 피하게 되는 것 같아요.
master
-develop
브랜치 간 merge- 사용: Rebase and Merge
- 이유: develop의 내용을 master에 추가한다는 건 무언가 새롭게 버전업을 하기 위한 경우가 대부분이기때문에 굳이 일반 merge로 불필요한 새로운 커밋을 만들 필요가 없으며 squash로 merge된 feat의 기록들을 또 한번 squash해 줄 필요가 없을거에요.
hotfix
-develop
/master
브랜치 간 merge- 사용: Merge / Squash and Merge
- 이유: Squash를 통해 머지했다는 커밋으로 흔적을 남기는게 좋을 것 같습니다!
마치며
rebase, squash는 항상 꼭 merge랑 사용해야하는 것은 아닙니다! rebase의 심리스한 특성과 squash의 모아서 보여주는 특성은 독단적으로 사용할 때도 유효하기 때문에 이 특성을 활용하여 history를 정리할 때에도 사용된답니다!
이렇게 오늘은 merge의 방식에 대해 알아보았습니다. 감사합니다 :)