GitHub Squash Mergeのメリットと派生ブランチの落とし穴
Squash Merge とは
PR をマージする際、PR 内の全コミットを1つのコミットにまとめて main に入れる方式。
通常マージとの比較
通常マージ(Create a merge commit)
PR 内の作業コミットがすべて main に入る。
main:
abc1234 Merge pull request #94
def5678 fix: テストのモック戻り値を修正
ghi9012 refactor: 引数を構造体に統一
jkl3456 feat: リトライ機構を追加 (#91)
Squash Merge
PR ごとに1コミットになる。
main:
abc1234 refactor: 引数を構造体に統一 (#94)
jkl3456 feat: リトライ機構を追加 (#91)
メリット
- main の履歴が PR 単位になり、途中の試行錯誤(typo 修正、レビュー対応等)が見えない
git log mainが読みやすいgit bisectで問題コミットを探すときも PR 単位で絞れる
落とし穴:派生ブランチで差分が混入する
Squash Merge では新しいコミットハッシュが生成される。そのため、未マージのブランチから別ブランチを切ると問題が起きる。
発生条件
main ─── A
└── branch-1 (PR #1) ─── B ─── C
└── branch-2 (PR #2) ─── D
PR #1 を Squash Merge すると、main には B+C をまとめた新コミット BC' が入る。
main ─── A ─── BC' (新しいハッシュ)
branch-2: A ─── B ─── C ─── D (元のハッシュのまま)
branch-2 の PR には B, C, D の差分が表示される。Git は BC' と B+C が同じ変更だと認識できない。
対策
- 新ブランチは常に最新の main から切る
- やむを得ず派生した場合は
git rebase origin/mainで解消できる
GitHub での設定
Repository Settings → General → Pull Requests で以下を選択可能:
- Allow merge commits(通常マージ)
- Allow squash merging(Squash Merge)
- Allow rebase merging(Rebase Merge)
複数有効にしてPRごとに選ぶことも、1つだけに絞ることもできる。
まとめ
Squash Merge は main の履歴をきれいに保つ良い選択。ただし「新ブランチは必ず main から切る」というルールとセットで運用すること。