본문 바로가기

GIT

git rebase

브랜치를 merge하는 한 종류

 

- 일반적인 merge 명령어를 사용하면 commit history가 복잡해지지만 rebase를 사용하면 commit history가 한 줄로 정렬된다. rebase를 진행하면 커밋해시가 변경된다. 커밋해시가 변경되면 같은 커밋 메시지를 갖고 있고, 같은 파일을 수정했다고 하더라도 git은 서로 다른 커밋으로 이해한다.

  그렇기 때문에 베이스를 새로 지정한다고 생각하면 된다.

 

 

- interactive rebase

인터렉티브 리베이스에는 여러 가지 옵션들이 있지만 squash만 설명한다.

squash: commit history를 합쳐서 하나의 commit으로 만든다.

ex)

commit history1

commit history2

commit history3

을 squash하면

new commit1, combination of 3 commits

가 된다.

 

commit history1

commit history2, combination of 2 commits

commit history3, combination of 3 commits

commit history4, combination of 4 commits

와 같이 이미 squash가 진행된 커밋 히스토리를 squash 하게 되면

new commit, combination of 10 commits

가 된다.

 

복잡한 commit history를 하나로 정리할 수는 있지만 협업을 할 때 squash를 하게 되면 누가 파일을 수정했는지는 확인할 수 없게 된다.


스쿼시 후에 다른 개발자가 리셋을 받지 않고 커밋 후 푸쉬를 하면 커밋 히스토리가 꼬이게 된다.

그 이유를 살펴보자.

스쿼시는 여러 개의 커밋을 하나의 커밋으로 녹이는 옵션이다. 하지만 단순히 여러 커밋을 하나로 만드는 것이 아니다. 스쿼시는 여러 개의 커밋을 각각 3 way merge를 통해 하나의 커밋으로 머지하는 것이다.

terminal에서 스쿼시가 진행되는 과정을 살펴보면 1/7 → 2/7 → ... → 7/7 이런 식으로 숫자가 올라가는 것을 확인할 수 있다. 먼저 첫 번째 커밋과 두 번째 커밋을 merge 해서 하나의 커밋으로 녹이고, 그 커밋과 세 번째 커밋을 merge 해서 하나의 커밋으로 녹이는 방법을 반복하는 것이다. 이렇게 되면 스쿼시 중 충돌이 발생하는 이유가 앞의 글에서 설명한 충돌 발생 원인과 동일하다는 것을 알 수 있다.

앞선 글에서 merge에서 중요한 것은 베이스가 되는 커밋이라고 설명했고, 리베이스를 진행하면 커밋 해시가 변경된다는 것도 설명했다.

스쿼시 후 리셋을 받지 않고 머지를 하게 되면 내용은 같지만 커밋해시가 다른 커밋이 베이스가 된다. 그러면 깃은 그 커밋을 베이스로 인식하지 못하고 밑으로 내려가면서 베이스가 될 새로운 커밋을 찾는다. 이 과정에서 새로운 베이스부터 스쿼시가 된 커밋 사이에 있는 커밋들이 다시 살아나 깃 그래프상에서 보이게 되고, 이 과정에서 커밋 히스토리가 꼬이게 된다.

728x90

'GIT' 카테고리의 다른 글

git reflog  (1) 2023.10.24
git merge  (0) 2023.08.30
초기 설정 + 기초 명령어  (0) 2023.08.24
GIT? + 용어 + 설치  (0) 2023.08.24