[TSL] git - Rebase vs Merge

intersoom·2024년 9월 7일
0

TSL

목록 보기
8/8
post-thumbnail

개요

지금까지 git을 사용하면서 브랜치를 합칠 때는 항상 merge를 사용해왔다.

그래서 git은 항상 내가 모르는 세계가 더 있다는 생각은 했지만, "나는 지금 알고 있는 것만으로도 잘 하고 있는데?" 라며 git에 대해서 더 공부해야겠다는 사실을 애써 무시해왔던 것 같다.

하지만 더 이상 물러날 곳이 없다.

회사에서 rebase를 사용하기 때문에 ! 드디어 rebase와 merge의 차이점에 대해서 공부해봤다.

브랜치란 무엇인가?

브랜치 병합 방법인, rebase와 merge에 대해서 알아보기 이전에 먼저 branch가 무엇이인지 알아보자.

브랜치커밋 사이를 가볍게 이동할 수 있는 일종의 포인터 같은 것이다.

그렇다면, 커밋은 어떤 것이기에 그것을 가리키는 것만으로 브랜치가 생성된다는 것일까?

Git의 파일 관리법

Git은 데이터를 Change Set이나 변경사항(Diff)으로 기록하지 않고 일련의 스냅샷으로 기록한다.

git에 commit 할 경우, 아래와 같은 commit Object가 형성된다.

  • 각 파일에 대한 Blob 3개 (노란색 🟨)
  • 파일과 디렉토리 구조가 들어 있는 트리 개체 (파란색 🟦)
  • 메타데이터, 루트 디렉토리 트리 개체를 가리키는 포인터 정보를 가지는 개체 (회색 ⬜️)

최초 commit 이 후에,
파일을 수정하고 commit을 할 경우, 이전 커밋이 무엇인지도 메타데이터와 함께 저장한다.

'HEAD’는 지금 작업하는 로컬 브랜치를 가리킨다.
현재 로컬의 브랜치가 master인 경우, master branch를 가리키고 있다.

$ git checkout testing

git checkout을 통해서 testing branch로 옮겨갈 경우,

이렇게 testing branch를 가리키게 된다.

Merge

fast-forward merge

<merge 전>

<merge 후>

hotfix branch가 가리키는 C4 commitC2 commit에 기반한 브랜치이다.

✅ 앞서 언급한 commit Object를 떠올리면, C4 commit Object 내부에 존재하는 이전 커밋에 대한 포인터가, C2 commit에 대한 포인터이기 때문에

그렇기 때무에 브랜치 포인터는 별도이 merge 과정 없이 그저 최신 커밋으로 이동한다.

이를 Fast forward merge 라고 부른다.

다시 말해, Fast forward merge

A branch에서 다른 B branch를 merge 할 때 B branchA branch 이후의 커밋을 가리키고 있으면, A branchB branch와 동일한 커밋을 가리키도록 이동 시키는 것이다.

3-way merge

Git은 각 브랜치가 가리키는 commit 2개와 공통 조상 1개를 사용하여 3-way Merge한다.

3-way Merge의 결과값을 새로운 commit인, C6 commit으로 만들고 현재 로컬이 가리키고 있는 branch가 해당 commit을 가리키게 만든다.

🤔 그러면 C6 commit의 이전 커밋(부모) 포인터는 어디를 가리키고 있는걸까?

정답은 둘 다이다. 이러한 commit을 merge commit이라고 부른다.
그래서 이러한 commit은 부모가 여러개이다.

Rebase

merge

merge는 마지막 commit 2개와 공통 조상 3개를 3-way-merge 하고 새로운 merge commit을 만들어내서 해당 commit을 현재 branch가 가리키게 했다.

rebase

rebase는 변경된 사항을 임시로 저장해두었다가 이를 C4 commit (rebase 주체의 가장 최신 commit)에 적용시키고 master branch를 C4' commit으로 fast-forward merge 한다.

Merge vs Rebase

rebase에서 C4' commit 내용은 merge의 C5 commit 내용과 같을 것이다.

그러면 둘의 차이점은 무엇일까?

그림으로 어느 정도 유추되었겠지만, Rebase는 깨끗한 히스토리를 만든다.

Rebase한 브랜치의 Log를 살펴보면 히스토리가 선형이다.
일을 병렬로 동시에 진행해도 Rebase 하고 나면 모든 작업이 차례대로 수행된 것처럼 보인다.

출처

https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-%EB%B8%8C%EB%9E%9C%EC%B9%98%EC%99%80-Merge-%EC%9D%98-%EA%B8%B0%EC%B4%88
https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-%EB%B8%8C%EB%9E%9C%EC%B9%98%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80
https://brunch.co.kr/@anonymdevoo/7

0개의 댓글