branchを切った時点のコミットとbranchの最新コミットとのlogとdiffをみたい

Pro Gitから図を引用すると、こういう

場合に、分岐した時点のmasterとexperimentの先っちょのlogやdiffをみたいというお話です。実際的には、topic branchをmasterにマージする前に変更点を確認したいといった局面です。

log

logの場合は「..」です。

$ git log --pretty=oneline master..experiment
ec8428d4d1884d3413e0949603c0c5cdd8aef414 D
863f5738a395fe090afaeaa120b67c45d65131c4 C

logにおける「..」についてPro Gitから引用すると、以下のように書かれています。

これは "experiment からはたどれるけれど、master からはたどれないすべてのコミット" という意味です。

Git - リビジョンの選択

一方、「...」という記法もあり、これについてはこう書かれています。

範囲指定選択の主な構文であとひとつ残っているのがトリプルドット構文です。これは、ふたつの参照のうちどちらか一方からのみたどれるコミット (つまり、両方からたどれるコミットは含まない) を指定します。

Git - リビジョンの選択
$ git log --pretty=oneline master...experiment
f4f63dd68307deea12da42038f57a00f1932794f F
ec8428d4d1884d3413e0949603c0c5cdd8aef414 D
e1b10c51204eb2fb34ea5f24c33b6f86f569d1c1 E
863f5738a395fe090afaeaa120b67c45d65131c4 C

diff

次にdiffです。

diffの場合は「..」ではなくて「...」です。

$ git diff master...experiment
diff --git a/foo b/foo
index 35d242b..8422d40 100644
--- a/foo
+++ b/foo
@@ -1,2 +1,4 @@
 A
 B
+C
+D

Pro Gitによればこう書かれています。

diff コマンドを実行するときにピリオドを三つ打った後に別のブランチを指定すると、「現在いるブランチの最新のコミット」と「指定した二つのブランチの共通の先祖」とを比較するようになります。

Git - プロジェクトの運営

ちなみに「..」は、このような差分が表示されます。

$ git diff master..experiment
diff --git a/foo b/foo
index 04bc76d..8422d40 100644
--- a/foo
+++ b/foo
@@ -1,4 +1,4 @@
 A
 B
-E
-F
+C
+D

おわりに

gitのリビジョンの範囲指定についてはgit help revisionsに書かれています。logの場合は範囲指定となるので、このルールに沿うかたちになるようです。

一方、diffは、

  • 範囲指定ではなく2点間の指定である
  • 「...」は範囲指定のそれではなく、あくまでgit diff $(git merge-base master experiment) experimentの構文糖に過ぎない

ということのようです。