프로젝트 팀이 바뀌면서, 새로운 팀에 적응하는 중이다.
팀에서 Merge가 아닌 Rebase를 사용한다고 해서, Rebase와 Merge의 간단한 개념과 동작 방식, 차이점에 대해서 정리해보았다.
찾아보다가 다시 개념을 정리하게 된 Git 기본 용어들도 있어서, 이것들도 정리해봤다.
Git
용어들HEAD
현재 작업중인 커밋. 즉, 현재 체크아웃된 커밋.
HEAD
는 항상 작업 트리의 가장 최근 커밋을 가리킨다.
작업 트리의 변화를 주는 git 명령어(ex. git checkout
, git commit
)들은 대부분 HEAD를 변경하는 것으로 시작한다.
HEAD
는 branch의 이름을 가리키고 있다.
commit을 하면, branch의 상태가 바뀌고, 이 변경은 HEAD를 통해서 확인이 가능하다.
Commit Tree
git commit을 했을 때 생성되는 Commit Object로 이루어진 트리
BASE
feature branch의 입장에서 master branch와 feature branch가 공통으로 갖는 커밋 (feature branch들의 공통 조상이 되는 master branch 커밋)
참고) 그래서 rebase는 다음과 같이 정의할 수 있다
이제 merge와 rebase에 대해 알아보자..
merge
merge 는 '병합한다'는 뜻이다.
즉, 어떤 기능을 하는 branch에서 작업한 내용들을 master처럼 root가 되는 branch에 적용할 때, '병합한다' 또는 'merge한다'고 표현한다.
merge 를 하는 방법에는 2 way merge
와 3 way merge
라는 두 가지 방식으로 나뉜다.
2개의 branch의 각 최신 커밋을 비교하여, 같은 부분(아래 그림에서의
1
)만 병합하고 나머지 다른 부분들(아래 그림에서의M2와 2
,3과 E3
,M4와 E4
)은 충돌을 발생시켜 사람이 직접 해결하는 병합 방식.
2 way merge
방법은 기준이 되는 BASE
가 없이 두 브랜치 간의 다른 부분들은 모두 충돌을 일으키기 때문에 conflict가 많이 발생한다. (사람이 직접 수정해야 하는 부분이 많아짐)
위 사진을 예로 들면, 1 M2 3 M4
커밋과 1 2 E3 E4
커밋의 변동 사항을 제외하고 변동되지 않은 부분은 1
밖에 없다.
따라서 1
만 자동 병합되고, 나머지는 모두 충돌이 나서 직접 사람이 해결해줘야 한다.
2개의 branch의 각 최신 커밋과, 이들을 공통조상(=
BASE
)으로 갖는 새로운 커밋을 만들어, 이 3가지를 비교해 충돌나지 않는 변경사항(아래 그림의1
,M2
,E3
)은 자동 병합하고, 나머지 충돌나는 변경사항들(M4와 E4
)만 충돌을 발생시켜 사람이 직접 해결하는 병합 방식.
즉, feature branch에서 master branch로 3 way merge
할 때 비교 대상이 되는 3가지는 다음과 같다.
BASE
)
3 way merge
방법은 BASE
가 있어서 충돌이 많이 일어나지 않는다.
보통 다음과 같이 git merge
명령어로 병합했을 경우, 2 way merge
가 아닌, 3 way merge
방식으로 병합된다.
git checkout feature, git merge master
Rebase
아까 base
를 feature branch의 입장에서 master branch와 feature branch가 공통으로 갖는 공통 조상 커밋이라고 했다.
그래서 rebase는 다음과 같이 정의할 수 있다고도 했다.
rebase = base를 바꾼다 = feature 브랜치들의 공통 조상을 바꾼다
위와 같은 방법으로 두 브랜치를 병합하는 방법이 rebase이다.
위 그림을 보면, rebase 하기 전에는 feature branch의 base
가 A
이다.
git checkout feature, git rebase master
그러나 위와 같은 git rebase
명령을 통해 rebase 작업을 한 후에는,
feature branch의 base
가 master branch의 마지막 커밋인 C
가 된다.
rebase는 위 그림처럼 commit history가 일렬로 나열되어 보기가 쉽다는 장점이 있다.
그러나 merge보다 비교적 작업하기 어렵고 위험하다.
💡 [참고] rebase 작업 과정
1. 두 브랜치가 나뉘기 전인 공통 커밋으로 이동한다.
2. 그 커밋부터 지금 Checkout 한 브랜치가 가리키는 커밋까지 diff를 차례로 만들어 어딘가 임시로 저장한다.
3. Rebase할 브랜치(=feature), 합칠 branch(=master)가 가리키는 커밋을 가리키게 하고, 아까 저장해놓았던 변경사항을 차례대로 적용한다.
Merge
와 Rebase
비교Git에서 한 브랜치를 다른 브랜치에 합치는 방법에는 merge와 rebase가 있다.
merge와 rebase는 실행 결과는 동일하지만, commit history가 달라진다.
- merge의 특징
- 비교적 쉽고 안전하다. (conflict 해결이 쉽다)
- commit history가 병렬로 나열되어 지저분하고 보기가 어렵다.
- rebase의 특징
- 어렵고 위험하다. (왜?)
- commit history가 일렬로 나열되어 보기 쉽다.