본문 바로가기
코딩해보니/Git

[Git_36] 리베이스(rebase)로 커밋(commit) 수정하기 (ft.충돌)

by 위시랜 2023. 1. 26.

리베이스(rebase)로 커밋(commit) 수정하기
리베이스(rebase)로 커밋(commit) 수정하기

리베이스(rebase)로 커밋(commit) 수정하기

리베이스로 커밋 정보를 수정할 수 있습니다.

-i 옵션을 이용하는 것이며, 사용법은 다음과 같습니다.

# <브랜치 이름>의 HEAD 커밋으로 리베이스 하기
$ git rebase -i <수정을 시작할 커밋 아이디>

 

<수정을 시작할 커밋 아이디>HEAD 포인터를 활용합니다.

 

가령, 현재 커밋의 이전 커밋,

다시 말해 바로 앞의 커밋 정보를 수정하려면

$ git rebase -i HEAD~라고 입력하면 되겠습니다.

 

-i 옵션<수정을 시작할 커밋 아이디>부터 최근 커밋까지 묶어서 수정 처리할 수 있습니다.

가령, $ git rebase -i HEAD~2라고 하면 이전 커밋 2개를 한 번에 수정할 수 있습니다.

 

다음은 $ git rebase -i HEAD~2 를 실행한 후의 화면입니다.

$ git rebase -i HEAD~2 를 실행한 후의 화면
$ git rebase -i HEAD~2 를 실행한 후의 화면

 

맨 상단 두줄에 pick 으로 시작하는 부분을 볼 수 있을 텐데요.

이전 2개의 커밋을 여기서 어떻게 수정할 것인지 명령어를 사용해 편집하게 됩니다.

pick acd05cf master commit 7이라고 되어 있는데,

이대로 그냥 저장하고 편집기를 종료하면 커밋 정보는 아무런 수정이 일어나지 않습니다.

 

pick 자리가 수정할 명령어 자리입니다.

[명령어] [커밋아이디] [커밋메시지]형식으로 작성하게 됩니다.

 

아래에는 어떤 명령어들을 사용할 수 있는지, 각 명령어에 대한 설명이 나와 있습니다.

명령어 몇 개만 설명하겠습니다.

 

pick

커밋을 사용하겠다는 의미로,

기본적으로 pick으로 설정되어 있으며,

이를 이용해 커밋의 순서를 바꿀 수 있습니다.

위 화면에서 두 개의 커밋 순서를 바꾼다면,

커밋 순서와 커밋 해시 값까지 변경됩니다.

 

reword

커밋 메시지를 변경하는 명령어로,

커밋 메시지를 변경할 커밋 앞에 reword 명령으로 수정하고,

저장하면 해당 커밋의 메시지를 다시 작성하는 편집기 창이 열리게 됩니다.

커밋 메시지와 커밋의 해시값 또한 변경됩니다.

 

edit

커밋 메시지뿐만 아니라 커밋의 작업 내용까지 변경할 수 있습니다.

작업 내용까지 변경할 수 있기 때문에

edit 사용하면 변경할 커밋으로 체크아웃되고,

그 상태에서 변경 작업을 수행하면 됩니다.

변경 작업을 완료하고 변경 사항을 저장하기 위해서는

다음의 명령들을 수행해야 합니다.

# 스테이지에 올림.
$ git add . 

# 변경할 커밋 메시지 입력
$ git commit --amend -m “커밋메시지” 

# 리베이스 진행
$ git rebase --continue

 

squash

해당 커밋을 이전 커밋과 합치는 명령어입니다.

커밋 메시지까지 확인해 가며 수정할 수 있습니다.

$ git rebase -i HEAD~3을 실행해 보겠습니다.

$ git rebase -i HEAD~3 실행
$ git rebase -i HEAD~3 실행

실행 후 수정할 수 있는 편집 화면이 실행됩니다.

