GitHub でプルリクエストをマージする時、マージボタンのプルダウンに「Squash and merge」「Rebase and merge」ってありますよね。これらの違いをよく知らなかったので手元で試してみました。

プルリクエストのマージについて | GitHub ドキュメント

動作確認用に使ったプルリクエストはタイトルを PR-A に、コミットメッセージを A1 {コミット時刻} と統一しています。

1) Create a merge commit

プルダウンを展開せずにマージボタンを押したデフォルトの動作です。

同じブランチから切った複数ブランチをマージすると、時系列でコミットが積み上がります。

メインブランチに見立てた merge にブランチ merge-A merge-B をマージすると次の図のようになります。

デフォルトマージの図

git log merge-A
> 44b8478 A2 21:25
> fba0ad2 A1 21:23

git log merge-B
> 6bfb8c4 B2 21:26
> 74b8961 B1 21:24

git log merge
> 881e805 Merge pull request #18 from ringtail003/merge-B
> d2bef64 Merge pull request #17 from ringtail003/merge-A
> 6bfb8c4 B2 21:26 <== プルリクエスト(2)のコミット
> 44b8478 A2 21:25 <== プルリクエスト(1)のコミット
> 74b8961 B1 21:24 <== プルリクエスト(2)のコミット
> fba0ad2 A1 21:23 <== プルリクエスト(1)のコミット

GitHub でサンプルを見る

2) Squash and merge

Squash はプルリクエストのコミット群をひとつにまとめた新しいコミットを作成します。マージ先のブランチでは、プルリクエストとコミットが 1 対 1 になります。

メインブランチに見立てた squash にブランチ squash-A squash-B をマージすると次の図のようになります。

squashの図

git log squash-A
> 36001a5 A2 21:33 <== マージ元のコミット(2個目)
> 709eb44 A1 21:30 <== マージ元のコミット(1個目)

git log squash-B
> 2d087cb B2 21:34
> aea1a38 B1 21:32

git log squash
> 7d65cc7 PR-B (#20)
> 6d63afc PR-A (#19) <== マージ先のコミット(1個にまとまる)

GitHub でサンプルを見る

Squash and merge の Author

いくつかプルリクエストを作って試したところ、プルリクエストに一番最初にコミットした人がマージコミットの Author として採用されるようです。

プルリクエストに 2 番目以降にコミットした人は「共作者」という扱いになります。

git log --pretty=full

> commit 1234abc
> Author: user1 <user1@example.com>
> Commit: GitHub <noreply@github.com>
>  PR-A (#100)
> 
>  * A1
>  * A2
>  ---------
>  Co-authored-by: user2 <user2@example.com> <== 共作者

複数の作者を持つコミットを作成する | GitHub ドキュメント

3) Rebase and merge

Rebase はプルリクエストをマージ先ブランチでリベースしてからコミットを積みます。そのためコミットにそれぞれ新しいハッシュが付与されます。

メインブランチに見立てた rebase にブランチ rebase-A rebase-B をマージすると次の図のようになります。

rebaseの図

git log rebase-A
> 7258210 A2 21:39
> 7fcedd0 A1 21:37 <== マージ元のコミット

git log rebase-B
> 6ecf78f B2 21:40
> 5bd574d B1 21:38

git log rebase
> 3acd2d8 B2 21:40
> f4e83f7 B1 21:38
> e733a59 A2 21:39
> def1981 A1 21:37 <== マージ先のコミット(ハッシュが変わる)

GitHub でサンプルを見る

マージメッセージ

マージコミットのメッセージは Settings ページで変更できます。

選択肢がたくさんあるので表にまとめました。動作確認用に使ったプルリクエストはタイトルを PR-A {メッセージの種類} と統一しています。

マージの動作 メッセージの種類 Commits ページの表示
Merge Default message
Merge Pull request title
Merge Pull request title and description
Squash Default message
Squash Pull request title
Squash Pull request title and commit details
Squash Pull request title and description

GitHub でサンプルを見る | Merge
GitHub でサンプルを見る | Squash

一見すると同じに見えるマージメッセージですが、マージコミットのボディ部分が異なります。

Default message

Pull request title

Pull request title and commit details

Pull request title and description

考察

マージについて調べようと思ったきっかけは、どのプルリクエストをどの順番でマージしたのかサマリを見たいと思ったことでした。

この用途だと、プルリクエストごとにマージコミットが作成される「Squash and merge」が良さそうだということになります。ですが 1 コミットに集約されることで、本来のコミットごとの作業履歴が見られなくなる、単一のコミットでリバートできなくなる、などデメリットもあるようです。たとえば release ブランチにマージする時だけ「Squash and merge」を適用できたら嬉しいのですが記事執筆時点(2025/12)ではブランチごとのコントロールはできないようでした。

せっせとキャプチャをとってまとめましたが結論はデフォルトのまま現状維持、いずれまた検討する時がきたらこのブログを見に来ます。