본문 바로가기
기타/Git

[Git] Merge 기초

by 코딩하는 랄로 2024. 1. 4.
728x90

branch를 생성하고 이동시키는 방법에 대해서 공부하였으니 이제는 branch를 합치는 작업인 merge에 대해서 공부해보자. merge에 대해서 본격적으로 공부하기 위해서 하나의 시나리오를 통해 merge의 기초에 대해서 먼저 공부해보자.

 

 

merge 기초

먼저 시나리오를 살펴보자. 

  • 현재 배포 중인 웹 사이트가 있다. ( master branch )
  • 새로운 이슈를 처리하기 위한 branch를 생성 
  • 새로 만든 branch에서 작업을 진행하는 중 급하게 처리해야 할 버그 발생
  • 작업을 중단하고 이전의 운영 브랜치(master) 로 이동
  • 버그 해결을 위한 브랜치 생성
  • 버그 해결 후 해당 브랜치를 운영 브랜치로 merge
  • 다시 이슈 해결을 위한 브랜치로 이동 후 작업 진행

해당 시나리오대로 실제로 진행해보면서 branch의 기초에 대해서 알아보겠다. 먼저 이전 글의 예제의 master branch를 운영 branch로 사용을 하겠다. 이전 예제에서 생성한 ralro branch는 제거하자.

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master)
$ git branch -D ralro
Deleted branch ralro (was b535f19).

 

branch를 삭제하기 위해서는 git branch의 -d 옵션을 사용하면 되지만, 해당 branch가 merge를 진행한 상태가 아니면 -d 옵션으로는 삭제가 안되기 때문에 -D 옵션을 통해 강제로 삭제할 수 있다.

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master)
$ git log --pretty --graph --all
* commit f6421947d66d855a74cec90d7631c680307ea31a (HEAD -> master)
| Author: yusanggon <yusang5159@naver.com>
| Date:   Wed Jan 3 22:40:36 2024 +0900
|
|     file5 add
|
* commit 0aa91caa5c0df5947982b199202c6495c8d0aa59
  Author: yusanggon <yusang5159@naver.com>
  Date:   Tue Jan 2 21:00:46 2024 +0900

      Add three files

 

현재는 운영 branch인 master branch만 존재하고 커밋 히스토리는 위와 같다. 이 상황에서 53번 이슈를 처리하기 위한 branch를 하나 생성하여 보자. branch를 생성 후 바로 checkout 하기 위해서는 git checkout 옵션에 -b 옵션을 주면 된다.

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master)
$ git checkout -b iss53
Switched to a new branch 'iss53'

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (iss53)
$ git log --pretty --graph --all
* commit f6421947d66d855a74cec90d7631c680307ea31a (HEAD -> iss53, master)
| Author: yusanggon <yusang5159@naver.com>
| Date:   Wed Jan 3 22:40:36 2024 +0900
|
|     file5 add
|
* commit 0aa91caa5c0df5947982b199202c6495c8d0aa59
  Author: yusanggon <yusang5159@naver.com>
  Date:   Tue Jan 2 21:00:46 2024 +0900

      Add three files

 

iss53 branch를 생성한 후에 몇가지 작업을 진행하여 커밋을 했다고 가정하여 보자.

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (iss53)
$ echo "modified" > file5.txt

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (iss53)
$ git commit -am "handle iss53"
[iss53 0309b6d] handle iss53
 1 file changed, 1 insertion(+), 1 deletion(-)

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (iss53)
$ git log --format=oneline --graph --all
* 0309b6d2ddc15ff23aadffd055f52106fe11d493 (HEAD -> iss53) handle iss53
* f6421947d66d855a74cec90d7631c680307ea31a (master) file5 add
* 0aa91caa5c0df5947982b199202c6495c8d0aa59 Add three files

 

이 때, 운영 branch에서 즉각적으로 해결해야 할 버그가 발생하여 운영 branch로 되돌아간 후 버그 해결을 위한 branch를 생성하여 해결하여보자.

 

