GitHubのプルリクエストの差分はどこと比較しているか？(git diffの".."と"..."の違い)

[ディップ Advent Calendar 2018](https://qiita.com/advent-calendar/2018/dip-dev) の1日目です。


# はじめに
チーム開発をしていて、GitHubのプルリクエストでファイル差分を見たときに、
「masterと同じはずなのに差分として表示されている...なぜ？」となった経験はありませんか？

今回は、そのような事象にぶち当たったことがあるGit/GitHub初心者向けに、
GitHubのプルリクエストの差分の仕様についてまとめてみます。
また、その説明のためにGitのdiffコマンドのダブルドットとトリプルドットの違いについても確認します。


# まずは、`git diff`について
## `git diff`とは？
`git diff`は、コミット<->コミットやインデックス<->ワークツリーなどの差分を表示するコマンドです。

具体的な利用方法については、こちらの記事が分かりやすくてオススメです！
[忘れやすい人のための git diff チートシート - Qiita](https://qiita.com/shibukk/items/8c9362a5bd399b9c56be)

2つのコミットの差分を確認したい時、`git diff <commit1> <commit2>`という書き方以外に、
`git diff <commit1>..<commit2>`や`git diff <commit1>...<commit2>`といった書き方もあります。
では、これらの違いとは...？

## ダブルドット".."
ダブルドットの場合、指定した2つのコミット同士の差分を表示します。
以下の図で`git diff F..G`のように打つと、
コミットFとコミットGを比較して表示します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/50410/9c7b8b52-6025-5eed-bafd-df9ee6a9c128.png)

ちなみに、`git diff F G`とした場合と同じ結果になります。

## トリプルドット"..."
トリプルドットの場合は、**マージベース（2つのコミットの分岐点）との差分**を表示します。
以下の図で`git diff F...G`のように打つと、
**マージベース(分岐点)であるコミットB**とコミットGを比較します。
そのため、コミットCやコミットEで変更された内容は表示されません！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/50410/68709bd2-b8eb-2b81-1d42-c68c5a56c74b.png)


# では、GitHubのプルリクエストは？
GitHubのヘルプページにも書いてありますが、デフォルトは「**トリプルドット**」で表示されます。

> By default, pull requests on GitHub show a three-dot diff, or a comparison between the most recent version of the topic branch and the commit where the topic branch was last synced with the base branch.


参考: https://help.github.com/articles/about-comparing-branches-in-pull-requests/#three-dot-and-two-dot-git-diff-comparisons


## 実際に試してみた
GitHub上でプルリクエストを作成し、差分の表示を確認してみます。

### パターン1
以下のように、先程の図と同様の分岐となるようコミットしました。
各コミットでは、A,B,C...といったファイルを1つずつ作成しています。
<img width="228" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/50410/dfe9e7f7-9ea4-27f4-7270-d644ff98bf2e.png">

masterブランチには、topic-1ブランチで追加したCとEがマージされています。
<img width="262" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/50410/b71f087d-3e0e-32fe-f745-12b8dbbd40b7.png">

topic-2ブランチはこんな感じ。
<img width="277" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/50410/7cdddce3-c2e1-c2e4-cd9e-a275455c67ac.png">

この状態で、topic-2ブランチからmasterブランチへマージするためのプルリクエストを作成。
`Files changed`を見ると...
<img width="1002" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/50410/f53e23b7-c10d-d9c9-1244-cafec454c1ee.png">

このように、マージベースとの差分であるDとGのみが表示されます。

masterブランチにあってtopic-2ブランチにはない、CやEについては表示されません。


### パターン2
今度はこんな感じ。途中でCをtopic-2ブランチにもマージしてみます。

<img width="199" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/50410/2ef5e5ee-3fa2-4934-ef35-f5b228bcdcea.png">

masterブランチは先程と同じ。
<img width="262" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/50410/97faf559-ed79-e6eb-17ec-2446cf89f8d0.png">

topic-2ブランチにはtopic-1ブランチからマージしたCが含まれています。
<img width="273" alt="スクリーンショット 2018-11-29 17.13.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/50410/bc0607db-eca4-a75a-4ba4-21b96226c4f6.png">

この状態で、topic-2ブランチからmasterブランチへマージするためのプルリクエストを作成。
`Files changed`を見ると...
<img width="998" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/50410/48f88176-d2d7-d22f-e472-42721cda6f58.png">

このように、マージベースとの差分であるC、D、Gが表示されます。

masterブランチにも同じCが存在するので、「あれ？」となりがちですが、
あくまでもマージベースとの差分であることがわかっているとギモンは解決できます。


# まとめ
- git diffの".."はコミット同士の比較、"..."はマージベース(分岐点)との比較
- GitHubのプルリクエストの差分は**マージベース**との比較(トリプルドット)

普段使っていると当たり前すぎて意識していないかもしれませんが、
特殊なフローで運用していたり、意図しない差分が表示されて困ったりした時は復習してみると良いかも。