Remote 저장소인 GitHub과 Local 저장소의 commit 내역이 일치하지 않을 경우 rebase로 어떻게 해결하는지 알아보자. Local 저장소내에서 rebase를 사용하는 것과 약간의 차이점이 존재한다. (참조)
- git fetch 를 통하여 local 저장소로 merge 하지 않고 origin/master의 별도 브랜치를 local 저장소로 복사하자
- git rebase를 수행한다. 이때 다음의 3단계로 진행이 된다.
+ 브랜칭 된 이후의 master commit 내역을 temporary area로 이동시킨다-origin/master가 아니라- (초록색)
+ origin/master를 master 브랜치로 commit 한다. (분홍색)
////////////////////////////////////////////////////////////////////////////
// remote 저장소와 commit 내역을 맞추고 확인해 보자
$ git log --pretty=oneline
bbeb691d80512e17279764312f60416ebf28dd86 add content in rebase of local repo
// rebase.html 파일의 내용
////////////////////////////////////////////////////////////////////////////
// 로컬에서도 rebase.html 파일을 변경하고 push를 시도하지만 reject 된다.
// 즉, remote 저장소의 rebase.html과 local 저장소의 rebase.html 내역이 틀리다.
$ git push
Username for 'https://github.com':
Password for 'https://ysyun@yuwin.co.kr@github.com':
To https://github.com/ysyun/pro_git.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/ysyun/pro_git.git'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. If you did not intend to push that branch, you may want to
hint: specify branches to push or set the 'push.default' configuration
hint: variable to 'current' or 'upstream' to push only the current branch.
////////////////////////////////////////////////////////////////////////////
// origin/master를 local 저장소로 가지고 온다.
$ git fetch
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From https://github.com/ysyun/pro_git
d895a7e..9274820 master -> origin/master
////////////////////////////////////////////////////////////////////////////
// rebase를 위하여 master로 이동한다
$ git branch
* (no branch)
master
$ git checkout master
Warning: you are leaving 1 commit behind, not connected to
any of your branches:
bbeb691 add content in rebase of local repo
If you want to keep them by creating a new branch, this may be a good time
to do so with:
git branch new_branch_name bbeb691d80512e17279764312f60416ebf28dd86
Switched to branch 'master'
Your branch and 'origin/master' have diverged,
and have 1 and 3 different commits each, respectively.
$ git branch
* master
////////////////////////////////////////////////////////////////////////////
// rebase를 수행한다.
// rebase.html 파일 내역에서 conflict가 나온다고 메시지를 출력한다
$ git rebase
First, rewinding head to replay your work on top of it...
Applying: updating rebase in local repo.
Using index info to reconstruct a base tree...
M rebase.html
Falling back to patching base and 3-way merge...
Auto-merging rebase.html
CONFLICT (content): Merge conflict in rebase.html
Failed to merge in the changes.
Patch failed at 0001 updating rebase in local repo.
When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To check out the original branch and stop rebasing run "git rebase --abort".
$ git status
# Not currently on any branch.
# Unmerged paths:
# (use "git reset HEAD <file>..." to unstage)
# (use "git add/rm <file>..." as appropriate to mark resolution)
#
# both modified: rebase.html
#
no changes added to commit (use "git add" and/or "git commit -a")
////////////////////////////////////////////////////////////////////////////
// rebase.html 파일 내역을 보고 적절히 수정한다
$ cat rebase.html
this is rebase html file ok
<<<<<<< HEAD
updating rebase in remote repo. again
add content in remote repo.
=======
updating rebase in local repo.
>>>>>>> updating rebase in local repo.
$ vi rebase.html
$ cat rebase.html
this is rebase html file ok
updating rebase in remote repo. again
add content in remote repo.
updating rebase in local repo.
////////////////////////////////////////////////////////////////////////////
// rebase.html 을 staging area로 add 한다.
$ git add rebase.html
////////////////////////////////////////////////////////////////////////////
// rebase를 계속 진행한다
$ git rebase --continue
Applying: updating rebase in local repo.
////////////////////////////////////////////////////////////////////////////
// commit log를 확인해 보면 rebase가 되어서 remote commit 내역이 local 저장소에
// 복사되었다.
$ git log --pretty=oneline
30d42e6785e441c3b515a4f4181dbfa051ad400a updating rebase in local repo.
9274820a9f62b2e08411ffb34d808508c7a74f93 add content in rebase of remote repo
d895a7e83d85d05f2c81585232f9c3e22426383a updating rebase again in remote repo
8c7c04b40d9fce0a1ae5a52b45b438fa14ea95e1 Update rebase.html
////////////////////////////////////////////////////////////////////////////
// 다시 push를 하면 정상적으로 remote 저장소로 push 가 된다
$ git push
Username for 'https://github.com':
Password for 'https://ysyun@yuwin.co.kr@github.com':
Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 323 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)
To https://github.com/ysyun/pro_git.git
9274820..30d42e6 master -> master
// remote에 local에서 직접 수정한 내역이 commit 됨
// local repo(파란색, 30d42e6785)의 SHA 값이 가장 상위에 그 다음 remote repo 의 SHA(927480a9f...)가 밑에 있다.