PullRequestの差分が正しく出ない
PullRequestの差分が正しく出ない問題に遭遇しました。 それぞれのブランチが全く同じ内容のファイルなのにもかかわらず、です。
PullRequestの差分が正しく出ない理由は、新しく作ったブランチとtargetブランチのcommitIdが異なることに原因がありました。 (私の場合、原因は100%これにありました)
ここでは、新しく作ったブランチをdevelopとして、targetブランチをmainとします。 気をつけたほうが良い作業は、cherrypickやhotfix作業が挙げられますが、それ以外の場合でもこれを理解していれば解決の助けになるかもです。 PullRequestはcommitをもとに差分が比較されます。「commitをもとに差分が比較される」です。 何を言いたいかというと、commit自体が「ソースコードの差分」を持っているわけではありません。
コミットはスナップショットであり差分ではない - GitHubブログ
commitはスナップショットであり、PullRequestが差分を計算する際は、新しく作ったブランチとtargetブランチのcommitのスナップショット同士が比較されます。 さて、cherrypickやhotfixを行うとmainブランチには、developブランチにはないcommitが作成されます。
cherrypickは、developにあるcommitをmainブランチに持っていく作業のように見えますが、厳密にはdevelopブランチとmainブランチのcommitIdは異なります。
git log
でcommitIdを見てみるとわかります。 「新しく作ったブランチとtargetブランチのcommitのスナップショット同士が比較されます」と先ほど言いました。developブランチには無いcommitがmainブランチに存在した場合、それは比較対象から外れます。
表を作りました。commitId4にいくらcommiId3と同じソースコードが存在したとしても、developブランチが比較できるのはmainブランチのcommitId2までです。いくらmainブランチのHEADがcommitId4でもdevelopブランチの中にcommitId4の情報がないので比較ができません。 そのため、同じ内容のファイルなのに差分が正しく出ない問題が起きます。
develop | main commitId5 | | commitId4 commitId3 | commitId2 | commitId2 commitId1 | commitId1
これは、developブランチをrebaseすればなおります。rebaseは、developブランチにmainブランチの変更を取り込むことを意味します。
git checkout main git pull git checkout develop git pull git merge main
取り込むと先ほどの表は以下のようになります。 以前は、PullRequestの比較対象はmainブランチのcommitId2でしたが、commitId4が比較対象に含まれました。commitId4はcommitId3と同じソースコードを持つため、「commitId4にいくらcommiId3と同じソースコードが存在したとしても差分として出てしまう」といった問題がこれで解消されます。
develop | main commitId5 | commitId4 | commitId4 commitId3 | commitId2 | commitId2 commitId1 | commitId1
解決方法は単純ですが、なぜそうなるかを知っていれば、自信を持ってリリース作業を行えますね。