branch를 이동할 때 주의할 점은, 기존의 branch에서 커밋하지 않은 파일이 이동할 branch와 충돌이 나면 branch를 이동할 수 없다. 그렇기 때문에, branch를 이동하기 전에는 stashing과 cleaning을 통해 워킹 디렉토리를 정리해주어야 하는데 이에 대해서는 추후에 배워보겠다. 현재는 커밋하고 옮기도록 하자.

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (iss53)
$ git checkout master
Switched to branch 'master'

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master)
$ git checkout -b bug
Switched to a new branch 'bug'

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (bug)
$ echo "bug" > file1.txt

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (bug)
$ git commit -am "handle bug"
[bug 20cd591] handle bug
 1 file changed, 1 insertion(+), 1 deletion(-)

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (bug)
$ git log --format=oneline --graph --all
* 20cd5917b3604a65a8c9a1d756a944e4513ce1a9 (HEAD -> bug) handle bug
| * 0309b6d2ddc15ff23aadffd055f52106fe11d493 (iss53) handle iss53
|/
* f6421947d66d855a74cec90d7631c680307ea31a (master) file5 add
* 0aa91caa5c0df5947982b199202c6495c8d0aa59 Add three files

 

버그를 해결하였으니 운영 branch인 master branch에 bug branch를 merge하여 해결한 버그 코드를 적용해야 한다. 해당 작업은 git merge 명렁어를 통해 master branch에서 bug branch 의 내용을 합쳐보자. 

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (bug)
$ git checkout master
Switched to branch 'master'

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master)
$ git merge bug
Updating f642194..20cd591
Fast-forward
 file1.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master)
$ git log --format=oneline --graph --all
* 20cd5917b3604a65a8c9a1d756a944e4513ce1a9 (HEAD -> master, bug) handle bug
| * 0309b6d2ddc15ff23aadffd055f52106fe11d493 (iss53) handle iss53
|/
* f6421947d66d855a74cec90d7631c680307ea31a file5 add
* 0aa91caa5c0df5947982b199202c6495c8d0aa59 Add three files

 

merge를 하였을 때, 메세지를 살펴보면 fast-forward라는 메세지를 볼 수 있다. 이 메세지의 의미는 무엇일까? 이 메세지의 의미는 위의 git log를 통해 확인한 커밋 히스토리를 확인해보면 이해할 수 있다.

 

커밋 히스토리를 들여다보면 master branch가 bug가 가리키는 커밋 개체를 같이 가리키고 있는 것을 확인할 수 있다. 이는 master branch가 bug와 합쳐지면서 새로운 커밋개체를 생성한 것이 아니라 merge 과정 없이 bug 가 가리키는 커밋 개체로 이동했다는 의미이다.

 

왜 이런 과정이 발생한 것일까? 그 이유로는 bug branch가 가리키는 커밋이 master branch가 가리키는 커밋의 이후에 위치하였기 때문이다. 즉, bug branch 생성 후 master branch는 여전히 그대로 있었기 때문에 master와 bug branch만을 놓고 커밋 히스토리를 보면 두 branch가 가리키는 커밋 개체가 동일 선상에 위치하고 있다.

 

그렇기 때문에, master branch에 버그를 해결한 코드가 들어간 상태를 현재 bug branch에서 가리키고 있는 것이기 때문에 master branch가 단순히 bug branch가 가리키는 커밋 개체로 이동만 하면 되는 것이다. 이러한 merge 방식을 fast-forward 방식이라고 하는 것이다.

 

