ice rabbit programming

[Git] merge vs rebase(feat. squash) 본문

Development/Git

[Git] merge vs rebase(feat. squash)

판교토끼 2020. 9. 20. 23:52

rebase란?

rebase의 개념은 간단하게 설명하자면, 커밋의 줄기를 다른 곳에 붙인다고 생각하면 된다. merge와도 유사한 개념인데, 차이점은 새 커밋을 만드느냐(merge), 만들지 않느냐(rebase)의 차이이다. 물론 둘 모두 conflict는 자동 병합이 되지 않기 때문에 수동으로 해결해 주어야 한다.

예를 들어, 커밋 줄기가 아래와 같다고 생각해보자. feature 브랜치와 master 브랜치의 개념에 대해서 알고 싶다면 예전 글을 읽고 오면 좋다.

master branch과 그에서 파생된 feature 브랜치

기본적으로 합칠 때에는 PR을 한 후에 feature에서 master로 merge할 것이다. 그러면 흐름은 아래처럼 그려진다.

git checkout feature
git merge master

feature 브랜치가 master에 merge되었다.

즉, master branch에서 새 commit을 하나 만들고, 그곳에 feature 브랜치를 merge하였다. merge 방식의 병합은 비파괴적인 병합이기 때문에 합친 이후에도 해당 브랜치들이 남아 있어 추후에 찾아보기 좀 더 쉽다는 점이 있다.

반면에 rebase를 하면 다음과 같다.

git checkout feature
git rebase master

feature에 있던 커밋 히스토리들이 master branch로 들어갔다(rebase되었다).

즉, feature에 생겼던 변경점들이 master로 들어가게 된 것이다. 이는 merge라는 커밋이 아니라 실제로 코드가 변경한 부분만을 커밋으로 남겨 좀 더 명확하게 히스토리를 관리할 수 있다. 다만 여기서 예시는 master branch로 들었지만 제대로 협의되지 않은 상황에서 반대로 master 브랜치를 feature 브랜치로 rebase하는 경우에는 형상 관리가 꼬일 수 있으므로 협업자들 간의 커뮤니케이션이 꼭 필요하다.

커밋 합치기(squash)

squash는 다수의 커밋을 합치는 작업이다. 정확히는 squash라는 명령어는 없고, rebase를 이용해서 squash를 한다. 그림으로 설명하면, 아래와 같다. 그림을 좀 엉성하게 그리긴 했다만 파란 커밋 2개가 하나가 되었다는 도식이다.

마지막 커밋을 직전 커밋에 squash하였다.

이러한 기능은 JIRA와 함께 사용할 때 1티켓당 1커밋이라는 룰이 있거나, 오타 수정 등 자잘한 commit을 따로 남기고 싶지 않을 때 유용하게 사용할 수 있다.

git rebase -i HEAD~3

위 명령어를 입력하면 vim이나 VS Code 등 본인이 설정한 git의 기본 IDE로 들어가게 된다. 첫 번째로 들어가게 되는 파일에서 squash할 커밋을 고르면 된다.

저장 후에 창을 닫아주면 다음 파일이 나오는데, 이번에는 commit message를 건드려주면 된다. 냅두면 있었던 커밋 메세지들이 그대로 남게 되는데, 필자는 정리해서 바꾸어주는 편이다.

커밋 메시지까지 수정, 저장 후 닫아주면 성공적으로 rebase가 되었다고 나온다. 그러면 commit이 성공적으로 합쳐진 것이다. 단, 주의할 점은 이미 push가 된 commit을 rebase하면 conflict 해결이 골치가 좀 아프다. 웬만하면 push하지 않은 commit의 squash를 추천하며, 만약 필요할 경우에는 강제로 해 주면 push가 들어가게 된다.

git push -f