Both of these commands are designed to integrate changes from one branch into another branch - they just do it in very different ways.
BASE: 특정 브랜치를 생성할 때 기준이 되는 commit. 즉 브랜치 생성 전 마지막 commit.
main branch로 이동하여 remote main을 pull 받는다.
내가 push할 feature branch로 이동한다.
git rebase -i main
명령어를 입력하면 에디터가 나타난다.
-i
: interactive mode
가장 오래된 commit을 pick
한다. (오래된 순으로 나열되므로 맨 위에 있는 commit이 가장 오래된 것이다.)
다른 commit은 가장 오래된 commit을 기준으로 squash
한다. 다른 commit의 작업 내역이 없어지는 것이 아니라 pick한 commit으로 병합하는 것이다.
수정용 에디터가 하나 더 나타난다. 최종적으로 이 rebase된 commit의 메세지를 작성하는 부분이다. 현재까지 적은 commit 메세지가 전부 나타난다. 불필요한 내용을 제거하고 현재 수정 내역에 대한 commit 메세지를 작성한다.
branch를 생성한 후 처음 push할 때는 그냥 push하면 된다.
branch 생성 후 두 번째 push부터는 --force
옵션을 사용하여 force push를 진행한다.
git push origin feature/login --force
git push --force
를 하는 이유
- rebase는 commit history를 정리하는 역할을 한다. 같은 브랜치에서 rebase를 할 때마다 history가 달라질 수 있다.
- 수정 사항이 추가로 생긴 후 다시 rebase하면 history가 무조건 달라진다. git은 history가 다른 branch의 push를 허용하지 않는다.
- 즉, rebase를 하면 새로운 commit을 기존 commit에 추가하는 형태가 아니라 완전히 새로운 commit으로 덮어씌우는 것이기 때문에 local의 history와 remote의 history가 다르므로
--force
옵션을 붙여 강제로 push를 해야 한다.
conflict는 commit과 commit 사이에서 일어나는 작업 내용 사이의 충돌이므로, 여러 개의 commit이 한 번에 충돌날 가능성이 있다.
따라서 commit이 2~3개 쌓이면 rebase를 꼭 진행하는 것이 좋다.
git add .
(git commit
은 하지 않는다. 수정 사항이 없으니까)git rebase --continue
를 진행하면 멈춰 있던 rebase가 진행된다.git add .
→ git rebase --continue
를 반복한다.git rebase --abort
로 아예 rebase를 진행하기 전 상황으로 돌아갈 수도 있다.git rebase --i
(interactive mode) 명령어# Commands:
# 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 [-C | -c] <commit> = like "squash" but keep only the previous
# commit's log message, unless -C is used, in which case
# keep only this commit's message; -c is same as -C but
# opens the editor
# 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
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.