Git merge란?
git branch를 다른 branch로 합치는 과정을 merge라 한다. merge의 기본 단위는 브랜치이며, git merge 명령어로는 커밋 단위로 합치기가 불가능하다.
Fast Forward Merge
가장 기본적인 merge는 바로 Fast Forward Merge이다. Fast Forward Merge는 현재 브랜치의 HEAD가 대상 브랜치의 HEAD까지로 옮기는 merge이다. Fast Forward Merge는 다음 명령어를 통해 가능하다.
git switch [현재 브랜치]
git merge [대상 브랜치]
예를 들어 아래와 같은 git log가 있다고 해보자. feature-view branch의 HEAD는 third commit이며, main 브랜치의 HEAD는 second commit인 상황이다.
이를 그림으로 표현하면 다음과 같다.
Fast Forward Merge는 현재 브랜치의 commit을 대상 브랜치의 commit까지 옮기는 작업이다. 예를 들어 위의 main 브랜치의 HEAD를 feature-view branch의 HEAD까지 옮기고 싶다고 해보자. 이것을 하기 위해서는 다음의 과정을 거쳐야 한다.
1. git switch main을 이용해 main 브랜치로 전환한다.
2. git merge feature-view를 이용해 main 브랜치의 HEAD를 feature-view 브랜치의 HEAD로 옮긴다.
위 과정을 수행하면 main 브랜치의 HEAD가 feature-view 브랜치의 HEAD인 thrid branch로 옮겨진다.
Fast Forward Merge의 한계점
Fast Forward Merge는 중간에 변경이 없을 때만 동작한다. 만약 중간에 다른 커밋이 껴있고, 해당 커밋이 같은 부분을 수정했다면 컨플릭이 일어나 제대로 동작하지 않는다. 예를 들어 특정 파일(aa)을 동시에 수정한 main 브랜치의 fifth commit과 feature-layout branch의 fourth commit이 있을 경우 다음과 같은 애러 로그가 뜬다.
CONFLICT (content): Merge conflict in aa
Automatic merge failed; fix conflicts and then commit the result.
여러 명이 같이 작업을 하다 보면 이러한 상황이 매우 흔하다. 이런 경우 어떻게 처리해야 하는지 살펴보도록 하자.
Merge Commit 사용해 Merge Conflict 제어하기
그림6과 같이 fourth commit을 가진 feature-layout 브랜치를 fifth commit을 자닌 main 브랜치에 머지하는 상황을 가정해보자. 이때 만약 fourth commit과 fifth commit이 같은 부분을 수정했을 경우에는 main 브랜치와 feature-layout 브랜치 사이에 merge conflict가 생긴다.
merge 시 conflict가 생긴 파일은 git의 status가 both modified로 바뀐다. 이것을 해결하기 위해서는 conflict가 일어난 파일을 해결해야 한다.
만약 main 브랜치에서는 aa 파일을 "fifth commit"이라고 편집하고 feature-layout 브랜치에서는 aa 파일을 "fourth commit"이라고 편집했다면 다음과 같이 aa 파일이 변경된다.
위와 같은 형태를 처음 보면 조금 생소할 수 있지만 어려운 내용은 아니며 다음과 같이 이해하면 된다.
1. 먼저 맨 위의 '<<<<<<<< HEAD' 와 구분선 '=======' 사이의 값인 fifth commit은 현재 브랜치인 main 브랜치의 변경 사항이다.
2. 구분선인 '========='과 '>>>>>>>>> [feature-layout]' 사이의 값인 fourth commit은 머지 대상 브랜치인 feature-layout 브랜치의 변경 사항이다.
<<<<<<<<<<<<<< HEAD
[현재 브랜치의 변경 사항]
================== [구분선]
[머지 대상 브랜치의 변경 사항]
>>>>>>>>>>>>>> [대상 브랜치명]
위 컨플릭을 해결하기 위해서 우리는 <<<<<<<<와 =========와 >>>>>>>>>을 모두 제거한 후 선택해야 되는 변경사항을 반영해 다음과 같이 깨끗하게 만들면된다.
그 후 변경된 파일은 다시 add한 후 commit을 하면된다.
위의 사항이 반영되면 다음과 같이 변경된다.
이를 그림으로 표현하면 다음과 같다.