$ git rebase -i HEAD~3 실행 후 편집 화면
$ git rebase -i HEAD~3 실행 후 편집 화면

커밋 정보 3개가 불러져 있습니다.

 

여기서 “hotfix commit 6”을 “master commit 6”과 합치기 위해 다음과 같이 편집합니다.

squash 명령으로 수정
squash 명령으로 수정

저장하고 편집기를 종료하면,

다음과 같이 커밋 메시지 입력 편집기가 다시 실행됩니다.

커밋 메시지 입력하기 위한 편집기 실행 화면
커밋 메시지 입력하기 위한 편집기 실행 화면

그대로 저장하고 종료해 보겠습니다.

$ git rebase -i HEAD~3 실행 후 최종 결과 화면
$ git rebase -i HEAD~3 실행 후 최종 결과 화면

위 화면과 같이 변경되었다는 메시지를 확인할 수 있습니다.

 

소스트리로 확인한 전/후 결과입니다.

[합치기 전] hotfix commit 6과 master commit 6 커밋을 합치기 전입니다.

소스트리(Sourcetree)에서 확인한 커밋 이력
소스트리(Sourcetree)에서 확인한 커밋 이력

 

[합치기 후] hotfix commit 6이 없어지고,

master commit 6으로 합쳐진 것을 확인할 수 있습니다.

소스트리(Sourcetree)에서 확인한 커밋 이력
소스트리(Sourcetree)에서 확인한 커밋 이력

 

fixup

squash와 마찬가지로 해당 커밋을 이전 커밋과 합치는 명령어이지만,

커밋 메시지는 이전 커밋의 메시지를 남기게 됩니다.

 

drop

커밋 히스토리에서 커밋을 삭제합니다.

 

이렇듯 리베이스 명령어는 커밋을 수정할 수 있기 때문에 항상 주의가 각별히 필요한 명령어입니다.


리베이스(rebase) 충돌(Conflict)

리베이스 명령도 병합(merge)과 마찬가지로 충돌이 발생할 수 있습니다.

리베이스 실행 중에 충돌이 발생하면

병합 시 충돌을 해결할 때와 마찬가지로 충돌이 발생한 코드를 수정합니다.

 

수정한 후에는 $ git rebase --continue 명령으로

실행하던 리베이스를 진행시켜 완료해야 합니다.

병합(merge)과 리베이스(rebase)는 협업을 하는

구성원들 간의 상호 협의에 따라 규칙을 정하는 것이 좋습니다.

 

병합과 리베이스는 적절하게 잘 사용하면 Git관리에 많은 도움이 됩니다.
리베이스를 전혀 사용하지 않고 병합만을 허용한다면,

커밋 이력이 매우 복잡해져서 커밋을 추적하기에 매우 어려운 상황이 올 수 있습니다.

 

반면에 리베이스를 남용하면 커밋 이력을 찾을 수 없어

누가 어떤 이유로 어떻게 커밋을 했는지 알 수 없게 되어

문제를 해결함에 어려움이 올 수 있습니다.

 

불필요한 병합 커밋을 선호하지 않고

선형으로 히스토리를 깔끔하게 유지해 가는 것이 중요할 경우에는

병합보다는 리베이스를 시의적절하게 수행하는 규칙을 정해 가야 합니다.


반면에, 저처럼 프로젝트의 전반적인 기록을

투명하게 남겨두는 것이 중요하다고 생각할 경우에는

병합을 우선해 가는 방향으로 규칙을 정하는 것이 좋겠습니다.

 

그래서 저는 리베이스는 자신의 PC에서 혼자 작업할 때,

커밋과 브랜치를 정리하는 차원에서 사용할 수는 있습니다.

 

하지만 원격 저장소만큼은 작업 히스토리가

투명하게 남겨둬야 전/후 누군가 작업을 함에 있어 반드시 필요하다고 생각합니다.


여기까지 리베이스(rebase)에 대해 중요한 부분들을 살펴봤습니다.

 

감사합니다.

댓글