Git에서 branch merge 방법들과 각 방법의 특징 이해하기
Git에서 branch를 병합하는 방법들과 각 방법의 특징을 알아보자.
3-Way-merge
각 브랜치에 새로운 커밋이 있는 경우 두 브랜치의 커밋을 합쳐서 new commit을 생성하는 병합 방식
여기서 base의 커밋 , 현재 브랜치의 커밋 , 병합 대상 브랜치의 커밋들을 비교한다고 해서 3 way라고 한다.
실습해보기 (충돌이 일어날 경우)
main 브랜치에서 sum 함수를 추가한 내용인 "append sum" 라는 커밋을 생성했다.
function sum() {
return a+b
}
premium 브랜치를 생성하여 square 함수를 추가한 내용인 "append square" 라는 커밋을 생성했다.
function sum() {
return a+b
}
function square(a*b) {
return a*b
}
그런데 이제보니 처음 sum함수를 생성할 때 코드에 오류가 있다. main 브랜치로 가서 sum 함수를 고치고, fix sum이라는 새로운 커밋을 했다.
function sum(a,b) {
return a+b
}
main에서 premium을 병합한다. 이때 premium 브랜치의 sum함수와 main 브랜치의 sum 함수가 달라졌기에 충돌이 생긴다.
코드를 수정하여 merge commit 이름을 설정해준다.
function sum(a,b) {
return a+b;
}
function square(a,b) {
return a*b;
}
설정한 merge commit 이름으로 새로운 커밋이 생겨났다.
실습해보기 (충돌이 일어나지 않을 경우)
main 브랜치에서 minus 함수를 추가하는 append minus 커밋을 생성해주었다.
function sum(a,b) {
return a+b;
}
function minus(a,b) {
return a-b;
}
function square(a,b) {
return a*b;
}
그리고 append minus 커밋을 base로 하는 브랜치 premium를 생성하고, devide 함수를 만들어 append devide라는 커밋을 생성해주었다.
function sum(a,b) {
return a+b;
}
function minus(a,b){
return a-b;
}
function square(a,b) {
return a*b;
}
function devide(a,b){
return a/b;
}
다시 main 브랜치에서는 나머지를 구해주는 remain함수를 만들어서 append remain 커밋을 해줬다. (여기서 remain의 위치를 premium2 브랜치의 devide와 같은 위치에 넣어버리면 충돌이 나므로 주의 <- square함수 다음에 devide가 오는건지 remain이 오는건지 묻기 때문)
function sum(a,b) {
return a+b;
}
function minus(a,b) {
return a-b;
}
function remain(a,b) {
return a%b;
}
function square(a,b) {
return a*b;
}
이제 merge를 하면 충돌 없이 merge가 되고, 3-way-merge 이기에 새로운 커밋이 이름도 자동으로 설정되어 생성됐다.
지금까지가 3-way-merge이고, fast-forward-merge가 있는데, 위 과정에서 remain함수를 넣기전에 merge를 한다면 fast-forward-merge가 된다.아래에서 자세히 살펴보자.
Fast-Forward-Merge
기준 브랜치에는 새로운 커밋이 존재하지 않고, 커밋이 존재하는 다른 브랜치를 병합하는 경우
아래 사진을 볼 때, Base에서 하위 브랜치를 merge 했을 경우에 새로운 커밋이 생겨나지 않고, Head가 커밋 4로 이동한다.
번외로, Fast-Forward라도 강제로 3-Way 방식 처럼 새로운 커밋이 생기게할 수 있다.
git merge --no-ff feature
Rebase and Merge
base를 기준으로 뻗어나온 가지를 조정한다고 생각하면 되겠다. 하위브랜치로 뻗어나온 가지를 옮겨서 Fast-Forward를 적용하는 것이다. 조상을 바꾼다? 라고 나는 이해했다.
rebase를 쓰면 좋은 점은 프로젝트가 커질 때 3-way merge를 하는 것보다 훨씬 로그가 깔끔해진다. 하지만 충돌이 일어날 수 있다는 단점이 있다.
Squash and Merge
병합대상 브랜치의 커밋들을 하나로 합쳐서 기준 브랜치에 새로운 커밋으로 추가한다. 하나로 합친 이후 각 커밋들의 이력은 사라지기 때문에 커밋로그가 깔끔해진다. 이는 장점이자 단점이다. 3-Way-Merge를 하는데 커밋이력을 다 가져오지 않고 합쳐서 가져온다고 이해했다.
사용 방법
git merge --squash 대상 브랜치