🦧

【図解】git merge か git rebase か?履歴の見え方の違い

に公開

プロジェクトで運用ルールを決める際、最も大きな判断基準となるのが「コミットログ(履歴)をどう残したいか」です。マージ型とリベース型で何が違うのか実際にGitグラフを使いながら説明します。

1. マージ型:全ての履歴を残す (git merge)

「いつ分岐して、いつ合流したか」という事実をすべて残すパターンです。
git pull (オプションなし) や git merge --no-ff を使った場合、必ず「マージコミット」が作成されます。

特徴:

  • 履歴が枝分かれし、合流地点(マージコミット)が記録される。
  • 開発の時系列が正確に残るが、人数が増えると線が複雑に絡み合い(いわゆる「スパゲッティ状態」)、追いづらくなることがある。

2. リベース型:履歴を一本にする (git rebase)

「あたかも最新の状態から開発を始めた」かのように履歴を書き換えるパターンです。
git pull --rebase を使って、枝分かれを解消してから統合します。

特徴:

  • マージコミットが作られず、履歴が一直線(Linear)になる。
  • 「いつ分岐したか」の情報は消えるが、機能単位のコミットの流れが非常に追いやすくなる。

(※図はリベース後に Fast-forward マージされ、一直線になった状態を表しています)

マージとリベースの違い、実は同じでない?

上のセクションを読むと「結局、どちらでも同じ結果になるのでは?」と思いませんか?

実は、ブランチが2つ以上分岐する場合に、大きな違いが出てきます。以下の画像が非常にわかりやすいので取り上げさせていただきます。参考URL : [git pull と git pull --rebase の違いって?図を交えて説明します!]

左図:マージした場合

  • moyou(昔のmainブランチ)とマージコミット(M)が存在する
  • 複数の経路が同時に進行していたことが分かる

右図:リベースした場合

  • マージコミット(M)が作られない
  • moyouブランチは存在しなくなり、あたかも一直線で開発が進んだように見える

つまり:

  • git merge → 「複数の流れが合流した」という事実を残す
  • git rebase → 「あたかも最初から一直線だった」かのように見せる

この差は、チーム開発で数多くのブランチが存在する場合に、履歴の追いやすさに大きく影響します。

まとめ:どちらを採用すべき?

マージ型 (merge) リベース型 (rebase)
履歴の形 枝分かれが発生(ダイヤモンド型) 一直線
メリット 実作業の時系列が正確に残る。
コンフリクト解決が一度で済む。
ログが見やすく、bisect(バグ特定)などが容易。
コミットログが「物語」として読みやすくなる。
デメリット ログが汚くなりやすく、変更の追跡が難しくなる場合がある。 履歴を改変するため、共有済みのブランチでやると危険。
コンフリクト解決がコミットごとに発生する場合がある。

参考URL

https://kray-blog.docbase.io/posts/3738493

Discussion