gitでローカルのmasterとリモートのorigin/masterのどちらが先に進んでるか簡単に分かるコマンドないですか?

gitでバージョン管理しているものの中に、たまにコードを書き進めるちょっとしたプログラムがあります。たまにしか書かないので、なかなかpushしないんですが、ほんとたまになので、未pushがあるのかどうかも忘れてたりします。これは1人で書いてるからまぁ良いんですが、もし複数人でやっててorigin/masterが知らない間に進んでるとしたら、未pushなのがあるかどうかの確認ってどうするんだろう?出来てもめんどくさいんじゃないかと思ってます。色々調べてみたんですが良い方法が見つかりませんでした。

エントリー書いた後に教えてもらった事

@kanonji git statusで上に出ませんか?upstreamが設定されてれば"Your branch is behind 'origin/master' by 1 commit"こんな感じで。

キーボードが波打っている on Twitter: "@kanonji git statusで上に出ませんか?upstreamが設定されてれば"Your branch is behind 'origin/master' by 1 commit"こんな感じで。"

エントリーを書いたら教えてもらいました。ありがとうございます。なぜか自分の環境ではこれが出なかったんですが、バージョンが低すぎたのか*1リポジトリがおかしくなっていたのか、とにかく普通は出力されるはずのものです。

$ git --version
git version 1.7.3.5
$ git status
# On branch master
nothing to commit (working directory clean)
$ git fetch
remote: Counting objects: 65, done.
remote: Compressing objects: 100% (38/38), done.
remote: Total 54 (delta 20), reused 3 (delta 0)
Unpacking objects: 100% (54/54), done.
From http://github.com/ichikaway/cakeplus
   35955e4..e84f014  master     -> origin/master
$ git status
# On branch master
# Your branch is behind 'origin/master' by 7 commits, and can be fast-forwarded.
#
nothing to commit (working directory clean)

gitのバージョンを1.7.3.5に上げて、下記で当初例に使ったリポジトリはマージしてしまったので、別のプロジェクトを使って試しました。どうやら、git fetchしてあれば、git statusで、ローカルとリモートの進み具合がわかるようです。出るはずのを見てなかったので、下記で書いたことがとんだ迷走になってるけど、gitの知識にはなったのでまぁいいか。

一応調べた事

結論的にはgit fetchしてFETCH_HEADがある状態にしてからgit diff FETCH_HEADなどとして、比較が出来る事は分かりました。ただgit diffだと、どちらが進んでいるのか予め知らないといけないようです。この例だと、リモートの方が進んでいるんですがgit diff FETCH_HEAD masterの様に書くと、出力されるunified diffではリモートにある追加された部分が-で表示されてしまいます。このエントリーの例だと、ローカルでは何も変更してないので、diffをじっくり見れば気がつけそうではあります。
でも、ローカルは自分で変更してて、リモートは他の人が変更しpush済みだと、diffじゃ分からないんじゃないかなと思っています。まだそういうリポジトリが手元に無いので、実際のとこどうか分からないけど。
git diffgit logで注意深く見分けろってことなのかな?

補足

調べるに当たって、リモートでコミットが進んでいて、手元にあるプロジェクトを探してみたら、ちょうどKtai Libraryがあったので、https://github.com/MASA-P/ktai-devを例に使いました。

また、各所でローカルのmasterという表現をしてますが、branchを切ってる場合はmasterじゃなくって、そのブランチ名とするのが正しいかもしれません。ローカルってだけの表記だと、なんか違う気がして書いてるんですが、正しくはどうなるんだろう?

git fetch

Twittergit fetchしたらどうかと教えてもらいました。今まであんまり必要なかったのと、git fetchって取り消しが出来なさそうな印象だったので、ちょっと敬遠してたんですが、この機会に調べました。

$ git log -1
commit 94b5de546d8c32c2ec73cedd90d85fe3672c9003
Author: Masaharu Takishita <censored>
Date:   Sat Dec 4 10:40:36 2010 +0900

    #44 バージョン0.4.0でuse_xmlをにセットしていないとワーニングが出る

ローカルではこのリビジョンまででした。ブランチ名省略したらgit log -1 masterと同じです。

$ git log -1 origin/master
commit 94b5de546d8c32c2ec73cedd90d85fe3672c9003
Author: Masaharu Takishita <censored>
Date:   Sat Dec 4 10:40:36 2010 +0900

    #44 バージョン0.4.0でuse_xmlをにセットしていないとワーニングが出る

https://github.com/MASA-P/ktai-dev/commit/9a6f91ce0fd021c8bfb514d3ae6c033e80e33b55

調べた時点での最新のコミットはこれ。だけどgit logでorigin/masterを見ても出てきません。

$ git log FETCH_HEAD
fatal: ambiguous argument 'FETCH_HEAD': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions

FETCH_HEADはまだ無いので見れない。

$ git fetch
From https://github.com/MASA-P/ktai-dev
   94b5de5..9a6f91c  0.x        -> origin/0.x
   94b5de5..9a6f91c  master     -> origin/master
From https://github.com/MASA-P/ktai-dev
 * [new tag]         0.4.1      -> 0.4.1

git fetchでリモートにある分を取ってきます。

$ git log -1
commit 94b5de546d8c32c2ec73cedd90d85fe3672c9003
Author: Masaharu Takishita <censored>
Date:   Sat Dec 4 10:40:36 2010 +0900

    #44 バージョン0.4.0でuse_xmlをにセットしていないとワーニングが出る

ローカルでは変化なし。git fetchはローカルのmasterに影響しないようです。

$ git log -1 origin/master
commit 9a6f91ce0fd021c8bfb514d3ae6c033e80e33b55
Author: Masaharu Takishita <censored>
Date:   Wed Feb 16 11:16:24 2011 +0900

    requestAction()で自動コンバートを抑制する(修正)

リモートであるorigin/masterは、ちゃんと最新のリビジョンになっています。

$ git log -1 FETCH_HEAD
commit 9a6f91ce0fd021c8bfb514d3ae6c033e80e33b55
Author: Masaharu Takishita <censored>
Date:   Wed Feb 16 11:16:24 2011 +0900

    requestAction()で自動コンバートを抑制する(修正)

そしてFETCH_HEADも。git fetchするとリビジョン?index?branch?かなんだか分かりませんが、FETCH_HEADが使える様になるみたいです。

git diff

git diffで比較するには、最初に書いたように、ローカルとリモートのどちらがより進んでるのかを、知らないと正しい比較が出来ませんでした。
なお、git fetchをして、git diffで比較出来るようになりました。上記で書いてないけどgit fetchする前はorigin/masterは最新じゃないので、git logと同様にgit diffも本当の最新リビジョンと比較できません。

git diff FETCH_HEAD*2git diff origin/mastergit diff origin/master mastergit diff master origin/masterになっています。

- * @copyright          Copyright 2009-2011, ECWorks.
+ * @copyright          Copyright 2009-2010, ECWorks.

ここを注目すると分かるように、新しいコミットが-になってます。

- * Copyright 2009-2010, ECWorks.
+ * Copyright 2009-2011, ECWorks.

正しくはこうなるべきで、これはgit diff master origin/masterの出力です。

$ git diff 古いリビジョン 新しいリビジョン

どうやらgit diffはこの順番で引数を指定するものみたいです。そして引数を1個だけにすると、ローカルのmasterが最新であると判断するみたい。ここでどっちがより進んでるのか判断して、適切に切り替えてくれたら期待通りだったんですが、残念ながら違いました。

環境

Mac Mac OS X 10.5.8(Leopard
git 1.6.5.2

*1:1.6.5.2

*2:画像にはないけど