git merge - fast-forward (--no-ff, --ff)
git은 다른 형상 관리툴과 달리 branch를 생성할 때 파일을 복사하는 것이 아니라 파일의 스냅샷만 가지고 생성하기 때문에 자원의 부담없이 branch 를 만들어 사용할 수 있다.
이러한 장점 때문에 git 으로 작업을 할 때에는 다양한 용도의 branch를 만들어 사용하는데, git 에서 한 브랜치에서 다른 브랜치로 합치는 방법으론 크게 두 가지가 있다. 하나는 Merge 이고 다른 하나는 Rebase 이다.
협업을 통해 개발하기 위해서는 두 병합 방법에 대한 사용법과 차이점을 알고 있는 것이 매우 도움이 될 것이다.
Merge
Merge 는 우리가 알고 있는 일반적인 브랜치 병합 전략이다. Merge 의 장점은 Merge 한 브랜치가 삭제되어 사라졌다고 해도 히스토리 그래프 상에서는 그대로 표기 되기 때문에 “어떤 브랜치에서 어떤 커밋이 진행되어 어떻게 머지 되었는지에 대한 자세한 정보”를 얻을 수있다.
1. fast-forward
fast-forward 방법은, branch 간의 병합을 진행할 때 커밋이 생기지 않고 merge 명령어를 실행하는 브랜치의 Head Commit 이 병합되어 지는 브랜츼의 Head Commit 으로 이동되는 방식이다.
쉽게말해, Base 브랜치의 내용이 변경되지 않았을 때 사용된다.
위에 그림을 보면, feature 브랜치를 생성하고 작업이 끝난 다음 master에 merge 를 진행할 때까지, master 에 어떠한 변경도 없다. 이때 fast-forward merge 를 하게 되면 merge-commit 이력은 남지 않게 되고 원래 master 브랜치에서 작업을 한것 마냥 master 브랜치의 Head commit 이 feature 브랜치의 Head Commit 으로 이동하게 된다. (master: A → B → X → Y, 이력상 하나의 커밋 그래프가 그려진다)
1
git merge -ff [병합하고자 하는 브랜치명]
2. 3-way merge
앞서 base 브랜치에 작업된 커밋이 이력이 없는 경우에는 fast-forward merge 를 통해 merge commit 을 남기지 않고 깔금하게 브랜치 병합을 할 수 있었다. 하지만 개발하는 와중에 협업을 하게 되면 다른 동료가 master 같은 base 브랜치에 작업내용을 반영하여 commit 이력이 생기는 경우가 발생 할 수 있다. 이럴땐 fast-forward merge 를 진행할 수 없다.
이때 merge 브랜치에서 사용하는 전략은 병합하고자 하는 각 두 브랜치의 커밋과 base가 되는 브랜치의 커밋을 동시에 비교하여 병합하는 3-way merge 이다.
위 브랜치 그림을 보면 master 의 마지막 커밋은 C, feature 브랜치의 마지막 커밋은 Y 이다. 그리고 두 브랜치의 base가 되는 커밋은 B가 된다. 이 3가지의 3커밋을 비교하여 이를 통해 새로운 merge commit 을 생성해 병합하는 것이다.
1
2
3
4
5
6
7
8
9
10
11
12
git checkout feature/hdo/ff_1
git merge --no-ff feature/hdo/ff_2
git log --all --oneline --graph
* 1a44721ce (HEAD -> feature/hdo/ff_1) Merge branch 'feature/hdo/ff_2' into feature/hdo/ff_1
|\
| * 331c05455 (origin/feature/hdo/ff_2, feature/hdo/ff_2) fast-forward commit - 3
| * 391b00d37 fast-forward commit - 2
* | a241c90c7 (origin/feature/hdo/ff_1) fast-forward commit - 4
|/
* 9fcbb01ff fast-forward commit - 1
위 결과를 살펴보면 master 브랜치(feature/hdo/ff_1) 와 feature 브랜치(feature/hdo/ff_2) 의 변경이력이 합쳐지는 방식으로 최종 Merge commit 이 생성된다.