1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHubのPull Requestにおける3種類のマージ方法の比較と使い分け

Posted at

GitHubでのチーム開発において、Pull Request(PR)は欠かせない機能です。PRを通じてコードレビューを行い、品質を担保しながら開発を進めることができます。PRのマージ方法には「Create a merge commit(マージコミットの作成)」「Squash merge(スカッシュマージ)」「Rebase merge(リベースマージ)」の3種類があります。これらの違いを理解し、プロジェクトに合った方法を選択することが重要です。

1. 3種類のマージ方法の違い

Create a merge commit(マージコミットの作成)

これはGitHubのデフォルトのマージ方法です。featureブランチの全てのコミット履歴を保持したまま、マージを行います。マージの際に新たな「マージコミット」が作成され、2つのブランチが合流したことを示します。

特徴:

  • featureブランチの全コミット履歴が保持される
  • マージの証拠となる専用のマージコミットが作成される
  • 開発の流れが完全に記録される

コミットの状態:

A---B---C---D---F (main)
     \         /
      E1--E2--E3 (feature)

マージ後:

A---B---C---D---F---G (main) ← Gはマージコミット
     \         /
      E1--E2--E3 (feature)
  • E1、E2、E3の全てのコミットが履歴に残る
  • マージコミットGが作成される
  • ブランチの分岐と合流が明確に表示される

Squash merge(スカッシュマージ)

featureブランチの全てのコミットを1つのコミットにまとめて(スカッシュして)、mainブランチにマージします。PRの全ての変更は単一のコミットとしてmainブランチに追加されます。

特徴:

  • 複数のコミットが1つにまとめられる
  • mainブランチのコミット履歴がシンプルになる
  • PRのタイトルと説明がコミットメッセージとして使用される
  • 個々の作業ステップの詳細は失われる

コミットの状態:

A---B---C---D---F (main)
     \
      E1--E2--E3 (feature)

マージ後:

A---B---C---D---F---E' (main) ← E'はE1, E2, E3をまとめたコミット
  • E1、E2、E3が統合されて単一のコミットE'になる
  • ブランチの分岐点は履歴に残らない
  • コミット履歴がシンプルになる

Rebase merge(リベースマージ)

featureブランチのコミットを個別にmainブランチに適用します。マージコミットは作成されず、コミット履歴は線形になります。

特徴:

  • featureブランチの各コミットが個別にmainブランチに追加される
  • マージコミットは作成されない
  • コミット履歴が線形になる
  • 各コミットのSHAハッシュが変更される(新しいコミットとして扱われる)

コミットの状態:

A---B---C---D---F (main)
     \
      E1--E2--E3 (feature)

マージ後:

A---B---C---D---F---E1'---E2'---E3' (main) ← E1', E2', E3'は再適用されたコミット
  • E1、E2、E3が個別にE1'、E2'、E3'として再適用される
  • コミットの内容は同じだが、新しいSHAハッシュが割り当てられる
  • 線形の履歴になる

マージ方法の比較表

特性 Create a merge commit Squash merge Rebase merge
コミット履歴 全てのコミットが保持される 1つのコミットに統合される 個別のコミットとして保持されるが再作成される
マージコミット 作成される 作成されない 作成されない
履歴の形状 分岐と合流が見える 線形 線形
コミットのSHA 元のままで保持 新しいコミット1つのみ作成 全てのコミットが新しいSHAで再作成
履歴の詳細さ 最も詳細 最も簡潔 詳細だが線形
トレーサビリティ 完全に保持される PRレベルでのみ保持 コミットの内容は保持されるが、元のSHAは変更
用途の例 開発過程の詳細な記録 機能単位での整理されたコミット 読みやすい線形履歴の維持

2. 実際の開発フローでの使い分け

GitHub上の開発では、「Git Flow」と呼ばれる開発フローがよく採用されています。Git Flowは、長期開発ブランチ(mainやdevelop)と短期トピックブランチ(feature、release、hotfix)を使い分けることで、安定した開発を実現します。このフローにおける各ブランチのマージ種別について見ていきましょう。

Git Flowの基本的なブランチ構成

Git Flowでは、主に以下のブランチを使用します:

  • main: 本番環境のコード(リリース済み)
  • develop: 開発中のコード(次回リリース用)
  • feature: 新機能開発用の短期ブランチ
  • release: リリース準備用のブランチ
  • hotfix: 緊急バグ修正用のブランチ

feature ブランチから develop ブランチへのマージ

推奨マージ方法: Squash merge

develop: A---B---C---D---F---E' (E'はfeatureブランチの変更をまとめたコミット)
          \
feature:    E1--E2--E3

理由:

  • 開発者が試行錯誤したコミット履歴を整理でき、developブランチをクリーンに保てる
  • 一つの機能実装を一つのコミットとして記録できる
  • PRのタイトルと説明をコミットメッセージとして活用できる
  • コードレビューの結果を反映した最終的な変更だけを残せる

設定方法:

# developブランチでSquash mergeを推奨する設定例(リポジトリ設定)
ブランチ保護ルール > develop > マージ方法の制限 > 「Allow squash merging」にのみチェック

release ブランチから main ブランチへのマージ

