Git Merge (fast-forward, 3-way, squash, rebase)

Git Merge (fast-forward, 3-way, squash, rebase)

이번 포스팅은 여러 종류의 Git Merge에 대한 특징 알아보려한다.

Fast-forward Merge


fastforward

Main branch의 commit 중 Feature branch의 조상 commit 이후로 변경된 사항이 없으므로, Feature branch를 Main branch로 merge할 경우 자연스레 Main branch와 Feature branch의 Head가 C를 가르키게 된다.

$ git switch Main
$ git merge Feature

3-way Merge


3way

내가 지금까지 기본적으로 사용한 merge 방법이다. Fast-forward merge에서 조상 commit 이후로 변경사항이 있다면 Main branch의 마지막 commit - C commit - 이를 합칠 D commit을 통해 merge가 진행된다.

$ git switch Main
$ git merge Feature

image

Squash Merge


squash

지금부터 보게될 merge 방법들은 사용해보지는 않았지만 3-way merge와 다르게 branch별 commit 내역을 깔끔하게 만들어준다는 장점이 있다. 그 중 Squash merge는 합쳐질 branch의 commit 내역을 모두 하나의 commit으로 합쳐 깔끔하게 구성한다.

$ git switch Main
$ git merge --squash Feature

# 충돌해결 후
$ git commit
  • Before

image

  • After

image

위 그림처럼 3-way merge와 다르게 Feature branch에서의 commit은 남지않고 하나의 merge commit으로 합쳐져 Main branch가 이어지는 것을 확인할 수 있다.

Rebase Merge


rebase

명령어 이름처럼 base를 Re 다시 지정하는 명령이다. 즉 기존 base가 조상 commit이었다면 지정한 branch를 조상으로 재지정한다고 생각하면 된다. 위 그림에서는 각각의 A, B, C Commit을 차례로 순회하면서 Main branch와 conflict를 해결하여 비로소 하나의 branch에서 작업한 것처럼 구성이 된다.

$ git switch Feature
$ git rebase Main

# 충돌해결 후
$ git rebase --continue

# Fast-forward로 Main branch의 Head를 옮긴다.
$ git switch Main
$ git merge Feature
  • Before

image

  • After

image

위 그림에서 최종적으로 Fast-Forward를 통해 Main branch의 Head만 옮기면 Feature branch는 온데간데없고 Main branch에서만 작업한 것처럼 구성된다.

결론


요즘 프로젝트를 여러개 진행하고 있다보니 PR과 Merge를 할일이 자주 생기고 있다. 기본적인 3-way merge만을 사용하고 있기에 여럿이서 만든 branch가 log에 뒤죽박죽 섞여 보기가 불편하게 되었다. 보기에는 Rebase merge기존 commit 기록도 재사용할 수 있고 유용하게 보이지만 Remote에 push된 commit 내역을 변경할 여부가 있기에 엄청난 리스크가 있다고 한다. 부딪혀보면 깨달을 수 있지만 큰 화?를 자초할 수 있기에 아무래도 Squash merge와 Rebase Merge는 팀원들과 상의 후에 상황에 적절하게 사용해야할 것 같다😥