かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Git squash merge された PR に依存する PR を Fast Forward に rebase する Tips

ある PR A の変更に依存した PR B を作った時、main ブランチに squash マージする戦略のリポジトリだとマージされた PR A のコミットは 1 つになっており、RR B のマージ先が main に向いた時、コミットの履歴が異なるので PR A のコミットがそのまま表示され、git rebase origin/main で fast forward にしようとしても RR B では PR A のコミットが 1 つになっているため rebase でコンフリクトが発生してしまいます。

図で書くとこんな感じ

  1. PR A に依存した PR B があるブランチ
    PRA に依存した PRB があるブランチ
  2. PR A が main に squash merge される
    PR A が main に squash merge された状態
  3. PR B を main で rebase して Fast Forward な状態にしようとしてもコンフリクトしてしまう
    PR B を main で rebase しようとしてもコンフリクトする

コミット数が少なければコンフリクトの解消も大した手間ではないかもしれませんが、コミット数の多い PR だと手間が多くそもそもコンフリクトの解消は新しいバグを混入してしまう原因になると思っているので極力避けたいところです

解決方法 main にマージされたコミットを 1 つにまとめてしまえば Fast Forward に rebase できる

main にマージされた PR A のコミット内容を rebase して 1 つのコミットにまとめてしまえば、main にマージされた merge コミットと比較されるのが同じ変更内容の 1 コミットになるのでコンフリクトを避けられる

  1. PR B を rebase して PR A の内容を fixup や squash で 1コミットにまとめる
    PR B を rebase して PR A の内容を 1コミットにまとめる
  2. PR B に PR A の内容を 1つにまとめたコミットが作られる
    PR B に PR A の内容を 1つにまとめたコミットが作られる
  3. PR B を main で rebase すると1つにまとめた PR A のコミットが打ち消され Fast Forward な状態になる
    PR B を main で rebase すると1つにまとめた PR A のコミットが打ち消され Fast Forward な状態になる

どのコミットまでが既にマージされたコミットなのかを覚えておく必要がありますが、squash merge されたコミットを1コミットにまとめてしまえば git rebase origin/main で自動的に既にマージ済みのコミット(rebase で 1つにまとめたコミット)がなくなりコンフリクト対応なしに Fast Forward な状態にすることができました!

個人的に squash merge 戦略は PR がマージされないと、その変更有りきの PR を作った後に必ず rebase が必要になるので事故が起こる原因にもなると思っておりあまり好きではないです。

squash merge 戦略あまり好きくない。
₍ ᐢ. ̫ .ᐢ ₎ おわり


[参考]