GitHub を用いたチーム開発をしている時、Pull Requestを取り込む方法はいくつかあります。
それは、「Create a merge commit
」「Squash and merge
」「Rebase and merge
」の3方式です。
以下のようにPull Requestをマージするボタンの三角ボタンを押すと出てきます。
ここに、上記で書いた、3種類のマージ方法があります。
今回の記事ではどのような使い分けをすればいいのかを書いていこうと思います。
なぜマージ方法が複数あるのか
GitHub は分散型バージョン管理システム「Git」を使用したアプリケーションのため、Git の設計思想が多く取り込まれています。そのため、以下のような利点があります。
第一に、誰が、いつ、どのような変更を行ったかを詳細に記録できること。第二に過去の変更履歴を参照することで、バグの原因を特定しやすくなること。第三に履歴を通じて、プロジェクトの設計意図や議論の経緯を新しいメンバーと共有できること。
これらのことから、履歴は単なる記録ではなく、プロジェクトの知的資産として機能します。それらをチーム規模や開発方針によってうまく運用・適応させるため、複数のマージ方法が存在します。
実際の使い分け
Create a merge commit
デフォルトで設定されている Create a merge commit
ですが、これは、複数のブランチを統合する際に、新たなマージコミットを作成します。図に表すと以下の通り。feature ブランチは、新しい差分を作成するために作ったブランチ名だと捉えてください。
流れとしては、
- main が存在する
- feature ブランチに分岐、新しい差分を追加
- main に対してPull Request(PR)として作成
- マージ(マージコミットFが作成される)
Fのコミットは、DとEの差分が含まれており、マージコミットと呼ばれます。これは「マージされたよ」というコミットです。どこのブランチからマージされたかという情報を含んでいます。マージコミットを作成するので、「Create a merge commit
」という方法なのです。
この方法は、誰が、いつ、どのような変更を行ったかを明確にするために有効です。そして、main ブランチ と feature ブランチは親子関係が残ります。しかし、マージコミットが増えることで、履歴が複雑になりがちです。
これを利用するケースとしては、「複数のブランチが頻繁にやり取りされる大規模なプロジェクト」や、「機能ごとのマージ履歴を明確に残したい場合」、「履歴を「どのブランチから取り込んだか」ベースで把握したい場合」に適していています。
Squash and merge
続いてSquash and merge
についてです。これは、複数のコミットを1つにまとめてからマージします。
図で表すと以下の通り。
流れとしては、
- main が存在する
- feature ブランチに分岐、新しい差分を追加(ここまでは同じ)
- main に対してPull Request(PR)として作成
- 新しいコミットが main ブランチに作成される
この新しいコミットは、先ほどのマージコミットとは違い、main ブランチ と feature ブランチは直接の親子関係を持ちません。そのため、履歴上にマージコミットは存在せず、直線的な履歴が保たれます。つまり、履歴が完結になり、見やすくなります。
しかし、マージコミットが存在しないため、どのブランチからマージされたのかが履歴上で明確に分からないという注意点も存在します。
これを利用するケースは、「作業途中のコミットをまとめて、1つの意味ある変更単位として履歴を残したい場合」や、「コードレビュー単位で履歴を残したいとき」に適しています。
Rebase and merge
この操作では、feature ブランチの各コミットが main ブランチの末尾に「再適用(rebase)」され、新たなコミットとして追加されます。
そのため、main ブランチにはマージコミットは作成されず、履歴は直線的な流れになります。
この直線的な履歴により、git log での読みやすさや git bisect による不具合調査がしやすくなるなどのメリットがあります。
ただし注意点として、Rebase により元のコミットとは別物(新しい SHA を持つ)として扱われるため、履歴の正確な出所(どのブランチで書かれたかなど)は履歴上からは判別しづらくなります。
実際、rebase を行うと、差分自体は main の 先頭に追加されるものの、feature ブランチの の D、E の差分のコミットIDと、main ブランチの の D、E の差分のコミットIDは異なります。
これを利用するケースとして、「各コミットを分解して追える状態で残したい場合」や「履歴をできるだけシンプルかつ直線的に保ちたい場合」に適しています。
おわりに
今回、GitHubで使用することのできる3つのPull Requestのマージ方法を紹介してきましたが、それぞれ規模感やチーム体制によって大きく左右されます。
「どれが正しい」ではなく、「どれが今のプロジェクトに合っているか」を意識することが大切です。本記事が、マージ方法の選択やブランチ戦略の整理に役立てば幸いです。
参考記事