본문 바로가기

개발👩‍💻/git

git merge와 rebase의 차이: rebase의 이해

728x90

처음 rebase를 들었을 땐 어떻게 동작하는 것인지 이해가 잘 안됐다.

 

그래서 merge와 rebase의 차이가 무엇인지도 몰랐었음..

 

Merge와 rebase의 차이

  • Merge: branch를 통합하는 명령어
  • Rebase: branch의 base를 옮기는 명령어

위와 같이 차이점을 말해 볼 수 있다.

 

즉, branch를 통합하는 방법은 2가지이다.

  1. Merge만 한다
  2. Rebase를 한 후 Merge를 한다

Merge

$ git switch main
# 메인 브랜치에서
$ git merge <feature branch>
# 다른 브랜치와 병합

Rebase를 하는 이유는, merge를 하는 방법을 먼저 보면 이해하기 쉽다.

Merge하는 방법에는 2가지가 있다.

  1. fast-forward
  2. 3-way merge

(merge를 하는 곳(브랜치)를 main(master),

merge 대상 브랜치를 현재(feature) 브랜치라고 하겠음)

 

- fast-forward 

위와 같이 (merge할) 현재 브랜치가 main(master) 브랜치를 조상으로 하는 경우에 사용되며,

현재 브랜치의 가장 최근 commit으로 master branch의 Head를 옮기는 것을 fast-forward라고 한다.

 

- 3-way merget

일반적인 merge 방법으로, 

commit들의 조상이 각각 main, feature 브랜치들로 다를 때,

하지만 이 두 브랜치의 공통 조상이 있을 때(main) 사용한다.

공통 조상으로 하는 브랜치(Main)에 새로운 commit을 만들어서 병합한다.

 

이렇게 3-way merge 처럼 병합을 하다 보면, 큰 규모의 프로젝트를 할 때 log가 복잡해진다.

그래서 rebase를 한 후 merge를 하며 관리를 해준다면 commit history가 깔끔해지고,

Log history를 선형으로 만들 수 있다. 

작업들을 차례대로 수행된 것 처럼 보이게 만들 수 있다

--> 결국, 깔끔한 History 관리를 위해 사용하는 것

 

Rebase

$ git switch <feature branch>
# feature branch 에서 
$ git rebase <main branch>
# main branch로 rebase

Rebase는 feature branch에서 작업된 일련의 commit들을 main branch로 병합하기 위해 사용한다.

push 하기 전 commit 상태의 작업들을 rebase해야한다 (push 하고 나서 rebase x)

 

아래와 같이 순서대로 작업을 하고 rebase를 해보자

1. main branch 에서 main.txt 파일 하나 만들고 commit

2. main branch 에서 main.txt 파일 수정하고 commit

3. feature branch dev.txt 파일 만들고 commit

4. 거기서 dev.txt 파일 수정하고 commit

5. main으로 돌아와서 main.txt. 파일 수정하고 커밋

 

위 과정들을 다하고 나서 rebase하면

이렇게 main branch 끝에 feature branch 들의 커밋들이 붙는다. ($ git log 해보면 위와 같은 순서로 나옴)

아직 main branch의 head는 5번을 가리키고 있고, feature branch는 최신 commit에 head가 있다.

(5번이 시간적으로 나중에 된 commit이라고 해도 log상 feature branch 들의 log보다 뒤에 있다)

 

이제 branch를 main branch로 바꾸고 merge를 해주면 main branch의 head도 4번을 향하게 된다.

이게 fast-forward merge를 하기이다.

 

rebase안하고 그냥 merge했다면 3-way merge가 된다.

 

추가 궁금했던 거

 

1. 같은 파일을 다른 브랜치에서 수정해서 rebase할 수 있을까?
- 할 수 있다. 근데 하려고 하면 애러난다.
   commit log conflict가 나는데, 같은 파일을 수정했던 feature branch의 conflict file 에 대해 난다.
   해결하는 방법은 

$ git rebase <main branch>
$ git add/rm <conflict_file>
# 같은 파일
$ git rebase --continue

   위 코드를 해주면 rebase가능하다.

 

2. 위가 된다면 같은 파일은 어떻게 수정되나

- main branch 의 commits -> feature branch의 commit들 순서대로 수정한 log를 가지므로

  feature branch 최신 commit 을 기준으로 수정된다 (중간에 main에서 commit했던 게 계속 영향을 주는 거라면 거기에 맞게 수정요소가    있을 것)

 

3. main branch에서 파일들을 삭제하고 feature branch에는 남겨둔 후 rebase하면 파일이 남아있나?

- 이미 삭제 했던 로그가 같이 rebase되기 때문에 삭제된다.

반응형