Tools/Git&GitHub 2020. 3. 27. 21:41

 

Git에서 한 브랜치에서 다른 브랜치로 합치는 방법은 두 가지다. 하나는 이전 포스팅에서 다룬 Merge이고 다른 하나는 Rebase이다. Rebase 상황을 이전 포스팅에서 다루어봤던 merge 상황이랑 비교해보자.

 

 

Git - fast-forward merge 란? fast-forward & 3-way Merge의 차이점

1. fast-forward merge 아래와 같은 상황이 있다고 가정하자. issue 처리를 위해 master 브랜치에서 브랜치를 따서 작업을 하고 있었다. 갑자기 픽스해서 빠르게 릴리즈해야할 버그 사항이 있어 hotfix 브랜치를..

coding-start.tistory.com

 

아래와 같은 상황이 있다.

 

 

이 상황에서 3-way-merge를 하면 그래프상태는 아래와 같은 상태가 된다.

 

#current branch master

> git merge issue-1

 

 

그런데 Rebase를 하면 어떻게 될까?

 

#current branch issue-1

> git rebase master
> git checkout master
> git merge issue-1

 

 

실제로 일어나는 일은 일단 두 브랜치가 나뉘기 전인 공통 커밋(C2)으로 이동하고 나서 그 커밋으로부터 지금 Checkout(issue-1)한 브랜치가 가르키는 커밋까지 diff를 차례로 만들어 어딘가에 임시로 저장해 놓고(새로운 커밋을 만든다.), Rebase할 브랜치(master) 커밋 뒤에 차례로 붙여버린다. 그리고 master에서 issue-1 브랜치를 머지하면 fast-forward merge가 된다.

 

결론적으로 보면 합친다는 관점에서 같고 최종 내용 또한 같다. 하지만 Rebase가 좀 더 깨끗한 히스토리를 만든다. Rebase한 브랜치의 Log를 살펴보면 히스토리가 위 그림과 같이 선형으로 되어 있다. 

 

하지만 Rebase를 사용할 때 주의사항이 있다. git rebase master를 해서 master branch 커밋에 issue-1 커밋을 차례로 붙여버렸는데, 이 커밋은 새로 생성된 커밋이다. Rebase전의 C3 != Rebase후의 C3 인 것이다. 그러면 이 상황이 어떻게 주의를 해야하는 상황이 되어버린 것일까? 그 상황은 바로 이미 리모트 저장소에 Push한 커밋을 Rebase하는 상황이다. Rebase는 새로운 커밋을 만들어 뒤에 차례로 붙여버린다고 이야기 했는데, 이미 Push한 커밋을 Rebase하고 Push하면 나말고 다른 팀원이 보고 있는 커밋이 내용은 같이만 다른 커밋이 되어버린다. 이런 경우에는 똑같은 커밋이 두개가 생겨버리는 것이다. 엄청 혼란스러운 상황이다. 이런 상황은 서로 모든 팀원이 공유가 된 상태에서 "git pull --rebase(git fetch & git rebase)" 로 문제를 미리 방지할 수 있다.

 

뭐가 더 좋다고 할 수는 없지만 상황에 따라 잘 사용해야한다. 

posted by 여성게
:
카테고리 없음 2020. 3. 27. 20:38

 

1. fast-forward merge

 

아래와 같은 상황이 있다고 가정하자.

 

  1. issue 처리를 위해 master 브랜치에서 브랜치를 따서 작업을 하고 있었다.
  2. 갑자기 픽스해서 빠르게 릴리즈해야할 버그 사항이 있어 hotfix 브랜치를 master 기준으로 따서 작업을 했다.

 

버그를 픽스하고 테스트를 통과해 이제 릴리스 해야하는 상황이다. 이제 master에 hotfix를 머지해야되는 상황이다. 그런데 hotfix는 master를 베이스로 하고 있는 브랜치, 즉 master의 upstream 브랜치이다. 이제 머지를 하면 fast-forward 머지가 되는 것인데, 이것은 단순히 master가 바라보고 있는 커밋을 앞으로 이동하는 것(hotfix 브랜치가 가르키는 커밋을 master가 바라본다.) 뿐이다.

 

2. 3-way-merge

 

그렇다면 3-way-merge는 무엇일까? 위 상황과 차이점이 있다면 현재 브랜치가 가르키는 커밋이 Merge할 브랜치의 조상이 아니라는 점이다. 이 경우에 Git은 각 브랜치이 가르키는 커밋과 두 개 커밋의 공통 조상 커밋을 사용하여 머지하는 3-way-merge를 하게 된다.

 

우선 3-way-merge가 발생하는 커밋 플로우를 보자.

 

 

master 브랜치가 가르키고 있는 C4 커밋이 현재 브랜치가 가르키고 있는 C5의 조상이 아니다. 이유는 이전에 hotfix 브랜치를 머지하여 fast-forward merge가 발생했기 때문이다. 이때 3-way-merge가 발생하면 최적의 공통 조상을 자동으로 찾아서 머지한다. 다른 버전 관리 시스템은 개발자가 직접 공통 조상을 찾아서 merge해야 하는데 이점에서 보면 Git은 merge가 아주 쉽다.

 

 

fast-forward와는 조금 다른 방식임을 직접 그림으로 보면 명확하다. 새로운 커밋이 생겼기 때문이다. 또한 fast-forward merge와는 다르게 충돌(conflict)이 날 수 있다. 그 상황은 처음 상황을 되살려서 hotfix가 수정한 파일과 issue-1 브랜치에서 수정한 파일이 같은 부분을 수행했을 때 발생한다. 이때는 Git은 충돌이 났기 때문에 자동으로 새 커밋을 생성하지 않는다. 충돌이 나서 unmerged된 파일을 수정하고 수동으로 커밋을 해야한다.

posted by 여성게
: