GitHubでのプルリクエストをマージする際のマージ戦略について纏めた記事です。
マージ戦略の種類
Merge Commit(マージコミット):
- これは最も一般的なマージ方法で、プルリクエストの全てのコミットをメインブランチにマージします。
- このプロセスはマージコミットを生成し、プルリクエストのコミット履歴がそのままメインブランチに追加されます。
Squash and Merge(スカッシュマージ):
- この方法では、プルリクエスト内の全てのコミットが1つのコミットに統合されてからメインブランチにマージされます。
- これにより、履歴が綺麗に保たれ、不要な中間コミットが除去されますが、個々のコミットの詳細は失われます。
Rebase and Merge(リベースマージ):
- この方法では、プルリクエストのコミットがメインブランチの最新コミットの上に再配置(リベース)されてからマージされます。
- これにより、リニアなコミット履歴が保たれますが、リベースの過程でコンフリクトが発生する可能性があります。
まとめ
先にまとめです。
Squash Merge
、Merge Commit
、およびRebase and Merge
の違いです。
特徴 / マージ戦略 | Squash Merge | Merge Commit | Rebase and Merge |
---|---|---|---|
コミット履歴 | 1つのコミットに統合されます。 | 全てのコミットが履歴に含まれます。 | フィーチャーブランチのコミットがリベースされます。 |
マージコミット | 生成されません。 | マージコミットが生成されます。 | 生成されません。 |
履歴の線形性 | 線形。 | 非線形(ブランチの分岐と統合が可視化されます)。 | 線形。 |
適用シナリオ | 多くの小さなコミットを1つにまとめたい時。 | ブランチの完全な履歴を保持したい時。 | リニアな履歴を保ちたい時。 |
履歴の保持 | 個々のコミットの詳細は失われる。 | ブランチの全てのコミットの詳細が保持される。 | 元のコミット順序は保持されるが、タイムスタンプが変更されることがある。 |
主な用途 | プロジェクト履歴をシンプルに保ちたい時。 | ブランチの分岐と統合の履歴を残したい時。 | プロジェクト履歴をリニアに保ちたい時。 |
以降、各マージ戦略の詳細です。
Merge Commit(マージコミット)
基本概念:
- メインブランチ(例えばmain
)とフィーチャーブランチ(例えばfeature
)の間で、新しい「マージコミット」を作成します。
- このマージコミットは両方のブランチの履歴を保持しています。
具体例:
- あるプロジェクトで、main
ブランチからfeature
ブランチが分岐しました。
- feature
ブランチで3つのコミット(C1, C2, C3)が作成されました。
- 同時に、main
ブランチでも新しいコミット(C4)が作成されました。
- feature
ブランチをmain
にマージするとき、新しいマージコミット(M)が生成され、main
にはC1, C2, C3, C4, そしてMが含まれます。
結果の履歴:
main: A -- B -- C4 -- M \ / feature: C1 -- C2 -- C3
- ここで、AとBは元々
main
にあったコミットです。 M
はマージコミットで、feature
ブランチの変更をmain
に統合します。
Rebase and Merge(リベースマージ)
基本概念: - フィーチャーブランチのコミットを、メインブランチの最新コミットの上に「再配置」(リベース)します。 - これにより、リニアな履歴が作成され、マージコミットは生成されません。
具体例:
- 同じシナリオを考えます:main
からfeature
が分岐し、feature
にはC1, C2, C3、main
にはC4のコミットがあります。
- リベースすると、C1, C2, C3はC4の後に配置されます。
- その後、feature
ブランチの変更がmain
にマージされます。
結果の履歴:
main: A -- B -- C4 -- C1' -- C2' -- C3'
- C1', C2', C3'はリベースされたC1, C2, C3のコミットです。
- リベースにより、
feature
ブランチのコミットは、main
ブランチの最新コミットの後に直接追加されます。
Squash and Merge(スカッシュマージ)
基本概念: - フィーチャーブランチ上の全てのコミットが1つのコミットに統合されます。 - この単一のコミットがメインブランチにマージされます。 - 元のフィーチャーブランチの個々のコミットの履歴は失われますが、その内容は保持されます。
具体例:
- main
ブランチからfeature
ブランチが分岐し、feature
ブランチには3つのコミット(C1, C2, C3)があります。
- 同時に、main
ブランチには新しいコミット(C4)が作成されています。
- feature
ブランチをスカッシュマージすると、C1, C2, C3が1つの新しいコミット(S)に統合され、その後main
にマージされます。
結果の履歴:
main: A -- B -- C4 -- S
- ここで、AとBは元々
main
にあったコミットです。 S
はスカッシュされた新しいコミットで、feature
ブランチの変更(C1, C2, C3)がすべて含まれています。main
ブランチの履歴はリニアに保たれ、feature
ブランチの個別のコミットはmain
の履歴には現れません。
結論
- Merge Commitはマージコミットを生成し、ブランチの分岐と統合の履歴が残ります。
- Rebase and Mergeはリニアな履歴を作成し、分岐したブランチのコミットをメインブランチのコミットの後に直接配置します。これにより、履歴が綺麗になりますが、元のコミットのタイムスタンプや順序が変わることがあります。
- Squash and Mergeでは、フィーチャーブランチの全ての変更が1つのコミットに統合され、メインブランチの履歴が綺麗に保たれます。
以上です。