Gitを使った開発では、複数人で作業した履歴をまとめたり、自分の作業ブランチを最新状態に合わせる場面が頻繁にあります。そのときによく使われるのが merge と rebase です。どちらもブランチの変更を取り込むコマンドですが、履歴の残り方や作業の流れに大きな違いがあります。
merge はブランチ同士を結合し、実行した時点の状態をそのまま新しいコミットとして残します。一方、rebase は履歴を付け替えることで、あたかも最初から一続きで作業していたような履歴に書き換えます。これにより履歴がスッキリしますが、使い方を誤ると他の人の作業に影響を与える危険もあります。
この記事では、merge と rebase の違いを押さえながら、git rebase を安全かつ効果的に使う方法を解説します。履歴をきれいに保ちたい方や、チーム開発で混乱を避けたい方に役立つ内容です。
基本概念の比較:merge vs rebase の違いと特徴
merge の特徴
git merge は、指定したブランチの変更を現在のブランチに取り込みます。
このとき、それぞれの履歴はそのまま残り、新しく「マージコミット」が追加されます。
メリット
- 履歴を改変しないため安全
- 他の開発者と作業を共有していても衝突が起きにくい
- 作業の分岐と統合の履歴が明確に残る
デメリット
- マージコミットが多くなり、履歴が複雑に見える
- 単純に変更を追いたいときにログが見づらくなる
rebase の特徴
git rebase は、あるブランチの変更履歴を別のブランチの先頭に「付け替える」動作をします。
結果として、履歴が一直線になり、あたかも最初からそのブランチ上で作業していたように見えます。
メリット
- 履歴が直線的になり、過去の作業を追いやすい
- コミット履歴が整理され、レビューや調査がしやすい
デメリット
- 履歴を書き換えるため、共有済みのブランチではトラブルの原因になる
- force push が必要になるケースがあり、操作を誤ると他人の作業を失う危険がある
比較表
| 項目 | merge | rebase |
|---|---|---|
| 履歴の形 | 分岐と統合が残る | 直線的に整理される |
| 安全性 | 高い(履歴を変えない) | 注意が必要(履歴を書き換える) |
| マージコミット | 発生する | 発生しない(通常) |
| 主な用途 | 履歴を正確に残す | 履歴を整理・見やすくする |
使い分けの目安
- 共有ブランチや本番用ブランチでは
mergeを使い、安全性を優先する - 自分専用の作業ブランチでは
rebaseを使い、履歴をきれいに保つ
私が現場での経験から学んだ事
私が関わったある現場では、チーム全体の方針として「履歴をきれいに保つために rebase を使う」ことが推奨されていました。確かに rebase を使えば履歴が直線的になり、ログも見やすくなります。しかし、その現場には Git の利用に不慣れなメンバーも多く、特にコンフリクトが発生したときに問題が頻発しました。
rebase は履歴を書き換えるため、操作を誤るとコミットが消えてしまいます。実際、コンフリクト解消時にうっかりコミットを飛ばしてしまい、作業履歴が失われるケースが何度もありました。結果として、「履歴をきれいにする」という一部の理解者にとってのメリットが、その他多数のメンバーにとっては大きな負担になっていたのです。
私はこの状況を見て、こっそりと「共有ブランチや安全性が求められる場面では merge を使おう」と周囲に勧めるようになりました。merge は履歴が分岐してもコミットを失う危険がなく、Git に不慣れな人でも安心して扱えます。履歴の美しさよりも、まずは安全性とチーム全体のストレス軽減を優先すべきだと、身をもって学んだ経験でした。
基本的な使い方:git rebase, git rebase -i とその流れ
基本的な git rebase の流れ
git rebase は、あるブランチの変更を別のブランチの先頭に付け替える操作です。
例えば、feature ブランチを main の最新状態に合わせたい場合、以下の手順になります。
# 作業ブランチに移動
git checkout feature
# main ブランチの最新状態を取得
git fetch origin main
# feature ブランチを main の先頭に付け替え
git rebase origin/main
この操作により、feature ブランチのコミットは main の最新コミットの後ろに並び、履歴が一直線になります。
対話的リベース(git rebase -i)
git rebase -i(interactive)は、指定した範囲のコミットを並べ替えたり、まとめたり、削除したりできる強力な機能です。
例えば、直近3コミットを整理したい場合は以下のようにします。
git rebase -i HEAD~3
エディタが開き、対象コミットが次のように表示されます。
pick a1b2c3d 初期設定ファイル追加
pick e4f5g6h README追記
pick i7j8k9l バグ修正
ここで pick を以下のように変更すると、動作が変わります。
| コマンド | 説明 |
|---|---|
| pick | コミットをそのまま使う |
| squash | 前のコミットにまとめる(メッセージもまとめて編集) |
| fixup | 前のコミットにまとめる(メッセージは破棄) |
| edit | コミット内容を修正 |
| drop | コミットを削除 |
コンフリクトが発生した場合
rebase 中にコンフリクトが発生すると、Gitは処理を一時停止します。
コンフリクトを解消したら、以下のコマンドで続行します。
git add <修正ファイル>
git rebase --continue
途中でやめたい場合は以下のコマンドで元に戻せます。
git rebase --abort
ポイント
git rebaseは 履歴を書き換える操作 なので、他の人と共有していないブランチで使うのが基本- コンフリクトが発生しやすいので、作業単位を小さくしてこまめに実行するのがおすすめ
- 対話的リベースは履歴整理に便利だが、誤操作でコミットを失わないよう注意する
対話モードのコマンド解説:pick, squash, fixup, edit など
git rebase -i(インタラクティブ・リベース)では、複数のコミットを自由に並べ替えたり、まとめたり、削除したりできます。ここでは、表示される主要なコマンドとその役割を詳しく解説します。
pick
指定したコミットをそのまま使います。
初期状態ではすべての行が pick になっており、これを変更することで他の操作を指示できます。
例:
pick a1b2c3d 初期設定ファイル追加
squash
この行のコミットを、直前のコミットにまとめます。
まとめた後、コミットメッセージを編集できます。履歴を整理して関連する変更を1つのコミットにしたいときに便利です。
例:
pick a1b2c3d 初期設定ファイル追加
squash e4f5g6h README追記
fixup
pick の直前のコミットにまとめますが、コミットメッセージは破棄されます。
後から修正しただけのコミットを統合したい場合に使います。
例:
pick a1b2c3d 初期設定ファイル追加
fixup e4f5g6h タイポ修正
edit
対象のコミットを適用したあと、処理を一時停止します。
この間に修正や追加を行い、git commit --amend などでコミットを更新できます。
例:
pick a1b2c3d 初期設定ファイル追加
edit e4f5g6h 関数の最適化
drop
コミットを履歴から削除します。不要な変更を取り除きたいときに使用します。
例:
pick a1b2c3d 初期設定ファイル追加
drop e4f5g6h 不要なコード追加
実用的な使い方の例
- 小さな修正や不要なコミットを
fixupでまとめて履歴をスリム化 - 関連するコミットを
squashで一つに統合してレビューを簡潔に - 一部のコミットを
editで修正し、品質を高める
注意点
インタラクティブ・リベースは履歴を書き換えるため、共有済みブランチでの使用は避けましょう。特に drop は変更内容を完全に消すので、必要な場合はバックアップや別ブランチの作成を行ってから作業するのが安全です。
具体的なユースケース紹介:複数コミットまとめ、最新取り込み、履歴整理
複数コミットをまとめる(squash / fixup)
作業中に「ちょっとした修正」や「タイポ修正」などの小さなコミットが増えてしまうことはよくあります。レビュー時や履歴の見やすさを考えると、関連する変更を1つのまとまりにした方が良い場合があります。
例:
# 直近3コミットをまとめる
git rebase -i HEAD~3
エディタで squash または fixup を指定し、不要なコミットを整理します。
最新の変更を取り込む(ブランチ更新)
長期間作業しているブランチに対して、ベースとなるブランチ(例:main)の最新変更を反映したいときに rebase が活躍します。
例:
git checkout feature
git fetch origin main
git rebase origin/main
これにより、feature のコミットが main の最新の後ろに並び、直線的な履歴になります。
履歴の整理(不要コミットの削除・修正)
履歴に不要な実験的コミットや誤った変更が含まれている場合、git rebase -i で削除(drop)や修正(edit)を行うことで、履歴をクリーンな状態に保てます。
例:
git rebase -i HEAD~5
- 不要なコミットは
drop - 修正したいコミットは
edit→ 修正 →git commit --amend→git rebase --continue
注意点
- 共有ブランチや他の人が作業中のブランチでは行わない
- 操作前に必ず作業内容を保存し、必要なら別ブランチにバックアップを作成する
rebase後はgit push --force-with-leaseが必要になる場合があるため、意図しない上書きに注意
操作手順のステップガイド:準備 → rebase → 衝突対処 → push
1. 準備
rebase は履歴を書き換える操作なので、まずは作業環境を安全な状態に整えます。
- 作業内容をコミット
未コミットの変更があると途中で混乱する原因になります。作業中の変更はコミット、もしくはgit stashで一時退避します。git add . git commit -m "作業中の変更を保存" - 最新のベースブランチを取得
mainブランチなど、取り込み先の最新状態を取得します。git fetch origin main
2. rebase の実行
作業ブランチを最新状態に合わせる場合の例です。
git checkout feature
git rebase origin/main
これで feature ブランチのコミットが main の最新コミットの後に付け替えられます。
3. コンフリクトの解消
rebase 中に変更が競合した場合、Git が処理を一時停止します。
- コンフリクト箇所をエディタやツールで解消します。
- 修正が終わったらステージングします。
git add 修正したファイル rebaseを続行します。git rebase --continue
4. 中断またはやり直し
rebaseを中止して元の状態に戻す場合:git rebase --abort- 直前の手順をやり直す場合:
git rebase --edit-todo
5. push
rebase 後は履歴が書き換わるため、既にリモートに push 済みのブランチを更新する場合は --force-with-lease を使います。
git push --force-with-lease origin feature
--force-with-lease は、自分以外のコミットが追加されていないことを確認してから上書きするため、--force よりも安全です。
ポイント
- 作業前にブランチをバックアップしておくと安心
- コンフリクトが多い場合は一度に大きく rebase せず、こまめに行う
- チーム作業では
rebaseのタイミングやルールを共有しておく
注意点 & 安全策:ハッシュ変更・force push、共有ブランチへの影響
履歴が書き換わることを理解する
git rebase の最大の特徴は「履歴を書き換える」ことです。
このため、コミットのハッシュ値が変更され、既に他の人と共有しているブランチに対して行うと、履歴の不整合が発生します。結果として、他の開発者の作業を上書きしてしまったり、マージ不能な状態になることがあります。
force push のリスク
rebase 後にリモートへ push する場合、通常は --force-with-lease オプションを使用します。
git push --force-with-lease
このオプションは、自分が知らない間に追加された他人のコミットを保護しつつ強制 push するため、--force より安全です。それでも履歴が書き換わることに変わりはないため、共有ブランチでは慎重に扱う必要があります。
共有ブランチでは原則禁止
- main / master / develop などの共有ブランチでは原則
rebaseを使わない - 個人の作業ブランチやレビュー前のブランチなど、影響範囲が自分だけの場合に限定する
- チームで利用する場合は「いつ」「誰が」「どのブランチで」行うかを明確にする
コンフリクト発生時の混乱
Git に不慣れなメンバーが rebase 中にコンフリクト解消を誤ると、コミットの損失や作業の巻き戻しが発生することがあります。履歴の美しさよりも、安全性と作業継続性を優先すべき場面も多いです。
安全策まとめ
- 共有ブランチでは
mergeを使用する rebaseは自分の作業ブランチでのみ実行する- 作業前にバックアップブランチを作成する
- 強制 push は必ず
--force-with-leaseを使う - チームで運用ルールを明文化して周知する
補足リファレンス:より詳しくオプションや設定を知りたい方向け
git rebase は基本的な使い方だけでも十分便利ですが、オプションや設定を活用すると作業効率がさらに向上します。ここでは、より詳細に学びたい場合に役立つ情報源と主要オプションを紹介します。
代表的なオプション
--interactive/-i
対話的リベース。コミットの順序変更や統合、削除など履歴整理に使う。--onto
リベース先を任意のコミットやブランチに指定可能。複雑なブランチ構造を整理するときに役立つ。--abort
進行中のリベースを中止して元の状態に戻す。--continue
コンフリクト解消後にリベースを続行する。--skip
現在のコミットをスキップして次に進む。
Git設定で便利な項目
rebase.autoStashpull --rebase実行時に未コミット変更を自動でstash → 復元する。git config --global rebase.autoStash truepull.rebasegit pullのデフォルト挙動をmergeからrebaseに切り替える。git config --global pull.rebase true
公式ドキュメント
- Git公式ドキュメント(英語)
すべてのオプションや挙動の仕様を確認可能。 - Pro Git 日本語版(2.6章 Rebase)
図解付きで概念と実例を理解できる。 - GitHub Docs:About git rebase
GitHub利用時のベストプラクティスや注意点を含む。
高度なオプションは便利ですが、操作ミスのリスクも伴います。特に --onto や履歴操作系のオプションは、テスト用ブランチで動作を試してから本番作業に取り入れると安全です。
まとめ
git rebase は、履歴を直線的に整理し、見やすく保つための強力なコマンドです。merge と比べると履歴がすっきりしますが、その分、履歴を書き換えるリスクがあり、使い方を誤ると作業損失やチーム全体への影響を招く可能性があります。
安全に活用するためには以下を意識しましょう。
- 共有ブランチでは原則
mergeを使用する rebaseは自分専用の作業ブランチで行う- コンフリクト解消や
--force-with-leaseの使い方を理解する - 作業前にバックアップや別ブランチの作成で保険をかける
適切な場面で使えば、git rebase は履歴を整え、レビューや調査を効率化する心強い味方になります。
「履歴をきれいに保ちたい」ときはメリットとリスクを天秤にかけ、チームの運用ルールに沿って活用していきましょう。

コメント