아둥바둥 개발일기

[Git] Merge vs Rebase - Git Branch 합치기 본문

Git

[Git] Merge vs Rebase - Git Branch 합치기

JoyyKim 2020. 12. 7. 17:53

우리는 깃을 쓰면서 브랜치를 나누어 안전하게 작업하고 완성된 작업을 다시 원래의 브랜치로 합쳐서 작업을 업데이트 한다.

깃에는 브랜치를 합치는 방법이 두 가지, MergeRebase가 있지만 깃을 처음 접하는 초심자들은 브랜치를 합칠 때 Merge만을 사용한다. 두 방법의 차이점을 알아보자.

 

합치는 명령어는 Merge와 Rebase이지만 실제 사용할 때에는 따로 사용하는게 아니다.

  1. Merge만 사용하기
  2. Rebase 후, Merge하기

예제를 통해 설명 하겠다.

현 상황은 master 브랜치에서 작업 중, 커밋 C2에서 experiment 브랜치를 생성해서 checkout 하고 C4커밋. master에서 C3커밋했다. 이제 작업이 완료된 experiment 브랜치를 master 브랜치로 합치려고 한다.

"C~"는 커밋이고 화살표는 자신의 부모 커밋을 바라보는 방향이다. ex) C1은 자신의 부모 커밋 C0을 바라본다.

master 브랜치에서 나뉜 experiment 브랜치

1. Merge

master 브랜치에서 experiment 브랜치를 Merge한다.

$ git checkout master
$ git merge experiment

충돌이 일어나지 않았다면 3-way Merge를 통해 별도의 Merge 커밋 C5를 만들고 master 브랜치는 C5로 최신화 된다.

3-way Merge를 통한 합치기. Merge 커밋 C5가 생성되었다.

Merge를 통한 브랜치 병합 과정에서 특징은 다음과 같다.

  1. experiment 브랜치는 변경이 되지 않음 (Merge 전의 각자 브랜치의 커밋 로그가 그대로 남아있음)
  2. Merge를 진행하는 주체는 master 브랜치이다. (master로 checkout한 후 experiment를 merge)

2. Rebase

Rebase도 브랜치의 병합이지만 조금 다르다. MergeMerge커밋을 통해 C3 C4 를 둘 다 가리키는 반면, Rebase는 C3 에서 변경된 사항을 Patch로 만들고 이를 다시 C4 에 적용시킨다.

 

요약: Rebase 명령은 한 브랜치에서 변경된 사항을 다른 브랜치에 적용한다.

 

이제 Rebase를 통해 두 브랜치를 합쳐보자

$ git checkout experiment
$ git rebase master

실행하면 아래와 같은 상태가 된다. master 브랜치는 그대로 있고 experiment의 작업(변경사항)이 master에게 옮겨왔다. 그리고 옮겨온 변경사항 커밋은 C4가 아니라 C4`이다. 이것은 experiment의 커밋로그가 내용만 복사되어 새로운 커밋이 됐다는 뜻이다. 자세한 내용은 나중에 설명하겠다.

Rebase를 통한 브랜치 합치기. experiment의 커밋이 복제되어 master에 적용되었다.

일단 명령어를 보면 Merge와는 조금 다른 점이 있다. 일단 Rebase를 하는 주체 master가 아니라 experiment다.

정확한 설명인지 자신은 없지만 나는 "experiment가 자신의 base, C2에서 master의 최신 커밋 C3로 base를 옮김, 즉 Rebase 했다"고 생각하니 이해하는데 도움이 되었다.

 

공식문서의 자세한 설명은 이렇다.

실제로 일어나는 일을 설명하자면 일단 두 브랜치가 나뉘기 전인 공통 커밋으로 이동하고 나서 그 커밋부터 지금 Checkout 한 브랜치가 가리키는 커밋까지 diff를 차례로 만들어 어딘가에 임시로 저장해 놓는다. Rebase 할 브랜치(experiment)가 합칠 브랜치(master)가 가리키는 커밋을 가리키게 하고 아까 저장해 놓았던 변경사항을 차례대로 적용한다.

아직 끝난게 아니다. master를 C4`로 최신화해줘야 한다. 아래의 명령어로 master를 Fast-forward 시켜주자

$ git checkout master
$ git merge experiment

master를 Fast-forward 시켜 최신화 해준다

master입장에서 experiment는 자신보다 앞서있는 브랜치이기 때문에 merge 명령어를 실행하면 별다른 병합 없이 해당 브랜치까지 전진하는데 이걸 Fast-forward 라고 한다. 이렇게 하면 master에 experiment의 작업이 모두 적용되었다.

 

 

참고

Git 브랜치 - Rebase하기
Git 브랜치 - 브랜치와 Merge 의 기초
Comments