Gitの小ネタおれおれAdvent Calendar 2022 – 14 日目

git log や git diff では 2 つのブランチを取って差分を表示することができます。

先にまとめ

  • git log A..B – A から見た B 側の更新のみを表示
  • git log A...B – A 側、B 側の両方の更新を表示
  • git diff A..B – A 側、B 側の両方の変更を表示
  • git diff A...B – A から見た B 側の変更のみを表示
A..B A...B
git log B のみ A と B
git diff A と B B のみ

逆転してますねどういうことですか調べてみましたがわかりませんでしたいかがでしたか???

図で見る git log における違い

この図解がめちゃくちゃわかりやすかったのでこれ見て終わりです。投稿者の情報はなくなっちゃってるので謎ですが。

ベン図やコミットツリーを着色した図解のスクショ。
図で見るとわかりやすい。

嘘ですすみません、ちゃんと書きます。

例

今こんな状態です。main ブランチから a ブランチを作成してコミット、その間に main にひとつコミットがあり、さらにそこから別のブランチ b が作られています。今 b の方にいますね。

(↑新しい)
* afadd3c update B  (HEAD -> b)
* 613a126 zzz  (main)
| * 6c3c970 update A  (a)
|/
* a5f8e2c yyy
* 7a96aff xxx
(↓古い)

2 つのドット .. で片方のみ

a..b で a を基準に b の更新内容が出てきます。”613a126 zzz” と “afadd3c update B” の 2 です。

$ git log a..b
commit afadd3c6d0096177e4274cd1d5001bff4df92ffd (HEAD -> b)
Author: Ginpei <[email protected]>
Date:   Tue Nov 29 19:03:49 2022 +0900

    update B

commit 613a126e56608c5ef407f37fe98b296d735fe6ce (main)
Author: Ginpei <[email protected]>
Date:   Tue Nov 29 19:14:40 2022 +0900

    zzz

逆に b..a にすると、同じく b を基準に a の更新内容が出てきます。a は main から分岐後のコミットは “6c3c970 update A” のみです。

$ git log b..a
commit 6c3c9706246dfc61cbe0921c824c49785ad8f9e3 (HEAD -> a)
Author: Ginpei <[email protected]>
Date:   Tue Nov 29 19:03:11 2022 +0900

    update A

main を基準にするとこんな感じ。いずれも「main ブランチにまだ含まれていないもの」が出てきます。

$ git log main..a
commit 6c3c9706246dfc61cbe0921c824c49785ad8f9e3 (a)
Author: Ginpei <[email protected]>
Date:   Tue Nov 29 19:03:11 2022 +0900

    update A
$ git log main..b
commit afadd3c6d0096177e4274cd1d5001bff4df92ffd (HEAD -> b)
Author: Ginpei <[email protected]>
Date:   Tue Nov 29 19:03:49 2022 +0900

    update B

3 つのドット ... で両者の違い

3 つ A...B の の場合は A と B の両方に共通するものを除きます。つまり両方の更新内容(コミット)が全て出てきます。結果として A...B と B...A は同じです。(だよね?)

$ git log a...b
commit afadd3c6d0096177e4274cd1d5001bff4df92ffd (HEAD -> b)
Author: Ginpei <[email protected]>
Date:   Tue Nov 29 19:03:49 2022 +0900

    update B

commit 613a126e56608c5ef407f37fe98b296d735fe6ce (main)
Author: Ginpei <[email protected]>
Date:   Tue Nov 29 19:14:40 2022 +0900

    zzz

commit 6c3c9706246dfc61cbe0921c824c49785ad8f9e3 (a)
Author: Ginpei <[email protected]>
Date:   Tue Nov 29 19:03:11 2022 +0900

    update A
$ git log b...a
commit afadd3c6d0096177e4274cd1d5001bff4df92ffd (HEAD -> b)
Author: Ginpei <[email protected]>
Date:   Tue Nov 29 19:03:49 2022 +0900

    update B

commit 613a126e56608c5ef407f37fe98b296d735fe6ce (main)
Author: Ginpei <[email protected]>
Date:   Tue Nov 29 19:14:40 2022 +0900

    zzz

commit 6c3c9706246dfc61cbe0921c824c49785ad8f9e3 (a)
Author: Ginpei <[email protected]>
Date:   Tue Nov 29 19:03:11 2022 +0900

    update A

同様に main...a の場合は “613a126 zzz” と “6c3c970 update A” が出ます。

main...b はどうでしょう。b は main の先に繋がっているので “613a126 zzz” は出ず、b の変更 “afadd3c update B” のみが出てきます。

--left-right でどちらの変更か表示

3 つ ... を使うときに --left-right オプションを付けると、> か < かを出力されどっちのブランチに連なるコミットなのかわかるようになります。

$ git log a...b --left-right 
commit > afadd3c6d0096177e4274cd1d5001bff4df92ffd (HEAD -> b)
Author: Ginpei <[email protected]>
Date:   Tue Nov 29 19:03:49 2022 +0900

    update B

…

commit < 6c3c9706246dfc61cbe0921c824c49785ad8f9e3 (a)
Author: Ginpei <[email protected]>
Date:   Tue Nov 29 19:03:11 2022 +0900

    update A

git diff は git log の逆

.. と ... が何故か逆の意味になります。なんで?

例

git log の例と同じ状態です。再掲します。

(↑新しい)
* afadd3c update B  (HEAD -> b)
* 613a126 zzz  (main)
| * 6c3c970 update A  (a)
|/
* a5f8e2c yyy
* 7a96aff xxx
(↓古い)

3 つのドット ... で片方のみ

git diff の場合は 3 つのドット ... の場合に片方だけを表示します。

先の例の状態で a...b だと a にない b 側の更新だけが表示されます。”613a126 zzz” と “afadd3c update B” の 2 つ分ですね。

$ git diff a...b 
diff --git a/new.md b/new.md
new file mode 100644
index 0000000..fa5f29b
--- /dev/null
+++ b/new.md
@@ -0,0 +1,1 @@
+# Hello
\ No newline at end of file
diff --git a/text.md b/text.md
index ec600df..6811f0e 100644
--- a/text.md
+++ b/text.md
@@ -6,4 +6,4 @@ This is A.

 ## B

-This is B.
+This is B!

同様に b...a だと a 側の変更だけが出てきます。b のブランチに存在しないのは “6c3c970 update A” だけですね。

$ git diff b...a
diff --git a/text.md b/text.md
index ec600df..2ae766d 100644
--- a/text.md
+++ b/text.md
@@ -2,7 +2,7 @@

 ## A

-This is A.
+This is A!

 ## B

2 つのドット .. で両者の違い

git log と逆にこれで両方出てきます。

$ git diff a..b 
diff --git a/new.md b/new.md
new file mode 100644
index 0000000..fa5f29b
--- /dev/null
+++ b/new.md
@@ -0,0 +1,1 @@
+# Hello
\ No newline at end of file
diff --git a/text.md b/text.md
index 2ae766d..6811f0e 100644
--- a/text.md
+++ b/text.md
@@ -2,8 +2,8 @@

 ## A

-This is A!
+This is A.

 ## B

-This is B.
+This is B!

なんで逆になってるんだろ

わからないので教えてください……。

おしまい

.. と ... の違いについては StackOverflow に投稿されていた図のおかげで完全理解しました。

一方 git log と git diff の違いについては謎ですね。なんなんこれ。

参考