git rebase 를 이용해 중간 커밋 수정하기

삽질 기록 2018. 7. 25. 21:54 Posted by 아는 개발자

최상위 커밋은 git commit --amend로 수정이 가능한데 중간에 있는 커밋은 수정하기가 참 난감하다. 가장 간단하면서 무식한 방법은 git format-patch로 수정하려는 커밋 전까지 패치 파일을 만들어둔 후 reset으로 수정하려는 커밋까지 쌓인 커밋들을 모두 지운 뒤 git commit --amend로 수정한 다음, reset 하기 전에 패치로 만들어둔 커밋을 다시 적용하는 방법이 있다. 이 방법은 매우 번거롭고 복잡하며 이미 Pull Request가 진행중인 브랜치에서는 적용할 수 없다는 문제가 있다.


이런 경우에는 git rebase의 interactive 옵션을 이용하면 Pull Request가 진행중인 브랜치의 중간 커밋을 수정 할 수 있다. 사용 방법은 간단하다.



위 그림에서 맨 아래 "appear action bar and use customized one in user activity"라는 커밋만 수정해보고 싶다고 해보자. 그러면 내가 수정하려는 커밋의 번호를 복사한 후 command에 아래와 같이 입력하자


// git rebase -i {커밋 id}^
git rebase -i 1372d858b7d84708f54da356035cec35a4375f07^


실행하고 나면 nano 에디터가 열리면서 아래와 같은 메시지가 나온다.


pick 1372d85 appear actionbar and use customized one in user activity
pick 0ba4172 cut side space in actionbar
pick 64d006d Fix bug: Change error message on dialog user name input
pick 5be8b91 Replace textview to imageview in sliding tab layout
pick c6d7a5e Add postfix string in actionbar title to show detailed information
pick 624baa3 upgrade version to 1.20

# Rebase 382448a..624baa3 onto 382448a (6 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit


메시지에는 수정하려는 커밋부터 최신 커밋까지 "명령" "커밋 번호" "커밋 메시지"의 형태로 쭉 나열 돼어 있다. 현재 상태는 어떤 커밋에 무슨 작업을 할 것인지 설정 할 수 있는 단계다. 아래 Commands의 설명이 나와 있는 것 처럼 'pick'은 commit을 그대로 사용하는 것이고 'edit'은 커밋을 사용하면서 수정하기 위해 멈춘다는 뜻이다. 기본으로는 모두 변경하지 않음인 'pick' 설정이 돼있다.


개발자는 "명령"에 해당하는 문자열 값을 바꿔서 해당 커밋에서 원하는 작업을 수행 할 수 있다.  우리는 가장 처음에 있는 커밋(1372d85)을 수정해야하니 이 문장에 pick을 edit으로 변경하고 빠져나오자. 그럼 아래와 같은 메시지가 뜬다.



해당 커밋에 멈춰 있으니 git commit --amend로 수정을 한 다음에 git rebase --continue를 하라는 뜻이다. git rebase --continue는 현재 커밋에 대한 작업을 수행한 후 다음 커밋의 작업으로 넘어가는 명령어다. 테스트를 위해 README.md 파일만 수정하고 넘어가본다. 그러면 숫자들이 빠르게 움직이고 나서 아래와 같은 메시지가 나온다.



반영이 모두 완료돼었다는 뜻이다. 그런데 이런 완료 메시지가 나오지 않고 충돌이 떴다는 메시지가 나오는 경우도 있다. 중간 커밋의 수정사항 때문에 기존 커밋을 적용하지 못해 충돌이 발생하는 경우다. 이런 경우에는 중간 커밋의 수정사항을 따를 수 있도록 기존 커밋도 바꿔주도록 한다.