이제 버그를 해결하였으니 bug branch는 삭제 후, iss53 branch로 이동하여 작업을 마저 하자.

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master)
$ git branch -d bug
Deleted branch bug (was 20cd591).

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master)
$ git checkout iss53
Switched to branch 'iss53'

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (iss53)
$ echo "last modified file5" > file5.txt

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (iss53)
$ git commit -am "finished issue 53"
[iss53 8621abe] finished issue 53
 1 file changed, 1 insertion(+), 1 deletion(-)

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (iss53)
$ git log --format=oneline --graph --all
* 8621abec8c7cbb1ef8bf16497fb9ed8c6f45f8bc (HEAD -> iss53) finished issue 53
* 0309b6d2ddc15ff23aadffd055f52106fe11d493 handle iss53
| * 20cd5917b3604a65a8c9a1d756a944e4513ce1a9 (master) handle bug
|/
* f6421947d66d855a74cec90d7631c680307ea31a file5 add
* 0aa91caa5c0df5947982b199202c6495c8d0aa59 Add three files

 

bug branch에서 작업한 내용은 iss53에는 영향을 끼치지 않는다는 점 또한 git branch의 주요 특징이다. 현재 상태에서 master branch를 iss53 branch에 merge 하면 iss53에 bug까지 해결된 코드가 합쳐진다. 또는 iss53 branch가 master에 merge 될 수 있을 때까지 기다렸다가 merge를 진행해야 한다. 

 

이번 예제에서는 iss53의 내용을 master에 merge할 수 있는 상태이기 때문에 merge를 진행하여 보자.

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (iss53)
$ git checkout master
Switched to branch 'master'

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master)
$ git merge iss53
Merge made by the 'ort' strategy.
 file5.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master)
$ git log --format=oneline --graph --all
*   ec6a6685ee40ed3081ebec88b9fb3fbb324363a0 (HEAD -> master) Merge branch 'iss53'
|\
| * 8621abec8c7cbb1ef8bf16497fb9ed8c6f45f8bc (iss53) finished issue 53
| * 0309b6d2ddc15ff23aadffd055f52106fe11d493 handle iss53
* | 20cd5917b3604a65a8c9a1d756a944e4513ce1a9 handle bug
|/
* f6421947d66d855a74cec90d7631c680307ea31a file5 add
* 0aa91caa5c0df5947982b199202c6495c8d0aa59 Add three files

 

iss53 branch는 master branch와 동일 선상에 있지 않기 때문에( 어떤 하나의 branch가 다른 branch의 조상이 아니기 때문에 ) 이전의 fast-forward 방식이 아닌 3-way merge방식으로 merge를 진행한다.

 

3-way merge 방식은 조상-자손 관계가 아닌 2 개의 branch를 merge하려고 할 때 사용하는 방법으로, 2개의 branch가 가리기고 있는 커밋 개체 2개와 2개 branch의 공통 조상 커밋 개체(base commit) 1개를 사용하여 merge 하는 방식으로 이 때 나온 결과물을 담는 새로운 커밋 개체를 생성하고 이를 Merge Commmit 이라고 부른다. ( 그렇기 때문에 merge 할 때, commit message를 입력하는 vim 이 동작한다. )

 

이후에 HEAD branch를 Merge 커밋 개체로 이동시킨다. 또한 이 Merge 커밋 개체는 위의 git log를 통해서도 알 수 있듯이 merge를 진행한 두 개의 branch가 가기키고 있던 커밋 개체에 해당하는 두개의 해시키를 갖게 된다.

 

위의 merge message에서 'ort' strategy는 git 이 3-way merge 방식을 사용할 때 base commit을 찾는 방식으로 이전의 사용하던 recusive strategy 방식을 보완한 방식이다. ( 이 정도로만 이해해도 충분!! )

 

마지막으로 이슈 해결을 위해 생성했던 iss53을 제거해주자.

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master)
$ git branch -d iss53
Deleted branch iss53 (was 8621abe).

 

 

 

 

 

 

 

reference : pro git

728x90

'기타 > Git' 카테고리의 다른 글

[Git] branch 관리  (1) 2024.01.09
[Git] Conflict 기초  (2) 2024.01.08
[Git] checkout  (1) 2024.01.03
[Git] branch 생성  (1) 2024.01.02
[Git] remote  (1) 2023.12.31