はじめに
複雑なブランチ構成をしたプロジェクトのgithubでプルリクエストを作ったとき、なぜかブランチで行っていない筈の修正が変更ファイルのタブに表示されてしまうことはないだろうか?
単純なファイルdiffを取るとこの修正は差分表示されなかったり、実際にマージを実行するときこの修正は悪影響を及ぼさなかったりするので、この謎の差分は何者なのか気になっていたが、こいつについて調査してみた。
現象・原因
現象
複雑なブランチ構成のgithub管理プロジェクトで、プルリクエストの Files changed タブ にマージ元ブランチ以外の修正内容(既にマージ済みの他ブランチ修正内容)が表示される場合がある。
(変更ファイルとして表示はされるが)実際にマージするときは、既にマージ済みの他ブランチ修正内容を再度マージしようとして衝突(コンフリクト)が発生することは無い。
原因
githubのプルリクエストでは、gitのトリプルドットdiffによって変更ファイルを表示している。
この現象の原因はトリプルドットdiffが「共通祖先」と「マージ元ブランチ」の差分を表示することにある。
トリプルドット差分は通常であればマージ元ブランチで行われた修正のみを差分表示する。
しかし、複雑な状況下では期待しない差分表示されてしまうことがある。
実際にマージするときは、「共通祖先」と「マージ元ブランチ」と「マージ先ブランチ」を元に3-way mergeアルゴリズムでマージされるので、上記差分とは異なる内容がマージされる。
(ちなみにこの状況でgit diff main...featureX
のコマンドを打つと、multiple merge bases, using 《コミットID》
警告が出る。)
具体例
現象の発生手順
git-flowでリリースブランチに緊急でfeatureをマージした場合などに、この現象は発生する。
たとえば以下のような手順で操作をおこなったとき、現象が発生する。
- developからrelease1.0.0ブランチ、feature1ブランチ、feature2ブランチを作成。
- feature1ブランチ、feature2ブランチにそれぞれ修正をかけて、修正内容をdevelopとrelease1.0.0へマージ。
- release1.0.0に修正を加えてdevelopにマージするプルリクエストを作成する。
このとき、プルリクエストのFiles changed タブは、以下のようになる。
-
期待するFiles changed タブ
release1.0.0で行った修正のみが表示される
(「feature1、feature2がマージされたdevelop」と「release1.0.0ブランチ」の差分) -
実際のFiles changed タブ
release1.0.0で行った修正+feature1で行った修正が表示される
(「feature2」と「release1.0.0ブランチ」の差分)
現象の発生するコミットグラフ
コミットグラフは以下のようになる。
見るとわかるように 共通祖先コミットは feature1修正を含まない 。
そのため git diff develop...release1.0.0
を表示すると、共通祖先とrelease1.0.0の差分である「release1.0.0で行った修正+feature1で行った修正」が表示される。
別パターンの現象発生コミットグラフ
以下のようなパターンでも、Files changed タブ にマージ元ブランチ以外の修正内容が表示されてしまう。(マージ先ブランチ=developで行った修正なのに表示されてしまう)
原因はやはりgitのトリプルドットdiffによって変更ファイルを表示していることである。
対策
根本的な対策はおそらく無い
この現象はgitの仕様から来ているものだと思うので、根本的な対策はおそらく無い。
気にせず無視するのがベターな対策だと思われる。
release1.0.0ブランチにdevelopをマージしても問題ない状況(developにリリースしたくない余計なコミットが入っていない)なら、developをrelease1.0.0にマージする事で、変更ファイルをrelease1.0.0で行った修正のみ表示させることができる。
ただし developからrelease1.0.0へ意図しない修正をマージしてしまう危険性があるのでお勧めしない 。
お勧めしない対策をした後のコミットグラフ
参考url
PR Diff shows different content from the actual file content in Bitbucket Datacenter
https://confluence.atlassian.com/bitbucketserverkb/pr-diff-shows-different-content-from-the-actual-file-content-in-bitbucket-datacenter-1384450058.html