블로그 이미지
윤영식
Full Stacker, Application Architecter, KnowHow Dispenser and Bike Rider

Publication

Category

Recent Post

2013. 1. 14. 00:39 Git, GitHub

Remote 저장소인 GitHub과 Local 저장소의 commit 내역이 일치하지 않을 경우 rebase로 어떻게 해결하는지 알아보자. Local 저장소내에서 rebase를 사용하는 것과 약간의 차이점이 존재한다. (참조)


1. Remote 저장소 merge conflict 조건

  - GitHub에 이미 다른 Commit이 존재한다 (분홍색)

  - Local 저장소에 변경된 commit이 존재한다

  - git push 를 수행할 경우 merge conflict가 발생한다

  - 기존에 push후 conflict 발생시 pull 하고 문제 해결하고 다시 push 한다 (해결하기)

  



2. 이제 1)번의 경우 말고 fetch 와 rebase 사용

  - git fetch 를 통하여 local 저장소로 merge 하지 않고 origin/master의 별도 브랜치를 local 저장소로 복사하자 

    


  - git rebase를 수행한다. 이때 다음의 3단계로 진행이 된다. 

    + 브랜칭 된 이후의 master commit 내역을 temporary area로 이동시킨다-origin/master가 아니라- (초록색)

     


    + origin/master를 master 브랜치로 commit 한다. (분홍색)

       


    + temporary area에 있는 master commit 내역을 다시 master로 commit 한다. 

     



3. local과 remote의 같은 파일을 commit 하였을 때 rebase 하는 방법

  - master 브랜치에서 rebase하고 있음에 주의한다 

////////////////////////////////////////////////////////////////////////////

// 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...)가 밑에 있다. 


posted by 윤영식