Search

Git Merge 전략 정리

Created time
2022/02/22 07:34
Modified
2022/11/14 12:55
Tags
git

Git Flow 사용

보통은 공통으로 사용하는 master(main), development 를 메인 브랜치로 두고, 코드를 형상관리합니다.
메인 브랜치에서 새로운 브랜치를 만들어서 작업하고, 메인 브랜치에 코드를 merge하는 방식으로 진행합니다.
이 과정에서 코드를 반영하는 전략을 다르게 가져갈 필요가 있습니다.
이 이유에서 Merge 방식을 다르게 사용하게 됩니다.

Git Merge 전략

1.
Merge Commit
2.
Rebase and Merge
3.
Squash and Merge

1. Merge Commit

“작업 Commit들을 시간 순서대로 대상 브랜치에 Merge하고 Merge Commit을 남기는 방식”
flowchart LR
Before1{{Before Fast-Forward-Merge}}

masterS1(master) --> |new branch develop & commit| A1(A)
A1 --> |commit| B1(B)
B1 --> |commit| C1(C)
C1 --> |merge commit| masterE1(master)
masterS1(master) --- masterE1(master)

Before2{{Before 3-Way-Merge}}

masterS2(master) --> |new branch develop & commit| B2(B)
B2 --> |commit| C2(C)
C2 --> |merge commit| masterE2(master)
masterS2(master) --> |commit| A2(A)
A2 ----- masterE2(master)

After{{After Merge}}

masterS3(master) --> A3(A)
A3 --> B3(B)
B3 --> C3(C)
C3 --> mergeCommit(merge commit)
Mermaid
복사
Git Merge란? 기준이 되는 대상 checkout branch에 다른 branch의 코드를 병합하는 것 주로 사용하는 Git Merge 방식 1. Fast-Forward-Merge 2. 3-Way-Merge ...

Merge Commit 처리 과정

1.
“branch develop”를 “branch master”로 Merge한다.
git checkout master git merge develop
Bash
복사
2.
Merge 전략에 따라 충돌을 해결한다.
a.
“Fast-Forward-Merge”인 경우에는 문제 없이 코드가 병합된다.
b.
“3-Way-Merge”인 경우에는 코드 순서와 변경점이 섞여서 Merge Conflict가 발생할 여지가 있고, 발생한다면 해결하고 merge한다.

Merge Commit 특징

장점
병합된 브랜치가 삭제되어도, Commit History는 그대로 남아있어서 어떤 브랜치에서 작업이 merge가 되었는지 파악이 가능하다.
작업 Commit 말고도 Merge Commit이 이력으로 더 추가되어 병합 시점을 알기 쉽다.
단점
많은 사람들이 하나의 브랜치로 병합하게되면, 많은 Commit History가 뒤죽박죽 가독성을 떨어뜨린다.

2. Rebase and Merge

“한 브랜치에서 진행한 작업을 순서을 그대로 Rebase 대상이 되는 브랜치 최신 Commit을 다시 base로 해서 커밋 히스토리를 재조정하고, 브랜치를 Merge하는 방식
flowchart LR
Before{{Before}}

masterS1(master) --> |new branch develop & commit| A1(A)
A1 --> |commit| B1(B)
B1 --> |commit| C1(C)
C1 ----> |rebase and merge| masterE2(master)
masterS1(master) --> |commit| D1(D)
D1(D) --> |commit| E1(E)
E1(E) --- masterE2(master)

After{{After}}

masterS2(master) --> D2(D)
D2 --> E2(E)
E2 --> |rebase master & merge develop| A2(A)
A2 --> B2(B)
B2 --> C2(C)
Mermaid
복사
Rebase란? 공통 base(조상)를 가진 두 브랜치에서 하나의 브랜치의 base를 다른 브랜치의 최신 Commit을 base로 하게끔 재정렬 하는 것을 의미한다.

Rebase and Merge 처리 과정

1.
“branch develop”를 “branch master”로 Rebase한다.
$ git checkout develop $ git rebase master
Bash
복사
a.
“branch develop”로 체크아웃한다.
b.
“commit A”, “commit B”, “commit C”를 순서를 유지하고, 묶어서 “branch master”의 최신 “commit D”의 뒤에 재정렬된다.
c.
“branch develop”는 “branch master”에 Rebase되었지만, “branch master의 버전은 아직 “commit D”에 위치한다. 이 위치를 병합을 통해서 최신화시켜야한다.
2.
“branch master”를 “branch develop”로 Merge한다.
$ git checkout master $ git merge develop
Bash
복사
a.
“branch master”로 체크아웃한다.
b.
“branch master”을 “branch develop”로 Fast-Forward-Merge한다.
c.
Merge Commit 방식처럼 커밋이 생기지 않는다.

Rebase and Merge 특징

장점
작업 내용이 묶여다니기 때문에, Commit History를 단순화시킨다.
Rebase는 브랜치를 병합시, Merge Commit이 남지 않아서 하나의 브랜치에서 작업한 것처럼 보인다.
작업 Commit을 대상 브랜치에 그대로 병합시키기 때문에 Commit History를 보기 쉽다.
단점
Merge Commit이 남지 않기 때문에 브랜치 병합 시점을 알 수 없다.
병합 시점을 알기 어렵기 때문에 Tagging에 신경써야한다.
Merge할 브랜치의 Commit 내용이 많다면, Merge Conflict이 발생이 많아진다.

3. Squash and Merge

“여러 개 커밋을 하나의 커밋으로 합치고, 대상 브랜치에 하나의 커밋으로 병합하는 방식 ”
flowchart LR
Before{{Before}}

masterS1(master) --> |new branch develop & commit| A1(A)
A1 --> |commit| B1(B)
B1 --> |commit| C1(C)
C1 --> |squash and merge| masterE1(master)
masterS1(master) --- masterE1(master)

After{{After}}

masterS2(master) --> A2(A,B,C)
Mermaid
복사

Squash and Merge 처리 과정

1.
“branch master”에 “branch develop”의 모든 작업 Commit을 하나로 Squash Merge한다.
git checkout master git merge --squash develop
Bash
복사
a.
“branch master”를 체크아웃한다.
b.
“branch develop”의 작업 Commit을 병합한다.
2.
Squash Merge로 병합된 내용을 Commit한다.
git commit -m "squash merge"
Bash
복사
a.
병합된 작업 “branch develop”의 병합된 내용을 Commit한다.
3.
Squash Merge가 필요없는 커밋은 Rebase를 이용해서 직접 히스토리를 편집해야한다.

Squash and Merge 특징

장점
Merge commit이 남아서 쉽게 히스토리에서 알아볼 수 있다.
기능 단위로 브랜치를 만들어 전략적으로 활용할 수 있다.
단점
Merge Commit 하나만 남기 때문에 Commit History를 알 수가 없다.

Git Flow에서 Merge 전략 사용 예시

Merge: develop ← feature

일반적으로 Merge 후, 복잡한 Commit History가 필요없고, Feature Branch를 삭제하기 때문에 “Squash and Merge”

Merge: master ← develop

develop를 master에 추가할 때, 별도의 새로운 커밋이 필요없기에 “Rebase and Merge”

Merge: (master or develop) ← hotfix

Hotfix 커밋 히스토리가 모두 남아야 하는 경우 “Merge Commit”
Hotfix 커밋 히스토리가 필요 없는 경우, “Squash and Merge”

References