CI\CD/Git

[Git] git merge 한 번에 정리하기 : Fast Forward Merge, Commit Merge, Conflict Merge

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인 상황이다.

 

그림1. Fast Forward Merge

 

이를 그림으로 표현하면 다음과 같다.

 

그림2. Fast Forward Merge

 

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로 옮긴다.

 

그림3. Fast Forward Merge

 

위 과정을 수행하면 main 브랜치의 HEAD가 feature-view 브랜치의 HEAD인 thrid branch로 옮겨진다.

 

그림4. merge

 

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.

 

그림5. Conflict

 

여러 명이 같이 작업을 하다 보면 이러한 상황이 매우 흔하다. 이런 경우 어떻게 처리해야 하는지 살펴보도록 하자.

 

 

 

Merge Commit 사용해 Merge Conflict 제어하기

 

그림6. 머지 요청과  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가 일어난 파일을 해결해야 한다. 

 

그림6. conflict 시의 git status

 

만약 main 브랜치에서는 aa 파일을 "fifth commit"이라고 편집하고 feature-layout 브랜치에서는 aa 파일을 "fourth commit"이라고 편집했다면 다음과 같이 aa 파일이 변경된다.

 

그림7. conflict가 일어난 파일 aa

위와 같은 형태를 처음 보면 조금 생소할 수 있지만 어려운 내용은 아니며 다음과 같이 이해하면 된다.

1. 먼저 맨 위의 '<<<<<<<< HEAD' 와 구분선 '=======' 사이의 값인 fifth commit은 현재 브랜치인 main 브랜치의 변경 사항이다.

2. 구분선인 '========='과 '>>>>>>>>> [feature-layout]' 사이의 값인 fourth commit은 머지 대상 브랜치인 feature-layout 브랜치의 변경 사항이다.

 

<<<<<<<<<<<<<< HEAD
[현재 브랜치의 변경 사항]
================== [구분선]
[머지 대상 브랜치의 변경 사항]
>>>>>>>>>>>>>> [대상 브랜치명]

 

위 컨플릭을 해결하기 위해서 우리는 <<<<<<<<와  =========와 >>>>>>>>>을 모두 제거한 후 선택해야 되는 변경사항을 반영해 다음과 같이 깨끗하게 만들면된다.

 

그림8. merge conflict 해결

 

그 후 변경된 파일은 다시 add한 후 commit을 하면된다.

 

그림9. merge commit

 

위의 사항이 반영되면 다음과 같이 변경된다. 

 

그림10. 머지 커밋

 

이를 그림으로 표현하면 다음과 같다.

 

그림11. 머지 커밋 시각화

반응형

 

이 글의 저작권은 '조세영의 Kotlin World' 에 있습니다. 글, 이미지 무단 재배포 및 변경을 금지합니다.

 

 

Kotlin, Android, Spring 사용자 오픈 카톡

오셔서 궁금한 점을 질문해보세요!
비밀번호 : kotlin22

open.kakao.com