레넌의 개발 일기

Git Merge와 Rebase의 차이 본문

Git

Git Merge와 Rebase의 차이

brorae 2022. 2. 17. 23:45

Git에서 한 브랜치에서 다른 브랜치로 합치는 방법은 두가지가 있다.

1. Merge

2. Rebase

 

1. Merge

Merge는 branch를 말 그대로 통합하는 것이다.

위와 같은 상황에서 hotfix 브랜치를 master 브랜치에 병합하고 싶다면 아래와 같이 코드를 작성하면 된다.

$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
  Fast-forward
   index.html | 2 ++
   1 file changed, 2 insertions(+)

hotfix 브랜치가 가리키는 C4 커밋이 C2 커밋에 기반한 브랜치이기 때문에 브랜치 포인터는 Merge 과정 없이 그저 최신 포인트로 이동한다. 이런 Merge 방식을 Fast-forward 라고 부른다. 이후, 더 이상 필요 없는 hotfix 브랜치는 삭제한다.

$ git branch -d hotfix

위와 같은 상황에서 iss53 브랜치를 master 브랜치에 병합하고 싶다면 위에서 입력한 것과 같이 입력해주면 된다.

$ git checkout master
$ git merge iss53
Merge made by the 'recursive' strategy.
  index.html |    1 +
  1 file changed, 1 insertion(+)

위에서 hotfix를 Merge 했을 때와 메시지가 다르게 나올 것이다. 현재 브랜치가 가리키는 커밋(C4)이 Merge할 브랜치의 조상(C2)이 아니므로 Fast-forward가 아니기 때문이다. 이 경우에는 각 브랜치가 가리키는 커밋 두 개(C4,C5)와 공통 조상 하나를 사용하여 3-way Merge를 한다.

Merge한 결과는 위와 같다.

 

2. Rebase

Rebase는 branch의 base를 옮기는 것이다.

위의 상황에서 두 브랜치를 합치는 가장 쉬운 방법은 위에서 사용한 Merge 명령어를 사용하는 것이다.

하지만 다른 방식으로, C3에서 변경된 사항을 Patch로 만들고 이를 다시 C4에 적용시키는 방법이있다.

$ git checkout experiment
$ git rebase master

위와 같이 명령어를 입력하면, 두 브랜치가 나눠지기 전인 C2로 이동하고 나서 그 커밋부터 지금 checkout한 브랜치(experiment)가 가리키는 커밋까지 diff를 차례로 만들어 어딘가에 임시로 저장해 놓는다. Rebase할 브랜치(experiment)가 합칠 브랜치(master)가 가리키는 커밋을 가리키게 하고 아까 저장해놓았던 변경사항을 차례대로 적용한다. 그 결과는 아래와 같다.

그리고 나서 master 브랜치를 Merge 명령어를 통해 합쳐준다.

$ git checkout master
$ git merge experiment

위와 같이 Fast-forward 된 것을 확인할 수 있다.

 

3. Rebase의 위험성

이미 공개 저장소에 Push한 커밋을 Rebase 해서는 안된다.

그 이유는 Rebase는 내용은 같지만 다른 커밋을 새로 만들기 때문에, 동료 중 누군가가 이전의 커밋에서 작업을 하다가 Push를 해버리면 동료는 다시 Merge를 해야한다. 그리고 나서 Merge한 내용을 다시 Pull하면 코드가 엉망진창이 될 수 있다.

 

4. 결론

  • Merge는 서로 다른 브랜치 2개를 통합하는 것이지만, Rebase는 브랜치의 base를 옮겨준다는 점에서 차이가 있다.
  • Merge와 Rebase는 최종 결과물에서는 같을 순 있지만, 커밋 히스토리에서 차이가 난다. 
  • Merge - 두 브랜치의 최종결과만을 가지고 합친다.
  • Rebase - 브랜치의 변경사항을 순서대로 다른 브랜치에 적용하면서 합친다.
  • Rebase는 리모트 브랜치에 커밋을 깔끔하게 적용하고 싶을 때 사용한다.

 

참고 - progit

 

 

 

 

'Git' 카테고리의 다른 글

Git Submodule로 비밀 정보 관리하기  (0) 2022.10.12