본문 바로가기

SCM/Git

15. Git 브랜치 합치기 - git merge

브랜치를 여러개 만들었을 때 다른 두 개의 소스를 병합해야 하는 경우가 생긴다.
 
이때 사용하는 명령이 git merge 이다.
 
 

git merge
 
아래 명령은 master 브랜치에 develop 에 있는 소스를 병합한다.
 
$ git checkout master
$ git merge develop
 
병합은 아래와 같은 상황이 있을 수 있다.
 
 

Fast forward Merge
 
현재 작업하는 프로젝트의 상태가 아래와 같을때
 
 
아래 명령중 하나로 브랜치를 하나 만들고  HEAD 포인터의 위치를 옮겨보자.
 
$ git branch iss53
$ git checkout iss53
$ git checkout -b iss53
 
 
여차 저차 해서 아래와 같은 상황이 되었을 때 
 
(현재 브랜치인 Master 가 가리키는 C2 가 Merge 할 브랜치 iss53 의 조상인 경우 )
 
 
아래 명령을 수행하면 Git 은 단순히 master 의 위치를 C3 로 옮기고 불필요한 iss53 은 삭제한다.
 
$ git checkout master
Switched to branch 'master'
$ git merge iss53
 
이게 Fast forward Merge 이다.
 
 
 

3-way Merge
 
만약 아래와 같은 상황으로 번졌다고 가정해 보자. 
 
 
이 경우도 같은 명령으로 merge 할 수 있다. 
 
$ git checkout master
Switched to branch 'master'
$ git merge iss53
 
다만 상황이 좀 다르다.
 
현재 브랜치인 master 가 가리키는 C4 가 merge 할 브랜치 iss53 의 조상 인 C3 가 아니므로
 
Git 은 각 브랜치가 가리키는 두개의 commit 두 개와 C4, C5 와 공통 조상인 C2 를 사용하여
 
3-way merge 를 한다.  
 
 
이는 단순히 브랜치 포인터를 최신 커밋으로 옮기는게 아니라 
 
3-way merge 의 결과를 별도의 커밋으로 만들고 해당 브랜치가 그 커밋을 가리키도록 이동시킨다.
 
 
 
CVS 나 Subversion 같은 버전 관리 시스템은 직접 공통 조상을 찾아서 Merge 해야 하는데
 
Git 은 Merge 하는데 필요한 최적의 공통 조상을 자동으로 찾는다. 
 
iss53 브랜치를 master 에 merge 하고 나면 iss53 브랜치가 더 필요 없으므로 다음 명령으로 브랜치를 삭제한다.
 
$ git branch -d iss53
 
 

3-way Merge 충돌
 
3-way merge 과정에서 각각의 브랜치에 있는 commit 이 같은 파일의 동일한 부분을 변경하는 경우 일어난다.
 
충돌이 일어나면 아래와 같이 자동으로 Merge 하는데 실패하였다고 나오고
 
 
git status 를 찍어보면 both modified 로 나오는 파일이 있다.
 
 
파일을 열어 충돌이 일어나 수정이 필요한 내용을 수정한 다음 다시 git add 하고 git commit 하면 수동 merge 가 완료된다.
 
 
이 상태에서 git log 로 확인해 보면 3-way merge 가 완료된 것을 확인할 수 있다.