Git リベース
コミット履歴を整理し、クリーンな直線的履歴を維持するための Git 操作
Git リベースとは
git rebase は、ブランチの基点 (ベース) を別のコミットに移動し、コミット履歴を直線的に書き換える操作である。マージコミットが発生しないため、履歴が読みやすくなる。
Git 本体が書き始められたのは 2005 年 4 月だが、git rebase はその時点では存在しない。同年 6 月に git-rebase-script という名前で追加され (現在のコマンド名になったのは同年 9 月のツール一斉改名以降)、後から入った道具である。「履歴を書き換える」という性質上、使い方を誤ると深刻な問題を引き起こす。Git の中で最も強力かつ危険なコマンドの 1 つだ。
マージとリベースの違い
マージとリベースの違いを図で示す。
# マージの場合: マージコミットが作られ、分岐の履歴が残る
main: A---B---C-------M
\ /
feature: D---E---F
# リベースの場合: コミットが再適用され、直線的な履歴になる
main: A---B---C---D'---E'---F'
リベースでは D, E, F のコミットが「新しいコミット」(D', E', F') として再作成される。コミットハッシュが変わる点が重要だ。内容は同じでも、Git 上は別のコミットとして扱われる。
マージとリベースの使い分け
マージとリベースの使い分けを以下にまとめる。
| 観点 | リベース | マージ |
|---|---|---|
| 履歴の見た目 | 直線的でクリーン | 分岐とマージの履歴が残る |
| コンフリクト解決 | コミットごとに 1 つずつ解決 | まとめて 1 回で解決 |
| コミットハッシュ | 変わる (履歴の書き換え) | 変わらない |
| 安全性 | プッシュ済みコミットには危険 | 常に安全 |
| 適するケース | ローカルの未プッシュコミット | 共有ブランチへの統合 |
git bisect | 直線的で二分探索しやすい | マージコミットが邪魔になることがある |
チームによって方針が異なる。1 つの変更を 1 コミットに整えてから取り込む運用 (リベース + スカッシュ) を採るチームもあれば、OSS プロジェクトのようにマージコミットを残して貢献の経緯を履歴に保存する文化もある。履歴を「作業の記録」と見るか「レビュー可能な変更の列」と見るかの違いで、どちらかが一方的に正しいわけではない。
インタラクティブリベース
git rebase -i は、リベースの真価を発揮する機能だ。コミットの統合 (squash)、分割、メッセージの修正、順序の入れ替え、削除が自由にできる。
git rebase -i HEAD~5
# エディタが開き、直近 5 コミットの操作を選択できる
pick a1b2c3d ユーザー認証の基盤実装
squash d4e5f6a WIP: ログイン画面
squash 7a8b9c0 fix typo
reword 1d2e3f4 テスト追加
drop 5a6b7c8 デバッグ用 console.log
| コマンド | 動作 |
|---|---|
pick | コミットをそのまま使う |
squash | 前のコミットに統合 (メッセージを編集) |
fixup | 前のコミットに統合 (メッセージは破棄) |
reword | コミットメッセージだけ変更 |
edit | コミットを修正 (ファイル変更も可) |
drop | コミットを削除 |
プルリクエスト前に「WIP」「fix typo」「debug」のようなコミットを整理し、レビュアーが読みやすい履歴にするのが典型的な使い方だ。
黄金ルール - プッシュ済みコミットをリベースしない
リベースの最も重要なルールは、他の開発者と共有済みのコミットをリベースしないことだ。
リベースはコミットハッシュを変更する。他の開発者がそのコミットを基に作業している場合、リベース後に git push --force すると、他の開発者のローカルリポジトリと履歴が不整合になる。最悪の場合、他の開発者の作業が消失する。
# ❌ 絶対にやってはいけない
git rebase main # 共有ブランチのコミットを書き換え
git push --force # 強制プッシュで他の開発者の履歴を破壊
# ✅ 安全な代替
git merge main # マージなら履歴を書き換えない
git push
例外として、自分だけが使っているフィーチャーブランチであれば、git push --force-with-lease (他の人がプッシュしていないことを確認してから強制プッシュ) を使ってリベース結果をプッシュできる。
rebase --onto による高度な操作
--onto オプションを使うと、ブランチの一部のコミットだけを別のブランチに移植できる。
# feature ブランチの途中から分岐した sub-feature を main に直接移植
git rebase --onto main feature sub-feature
これは「feature ブランチがまだマージされていないが、sub-feature の変更だけ先に main に入れたい」というケースで使う。Cherry-pick で 1 コミットずつ拾うより効率的だ。
コンフリクト解決のコツ
リベース中のコンフリクトはコミットごとに発生する。10 コミットをリベースすると、最悪 10 回コンフリクトを解決する必要がある。
# コンフリクト発生時
git rebase main
# CONFLICT: 手動で解決
git add .
git rebase --continue # 次のコミットに進む
# リベースを中断して元に戻す
git rebase --abort
コンフリクトが多発する場合は、git rerere (Reuse Recorded Resolution) を有効にしておくと、一度解決したコンフリクトパターンを Git が記憶し、次回以降は自動解決してくれる。
git config --global rerere.enabled true
チームでの運用パターン
リベース + スカッシュマージ
GitHub の「Squash and merge」ボタンがこのパターン。フィーチャーブランチの全コミットを 1 つにまとめて main にマージする。main の履歴が 1 機能 = 1 コミットになり、非常にクリーンだ。ただし、個々のコミットの粒度が失われるトレードオフがある。
リベース + 通常マージ
フィーチャーブランチを main にリベースしてからマージする。コミットの粒度を保ちつつ、直線的な履歴を維持できる。ただし、開発者全員がリベースの操作に慣れている必要がある。
詳しくは関連書籍を参照。
この記事は役に立ちましたか?
関連用語
Git
分散型バージョン管理システムで、ソースコードの変更履歴を管理する
フィーチャーブランチとは - 機能ごとに独立したブランチで開発しマージする Git ワークフロー
機能ごとに独立したブランチを作成し、完成後にメインブランチにマージする Git ワークフロー
コードレビュー
他の開発者がコードを検査し、品質向上と知識共有を行うプラクティス
トランクベース開発
全開発者が 1 つのメインブランチに頻繁にコミットし、長寿命ブランチを避ける開発手法
Conventional Commits とは - コミットメッセージ規約の書き方と導入手順
Conventional Commits はコミットメッセージに feat/fix 等の型を付与する規約。CHANGELOG 自動生成やセマンティックバージョニングとの連携方法を実例で解説
Apache Kafka
大規模なリアルタイムデータストリーミングのための分散メッセージングプラットフォーム
関連する記事
技術書の読書ログを GitHub で管理する - エンジニアらしい記録法
技術書の読書記録を GitHub リポジトリで管理する方法を紹介します。Markdown で読書ノートを書き、コミット履歴で読書の軌跡を残す、エンジニアならではの読書ログ術です。
「あとで読む」ブックマークが 100 件を超えたら本を買え
ブラウザのブックマークに技術記事を溜め込んでいませんか。断片的な記事を 100 件読むより、同じテーマの本を 1 冊読む方が効率的な理由を解説します。
Git / GitHub 本ガイド - マンガ / GUI / 仕組み理解の 3 つの入口で選ぶ
Git と GitHub を学ぶ本の選び方を「入口の違い」で整理。マンガで概念を掴む本、GUI から入る本、仕組みを腹落ちさせる本、チーム開発の作法を学ぶ本、手元に置くリファレンスまで、2026 年 8 月時点の定番書で独学ルートを解説します。