GitHub でプルリクエストをマージする際には下記の通り3つの方法があります。
- Merge commit: All commits from this branch wil be added to the base branch via a merge commit.
- Squash and merge: The
ncommits from this branch will be combined into one single commit in the base branch.- Rebase and merge: The
ncommits from this branch will be rebased and added to the base branch.
では、以下のケースを想定して、それぞれのマージ方法でどのようなコミット履歴になるかを見てみましょう。
- ベースブランチ(main ブランチ)で
A, B, Cのコミットがありました。 Cのあとでトピックブランチ(feature ブランチ)を切り出してD, Eのコミットをしました。- ベースブランチ(main ブランチ)に PR を出してマージします。
Merge commit(マージコミット) #
マージを実行すると、main ブランチにマージコミット(X)が作成されます。
# マージ実行直前
main : A---B---C
\
feature: D---E
# マージ実行後
main : A---B---C---X--->
/
D---E
Squash and merge(スカッシュマージ) #
マージを実行すると、main ブランチに D と E をまとめた新しいコミット(X)が作成されます。
# マージ実行直前
main : A---B---C
\
feature: D---E
# マージ実行後
main : A---B---C---X--->
Rebase and merge(リベースマージ) #
マージを実行すると、D と E が main ブランチの最新のコミットの後ろに追加されます。
# マージ実行直前
main : A---B---C
\
feature: D---E
# マージ実行後
main : A---B---C---D'--E'-->
補足
ここで、GitHub でのリベースとマージの動作は、通常の git rebase コマンドの動作とは少し異なっていることには注意が必要です。通常の git rebase では、Fast-forward マージが可能な場合コミット情報(D, E)は変更されませんが、GitHub でのリベースマージでは新しいコミット SHA(D', E')で書き直します。
GitHub でのリベースとマージの動作は、
git rebaseとは少し異なっています。 GitHub でリベースしてマージすると、常にコミッター情報が更新され、新しいコミット SHA が作成されますが、GitHub 外のgit rebaseは、先祖コミットの上でリベースが発生した場合、コミッター情報は変更されません。
# マージ実行直前
main : A---B---C
\
feature: D---E
# 通常の git rebase でのマージ実行後
main : A---B---C---D---E--->
# GitHub でのリベースマージ実行後
main : A---B---C---D'--E'-->