Git Merge 전략에 대하여

이예슬·2023년 4월 9일
0
post-thumbnail

블로그를 이전했습니다(https://yeseul-blog.vercel.app/)


지난번에 아는 개발자분과 이야기 하면서 그 분 회사에서는 rebase merge를 merge 전략으로 사용하신다는 말을 들었다.
나는 일반적인 merge만 사용해봤었기 때문에 merge에도 전략이 있다는 사실을 처음 알았고 그래서 이번에는 merge 전략에 대해 정리한 내용을 작성해보려고 한다.


Merge 전략

먼저 git의 merge 전략은 아래와 같은 세 가지로 나눌 수 있다.

  • merge
  • rebase and merge
  • squash and merge

어떤 전략을 사용하는지에 따라 commit history가 달라진다. 따라서 상황에 맞는 merge 전략을 사용하면 history를 원하는 방식으로 남길 수 있다.

Merge

일반적으로 사용하는 merge 방식이다.

git checkout main
git merge feature/1

아래의 그림과 같이 init 브랜치에서 분기하여 a, b, c 라는 commit이 생성되어 있을 때 다시 init 브랜치로 merge할 경우 m 이라는 새로운 merge commit이 생긴다. m은 부모로 init과 c를 가진다.

이러한 방식을 사용하게 될 경우 아래와 같이 commit 로그와 merge 로그가 동시에 기록된다. commit 로그는 commit을 행한 순서대로 기록되고 merge 로그는 merge가 된 순서대로 기록된다. 즉 commit 로그의 순서와 merge의 순서가 다르기 때문에 history 관리에 어려움이 있다.

Squash and Merge

squash and merge는 병합하는 브랜치의 commit들을 합쳐 하나의 commit으로 만들어 mege하는 방식이다.

git checkout main 
git merge --squash feature/1
git commit 

즉 init 브랜치에서 분기하여 a, b, c의 commit을 생성한 후 squash and merge 전략으로 병합하게 될 경우 a, b, c commit이 합쳐진 하나의 commit이 init으로 병합된다. 이 때 a, b, c commit은 parent를 init 하나만 가진다.

Merge된 순서대로 master/main 브랜치에 기록된다. 그리고 작업 완료된 브랜치의 commit은 새로운 commit 으로 모두 squash되며, 새로운 commit의 제목은 PR 제목이 되고, 합쳐진 commit의 제목은 새로운 commit의 상세 내용이 된다.

이러한 특징으로 인해 atomic commit level로 rollback 하는 것은 불가능하다.

Rebase and Merge

rebase and merge는 현재 브랜치의 모든 commit을 병합 대상 브랜치로 추가하는 방식이다. 그러므로 각각의 commit들은 모두 하나의 부모를 가진다.

git checkout feature/task-2
git rebase dev 

// conflict 발생시 commit이 아닌 rebase --continue를 사용해야 함 
git add . 
git rebase --continue 

// rebase 취소하기 위해서는 --abort를 사용하면 된다. 

// 여기까지 진행하면 feature/task-2의 변경사항이 dev 브랜치의 앞 쪽으로 위치가 옮겨졌을 뿐 dev에는 아직 feature/task-2의 변경 사항이 적용되지 않았다. 

git checkout dev 
git merge feature/task-2

init에서 분기된 브랜치에서 a, b, c 각각의 commit을 작성하고 해당 브랜치를 rebase and merge 전략을 사용해 병합할 경우 init 브랜치에 모든 commit이 추가되며 merge를 위한 추가 commit은 생성되지 않는다.

또한 rebase and merge의 경우 commit 순서대로가 아닌 merge 순서대로 기록된다. 즉 하나의 PR에 담긴 commit이 다른 PR의 commit과 섞이지 않는다.
이로 인해 PR 단위의 history 관리가 용이하며 squash merge와 달리 atomic level로의 rollback도 가능하다.

하지만 모든 commit이 병합되는 브랜치에 기록되므로 history가 방대해질 수 있다.

그렇다면 각각의 merge 전략은 언제 어디서 사용되는 것이 유리할까?

dev - feature merge

물론 팀마다 전략에 따라 다르지만 feature 브랜치에서 작업한 commit의 경우 모든 commit과 commit message가 dev에 들어갈 필요는 없는 경우가 많다.

그러므로 feature 브랜치를 dev로 머지할 때는 복잡한 commit history를 하나로 묶어 새로운 commit으로 만들 수 있는 squash and merge를 사용하는 것이 유리하다.

일반적으로 feature 브랜치를 병합한 후에 모두 삭제해버리는 경우가 많으므로 feature의 commit history를 모두 dev에 연관지어 남길 필요는 없다.

master - dev merge

dev에서 master로 병합할 경우에는 모든 commit 기록이 남아야 하고 history가 섞이면 좋지 않으므로 squash and merge가 유리하다.

hofix - dev, hotfix - main merge

merge 혹은 Squash and merge 모두 유리하다.

hotfix 작업의 각 commit history가 모두 남아야 하는 경우 merge, 필요 없는 경우 squash and merge를 사용하면 좋다.


https://inmoonlight.github.io/2021/07/11/Git-merge-strategy/

profile
꾸준히 열심히!

0개의 댓글