본문 바로가기

Devops/Git

[Git] Git branch merge, rebase 예제

Fast-forward merge

 

머지를 해오려는 다른 브랜치가 머지를 요청한 Base 브랜치의 Commit 히스토리를 모두 가지고 있으면 Fast-forward 상태라고 한다.

위 그림에서 git-test-a는 git-test-b의 모든 commit 내용을 가지면서 추가 commit을 가진 상태이다.

 

이상태에서 git-test-a -> git-test-b로 머지를 하면 Fast-forward merge락고 칭한다. 이 경우에는 별도의  Merge commit 은 생성하지 않는다.

 

skkkm@Kindlove MINGW64 /d/Temp/GitTest/git-test-b (git-test-b)
$ git merge origin/git-test-a
Updating 03137f7..f497512
Fast-forward
 .ide.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

skkkm@Kindlove MINGW64 /d/Temp/GitTest/git-test-b (git-test-b)
$ git push
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To github.com:skkkms/git-test.git
   03137f7..f497512  git-test-b -> git-test-b

 

Fast-forward로 머지가 되서 별도의 Merge into 히스토리 없이 git-test-b의 HEAD가 옮겨진것을 볼수 있다.

 

Fast-forward 병합은 별도의 병합 커밋을 생성하지 않기 때문에 히스토리가 선형적으로 유지된다. 이는 히스토리를 간단하고 깨끗하게 유지할 수 있게 해준다.

그러나, 이 방식의 단점은 브랜치의 존재와 작업 히스토리가 사라진다는 것이다. 따라서 특정 기능 개발이나 버그 수정의 과정을 히스토리에서 추적하고 싶을 때는 non-fast-forward 병합을 고려해야 할 수 있다.

Fast-forward 병합은 주로 작은 변경 사항이나 긴급한 버그 수정에 적합하며, 복잡한 기능 개발이나 여러 사람이 참여하는 프로젝트에서는 non-fast-forward 병합이 더 적합할 수 있다.

Non-Fast-forward 병합

 

Merge 하려는 Branch가 Merge 대상 브랜치에 대해서 Fast-forward가 아닐 경우에 두 브랜치를 머지 후 머지 commit 기록을 남긴다.

 

아래 상황은  git-test-a branch(보라색)는 git-test-a #6 새 commit을 수행한 상태이고 git-test-b branch(녹색)은 git-test-a #6  commit은 모른채 git-test-b #3 commit을 수행한 상태이다. 즉 git-test-a는 git-test-b의 모든 commit을 가지고 있지 않으므로 Non-Fast-forward 상태이다.

 

Git merge 명령어로 머지를 수행한다. (git-test-a -> git-test-b로 머지)

skkkm@Kindlove MINGW64 /d/Temp/GitTest/git-test-b (git-test-b)
$ git merge origin/git-test-a
Merge made by the 'ort' strategy.
 .ide.js | 1 +
 1 file changed, 1 insertion(+)

skkkm@Kindlove MINGW64 /d/Temp/GitTest/git-test-b (git-test-b)
$ git push
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 16 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 306 bytes | 306.00 KiB/s, done.
Total 2 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To github.com:skkkms/git-test.git
   b22da2a..9d16b87  git-test-b -> git-test-b

 

 

merge 결과 git-test-a #6이 머지되고 (보라색, 녹색선 연결됨) Mege remote-tracking branch 등의 머지 히스토리 커밋이 생긴다.

 

Rebase

 

git rebase는 한 브랜치의 변경 사항을 다른 브랜치에 적용하고자 할 때 사용됩니다. 이 과정에서 커밋의 기준점이 변경되어, 마치 변경 사항이 새로운 기준점에서 시작된 것처럼 보인다.

 

아래 상황에서 git-test-a 브랜치를 git-test-b 기준으로 rebase를 수행한다.

 

skkkm@Kindlove MINGW64 /d/Temp/GitTest/git-test-a (git-test-a)
$ git rebase origin/git-test-b (현재 git-test-a를 git-test-b 기반으로 rebase함)
Successfully rebased and updated refs/heads/git-test-a.

skkkm@Kindlove MINGW64 /d/Temp/GitTest/git-test-a (git-test-a)
$ git push (rebase 후 push를 하면 로컬과 remote가 달라져서 push가 안됨. git pull후 다시 수행한다.)
To github.com:skkkms/git-test.git
 ! [rejected]        git-test-a -> git-test-a (non-fast-forward)
error: failed to push some refs to 'github.com:skkkms/git-test.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. If you want to integrate the remote changes,
hint: use 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

skkkm@Kindlove MINGW64 /d/Temp/GitTest/git-test-a (git-test-a)
$ git pull -r
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 3 (delta 2), pack-reused 0 (from 0)
Unpacking objects: 100% (3/3), 278 bytes | 21.00 KiB/s, done.
From github.com:skkkms/git-test
   9d16b87..31d3ec1  git-test-b -> origin/git-test-b
warning: skipped previously applied commit e326b67
hint: use --reapply-cherry-picks to include skipped commits
hint: Disable this message with "git config set advice.skippedCherryPicks false"
Successfully rebased and updated refs/heads/git-test-a.

skkkm@Kindlove MINGW64 /d/Temp/GitTest/git-test-a (git-test-a)
$ git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 16 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 299 bytes | 299.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:skkkms/git-test.git
   337834f..7ddeffa  git-test-a -> git-test-a

 

Rebase 결과 git-test-b #3 commit이 들어와 있고 history도 선형적으로 재정렬되었다. 단 이때는 commit 번호도 새로 채번되어 들어가게 된다.

 

-- The End --