推奨マージ方法: Create a merge commit

main:    M1------M2------M3------M4------------------M5
          \                                         /
develop:   D1--D2--D3--D4--D5--D6--D7--D8--D9--D10
                            \                     /
release:                     R1--R2--R3--R4--R5--R6

理由:

  • リリースの事実を明示的に記録できる(マージコミットがリリースポイントになる)
  • リリースの範囲が履歴から明確に分かる
  • リリースタグを付けやすい(マージコミットにタグを付ける)
  • リリース単位での変更追跡が容易になる

設定例:

# mainブランチでCreate a merge commitを推奨する設定例
ブランチ保護ルール > main > マージ方法の制限 > 「Allow merge commits」にのみチェック

release ブランチから develop ブランチへのマージ

推奨マージ方法: Create a merge commit または Rebase merge

# Create a merge commitの場合
develop: D1--D2--D3--D4--D5--D6--D7--D8--D9--D10----D11
                            \                     /
release:                     R1--R2--R3--R4--R5--R6

# Rebase mergeの場合
develop: D1--D2--D3--D4--D5--D6--D7--D8--D9--D10--R3'--R4'--R5'--R6'
                            \
release:                     R1--R2--R3--R4--R5--R6

理由:

  • リリース準備中に行った修正をdevelopブランチにも反映する必要がある
  • Create a merge commitの場合:リリース準備での修正が一連の変更として分かりやすい
  • Rebase mergeの場合:修正を個別のコミットとして反映させつつ、線形の履歴を維持できる

hotfix ブランチから main ブランチへのマージ

推奨マージ方法: Create a merge commit

main:    M1------M2------M3------M4---------------M5------M6
          \                                      /         /
hotfix:                                                   H1--H2

理由:

  • 緊急修正の事実を明示的に記録できる
  • 修正内容が明確に分かる
  • 修正パッチとしてのバージョン管理がしやすい

hotfix ブランチから develop ブランチへのマージ

推奨マージ方法: Squash merge または Rebase merge

# Squash mergeの場合
develop: D1--D2--D3--D4--D5--D6--D7--D8--D9--D10--D11--H'
                                                        (H'はhotfixの変更をまとめたコミット)

# Rebase mergeの場合
develop: D1--D2--D3--D4--D5--D6--D7--D8--D9--D10--D11--H1'--H2'

理由:

  • 本番環境で行った緊急修正を開発環境にも反映する必要がある
  • Squash mergeの場合:「本番の緊急修正の取り込み」として一つのコミットにまとめられる
  • Rebase mergeの場合:修正内容を詳細に残しつつ、線形の履歴を維持できる

実際のワークフローにおける使い分けのポイント

  1. チームの規模と経験に応じた使い分け

    • 小規模チーム・経験の浅いチーム:Squash mergeを中心に使うと履歴が分かりやすい
    • 大規模チーム・経験豊富なチーム:Create a merge commitで詳細な履歴を残す
  2. コミット粒度の管理

    • コミット粒度が適切に保たれている場合:Rebase mergeやCreate a merge commitが適している
    • コミット粒度が細かすぎる場合:Squash mergeで整理する
  3. ブランチの役割に応じた使い分け

    • 長期ブランチ同士のマージ(release→main):Create a merge commit
    • 短期ブランチから長期ブランチへのマージ(feature→develop):Squash merge
    • バグ修正や変更の伝播(hotfix→develop):用途に応じてSquashかRebase
  4. 自動化とCI/CDの考慮

    • デプロイが特定のコミットに紐づいている場合:Create a merge commitで明示的なマージポイントを作る
    • テスト自動化がコミット単位で走る場合:Squash mergeで無駄なテスト実行を減らす

チーム開発での考慮点

プロジェクトやチームに合ったマージ戦略を選ぶ際には、以下の点を考慮すると良いでしょう:

  1. リポジトリ単位でデフォルト設定を決める

    • プロジェクトの性質に合わせて、リポジトリのデフォルトマージ方法を設定する
    • チーム全体で一貫性を持たせる
  2. ブランチ保護ルールの設定

    • 重要なブランチ(mainやdevelopなど)に対して、特定のマージ方法のみを許可する
    • 意図しないマージ方法の使用を防止する
  3. コミットメッセージの規約を設ける

    • 特にSquash mergeを使用する場合、PRのタイトルとなるコミットメッセージの形式を統一する
    • 例:[機能名] 実装内容の簡潔な説明
  4. プロジェクトのドキュメントに明記する

    • 採用するマージ戦略をREADME.mdやCONTRIBUTING.mdに明記する
    • 新メンバーがチームの慣習を理解しやすくする

まとめ

GitHubのPull Requestにおけるマージ方法は、プロジェクトの性質やチームの好みによって選択すべきものです。履歴の詳細さを重視するなら「Create a merge commit」、メインブランチのコミット履歴をシンプルに保ちたいなら「Squash merge」、線形の履歴が好ましいなら「Rebase merge」が適しています。

どの方法が「最良」というわけではなく、プロジェクトごとに最適な方法を選択することが重要です。チーム内で方針を統一し、一貫性のあるマージ戦略を採用することで、効率的な開発が可能になります。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?