akiyoko blog

akiyoko の IT技術系ブログです

Gitメモ ~ git pull の謎 ~

いざリモートリポジトリにpushしようとして、先にリモートリポジトリに変更があった場合に、「'git pull' でマージしてから push しろや」と怒られることがありますよね?

$ git push origin master
To ssh://sakura/var/git/test_repo.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'ssh://sakura/var/git/test_repo.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.


言われたとおり大人しく git pull すると、

$ git pull origin master
remote: Counting objects: 5, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From ssh://sakura/var/git/test_repo
 * branch            master     -> FETCH_HEAD
Merge made by the 'recursive' strategy.
 README |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

$ git log
commit 45e93cbe0251feb1c52db5249c1ca9d37866def3
Merge: e366c32 27da298
Author: Aki Yoko 
Date:   Thu Jun 6 00:46:22 2013 +0900

    Merge branch 'master' of ssh://sakura/var/git/test_repo

commit e366c326339dbcb216e05aedb2a2b5d06e8bc4ce
Author: Aki Yoko 
Date:   Thu Jun 6 00:45:39 2013 +0900

    Third commit.

commit 27da298d3900f54b7dcf4368cf7775772c59be22
Author: Other User 
Date:   Thu Jun 6 00:44:02 2013 +0900

    Second commit. (by other user)

commit 11bbb94827ab5394d7c1f2dd35f37db7f62b5fce
Author: Aki Yoko 
Date:   Fri May 31 00:34:34 2013 +0900

    Initial commit.

「Merge branch 'master' of ssh://sakura/var/git/test_repo」という不要なログが挟まることがあります。リモートの変更をローカルにマージしたよという意味なのでしょうが、気持ち悪いですよね。

今回は、これを無くすためのTipsです。


結論としては、「git pullするときに --rebaseオプションを付ける」というのが正解のようです。

なので、ここは一旦マージ前まで git reset --hard で戻してから、--rebaseオプション付きで git pullをやり直します。

$ git reset --hard e366c326339dbcb216e05aedb2a2b5d06e8bc4ce
HEAD is now at e366c32 Third commit.

$ git pull --rebase origin master
From ssh://sakura/var/git/test_repo
 * branch            master     -> FETCH_HEAD
First, rewinding head to replay your work on top of it...
Applying: Third commit.

$ git log
commit f0be36b6f8d4e37801d0d2d220b697e542618539
Author: Aki Yoko 
Date:   Thu Jun 6 00:45:39 2013 +0900

    Third commit.

commit 27da298d3900f54b7dcf4368cf7775772c59be22
Author: Other User 
Date:   Thu Jun 6 00:44:02 2013 +0900

    Second commit. (by other user)

commit 11bbb94827ab5394d7c1f2dd35f37db7f62b5fce
Author: Aki Yoko 
Date:   Fri May 31 00:34:34 2013 +0900

    Initial commit.

「Merge branch 」うんたらというコミットログが挟まらなくなりましたね。
これで安心して、git push できちゃいますね!!

てか、ほぼ気持ちの問題。


ちなみに、git pullは、実際には「git fetch して git merge」してるだけとどこかで読んだことがあります。--rebaseオプションを付けることで、fetch してからリモートリポジトリでリベースしてくれるというイメージなのかな。
いずれにせよ、便利♪