Git Merge vs Rebase 체험기

berry·2023년 11월 1일
0

문제 상황

아래 처럼 remote/main 브랜치에 새로운 commit 이 push 된 상태이다.
이 상태에서 local/main 브랜치에서는 remote 의 변경 사항을 받아오지 않고 새로운 commit 을 해버렸다.

이때 깃 로그를 한번 봐보자.
local/main 브랜치, remote/main 브랜치 각각에 commit 이 생겨있다.

이를 도식화해보면 다음과 같다.

이 상태에서 remote 브랜치에 local 변경 사항을 push 하려고 하면 다음과 같은 오류가 발생한다.
remote 의 변경 사항을 먼저 local 에 반영한 다음에 push 를 해야 한다는 것이다.

그럼 여기서 merge 와 rebase 의 차이는 뭘까?
직접 해보자!

merge 사용하기

터미널 명령어

git config pull.rebase false
git pull origin main

remote/main 브랜치를 local/main 브랜치에 merge 를 하면 깃 이력이 다음과 같이 바뀐다.

push 를 할 때 local 커밋과 merge 커밋 두 개의 커밋이 푸쉬된다.

도식화하면 다음과 같다.

만약 ide 가 아닌 명령어를 사용해서 merge 를 한다면, conflict 를 해결하고 생기는 commit message 에 fix: resolve merge conflict 이런 메시지를 써주면 된다.

rebase 사용하기

터미널 명령어

git config pull.rebase true
git pull origin main

이 상황에서 이번엔 rebase 를 사용해보자

rebase 를 사용하면 다음과 같이 커밋 이력이 남는다.
여기서 주의할 점은 local commit 의 id 가 변경되었다는 점이다.

그리고 이를 도식화하면 다음과 같다.
rebase 를 실행하면 선형적으로 커밋이 쌓이는 것을 볼 수 있다.

주의할 점은 재정렬되는 commit 이력이기 때문에, 재정렬되는 commit 이력에는 이전과는 다른 새로운 해쉬 ID가 부여된다.

만약 ide 가 아닌 명령어를 사용해서 rebase 를 한다면, conflict 를 해결하고 생기는 commit message 에 rebase 된 커밋의 메시지 를 써주면 된다.
여기서는 docs: first local commit 가 될 것이다.


위의 문제 상황에서 pull 을 받으려고 할 때 안되는 이유?!

만약 처음 문제 상황에서 git pull 을 받으려고 하면 다음과 같은 이유로 pull 이 거부된다.

우리가 사용하는 pull 명령어는 기본적으로 fast forward 형식을 사용한다.

✅ git pull --ff-only
pull 하려는 원격저장소의 브랜치와 로컬저장소의 브랜치가 fast-forward 관계일 때만 pull을 허용한다.

두 브랜치가 fast-forward 관계라는 건 둘 중 하나를 의미한다.

두 브랜치가 갈라진 commit을 기준으로

로컬저장소에만 새로운 commit이 있고, 원격저장소에는 없다.
원격저장소에만 새로운 commit이 있고, 로컬저장소에는 없다.

첫번째 경우는 pull을 받아올 필요가 없으므로 두 번째의 경우에만 pull이 가능하다는 뜻이 된다.
그럼 만약 원격저장소의 새로운 commit이 존재하는데 git pull을 하지 않은 상태에서 로컬저장소에 새로운 commit을 했다면, git은 pull을 허용하지 않을 것이다.

✅ git pull --rebase
pull 시에 rebase를 사용하면 아래와 같이 동작한다.

rebase란? 새 브랜치가 시작된 분기점 commit이 존재한다. 이 분기점을 기준 브랜치의 가장 최근 commit으로 변경하는 작업.

로컬 브랜치의 시작점을 원격 브랜치의 마지막 commit으로 옮기는 식인 것 같다. 그 과정에서 conflict가 발생할 경우 이를 해결해줘야 할 듯 싶다.
git history가 깔끔해진다는 장점이 있지만, 부주의하게 사용할 경우 별도의 알림 없이 git history를 영구적으로 변경할 수 있기 때문에 ff-only 방식을 더 추천한다고 한다.


참고

https://velog.io/@eunddodi/git-pull-%EC%8B%9C-%EB%B0%9C%EC%83%9D%ED%95%98%EB%8A%94-warning-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0Need-to-specify-how-to-reconcile-divergent-branches

profile
공부 내용 기록

0개의 댓글