Skip to content

Git:Rebase

Forward-port local commits to the updated upstream head.

How to use

작업 도중 다른 branch와 rebase할 경우 git rebase origin/master와 같은 식으로 rebase 하면 된다.

CONFLICT

만약 작업 도중 충돌이 발생하면 아래와 같은 메시지가 출력된다.

...
CONFLICT (content): Merge conflict in /conflict/file/path
Failed to merge in the changes.
...

이 후 git status로 확인하면 아래와 같은 상태 메시지가 출력된다.

rebase in progress; onto 87fbff3
...

이후 충돌 해결 방법은 아래와 같다.

  1. 충돌 해결 후 해당 코드를 git add한 후 git rebase --continue명령으로 rebase를 계속 한다.
  2. git rebase --skip명령으로 해당 충돌을 SKIP한다.
  3. git rebase --abort명령으로 rebase를 중단하고 원래의 branch로 복원한다.

이전 커밋 합치기

WARNING

로컬 저장소의 내용은 rebase 이후엔 이전 상태로 되돌릴 수 없다. 신중히 생각하고 진행하자.

다음과 같은 커밋이 있을 때:

* 51da922 (HEAD -> develop-2.0) Fix errors in api
* 9cad4de jest init
* 802d313 eslint init
* 3780bdf prettier init
* 4a16ea5 babel init
* bbffc8a webpack-cli init
* 7590a44 yarn init
* 8074314 (origin/develop-2.0) Update api project settings
* 6a79977 Initialize the api module as a typescript project
* 7325a9a vue add electron-builder

git rebase -i 7590a44 과 같이 날리면 vim으로 아래 내용을 편집할 수 있다. (주석 제거)

pick 51da922 Fix errors in api
pick 9cad4de jest init
pick 802d313 eslint init
pick 3780bdf prettier init
pick 4a16ea5 babel init
pick bbffc8a webpack-cli init
pick 7590a44 yarn init

참고로 주석의 내용은 다음과 같다:

  • p, pick <commit> = use commit
  • r, reword <commit> = use commit, but edit the commit message
  • e, edit <commit> = use commit, but stop for amending
  • s, squash <commit> = use commit, but meld into previous commit
  • f, fixup <commit> = like "squash", but discard this commit's log message
  • x, exec <command> = run command (the rest of the line) using shell
  • b, break = stop here (continue rebase later with 'git rebase --continue')
  • d, drop <commit> = remove commit
  • l, label <label> = label current HEAD with a name
  • t, reset <label> = reset HEAD to a label
  • m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
    • create a merge commit using the original merge commit's message (or the oneline, if no original merge commit was specified). Use -c <commit> to reword the commit message.

pick 으로 되어있는 부분을 s으로 바꾸면 합쳐진다.

pick 51da922 Fix errors in api
s 9cad4de jest init
s 802d313 eslint init
s 3780bdf prettier init
s 4a16ea5 babel init
s bbffc8a webpack-cli init
s 7590a44 yarn init

주의할 점은, pick을 모두 s로 바꾸면 다음과 같은 에러가 출력된다.

error: cannot 'squash' without a previous commit
You can fix this with 'git rebase --edit-todo' and then run 'git rebase --continue'.
Or you can abort the rebase with 'git rebase --abort'.

사용할 커밋(보통 최신인 첫째줄)은 반드시 pick 해야 한다.

Change Log message

진전 로그 메시지를 수정하는 방법은 git commit --amend를 사용하면 되지만, 그 이전의 로그 메시지를 수정할 경우 rebase를 사용해야 한다.

$ git rebase -i <commit>

지정한 커밋보다 이후의 커밋을 지정하면, 커밋의 목록이 표시된다. 그 중에서 코멘트을 수정하려고 하는 커밋을 찾아 그 행 pick 문자를 edit로 변경하고 저장, 종료한다.

다음 --amend 옵션을 지정하여 커밋을 실행하고, 로그 메시지를 수정한다.

$ git commit --amend

마지막으로 --continue옵션을 지정하여 rebase를 계속 진행한다.

$ git rebase --continue

Abort

rebase 도중 전체 작업을 취소하고 싶을 경우 아래와 같입 입력하면 된다.

$ git rebase --abort

Favorite site