実際のコード差分と GitHub 上の compare 結果が異なる状況の再現

開発現場でこのような状況が発生して pull request をどうレビューして良いのか分からない、マージして良いのか分からないという状況が発生したため書きました。
Git, GitHub の熟練者は改めて確認するような内容ではないと思います。

再現結果

いきなり結論ですが、再現した状況をここに用意しました。

f:id:semnil:20200318174952p:plain

再現方法

詳しくはここに書いてある通りです。 二つのブランチに対して、複数のコミットを逆順でマージした後、それぞれのブランチのソースコードは同一の内容になり、差分はありません。 ですが、一方のブランチから新たに作成したブランチで変更をコミットした後に GitHub で pull request をもう一方のブランチに向けて作成すると、コミットした変更以外の差分が表示されます。 GitHub の差分確認の機能を使用しても、本来発生していない差分が表示される状態になります。

f:id:semnil:20200318175235p:plain

なんで発生するのか

GitHub の差分が Three-dot 基準で表示されるためです。

help.github.com

git-scm.com

Three-dot のオプションを使用すると、二つのコミットの共通の祖先になるコミットから、後に指定したコミットの差分を出力する結果になります。 f:id:semnil:20200318181625p:plain

どうしたら良いのか

  1. 二つ以上のブランチに複数のコミットをマージする時には順番に気を付けましょう
  2. 発生してしまったら、二つのブランチ (今回の例では master に staging) をマージして pull request を作り直しましょう

補足

もっとわかりやすく書いていらっしゃる方がいらっしゃいました。

qiita.com

補足 2

どうしたら良いのかの 2 を実施してみたのがこれです。
GitHub 上で pull request を作ろうとするとボタンが押せない状態になるので、
f:id:semnil:20200319082724p:plain

手元でマージしてプッシュします。

% git checkout staging
Switched to branch 'staging'
% git merge master --no-ff
Merge made by the 'recursive' strategy.
# ↑ あまりお目にかかれない 'recursive' strategy の出力
% git push origin staging

f:id:semnil:20200319083240p:plain

この状態で改めて pull request を作り直すと、求めていた状態になるはずです。