🔀

rebase vs merge、いつ何を使うか

履歴保存と線形化のトレードオフ

両方とも最終ファイルは同じになり得る。違いは履歴の形だ。

merge

2つのブランチを結合する新しいコミット(マージコミット)を作る。元のコミットはそのまま残る。分岐と合流がグラフにそのまま現れる。

rebase

自分のブランチのコミットを取り外し、別のブランチ(通常main)の最新コミットの上に1つずつ積み直す。元のコミットは破棄され、新しいハッシュで再生成される。

核心ルール

共有ブランチはrebaseしない。 既に誰かが取得したコミットをrebaseするとハッシュが変わり、相手の履歴と衝突する。これが『Golden Rule of Rebase』だ。

個人のフィーチャーブランチはrebaseでmainの上に載せると綺麗だ。PRを出す前にgit rebase mainで整えると、レビュアーが見るdiffが最小化される。

squash merge

GitHubの『Squash and merge』ボタンはPRの全コミットを1つにまとめてmainに入れる。mainの履歴は綺麗だが、個別コミットの文脈は消える。トレードオフだ。

動作フロー

1

merge: `git checkout main && git merge feature` → マージコミット生成

2

rebase: `git checkout feature && git rebase main` → featureのコミットをmain上に移動

3

interactive rebase: `git rebase -i HEAD~5` → コミットのsquash/edit/reorder

4

衝突時は解決後`git rebase --continue`、または`git rebase --abort`

メリット

  • merge: 履歴をそのまま保存、安全
  • rebase: 線形履歴、レビューしやすい

デメリット

  • merge: マージコミットが積もるとグラフが複雑になる
  • rebase: 共有ブランチで使うと災害、force pushが必要

ユースケース

merge: チームの公式ブランチ統合(main ← develop、main ← release) rebase: PR前の個人ブランチ整理 squash: 小さな修正コミットをまとめてmain履歴を綺麗に保つ

参考資料