Git を使って開発を進めていると、細かいコミットが積み重なって履歴が見づらくなったり、後からコミットメッセージを修正したくなったりすることがあります。そんなときに便利なのが git rebase -i(インタラクティブリベース)です。ちゃんと計画どおりに実装を進めていたように履歴を構成し直すことができます!
1. リベースとは?
リベース(rebase) とは、Gitの履歴を整理するための機能 で、特定のブランチの変更を別のブランチに適用し直すために使われます。一般的には、メインブランチの変更を開発ブランチに適用したり、複数のブランチを統合する際に使用されます。
当記事では、そのようなブランチ間の調整方法ではなく、自分の作業ブランチ内でコミット履歴を整理する用途 にリベースを活用する方法について説明します。
例えば、以下のような場合にリベースを使うと便利です。
- コミットメッセージの誤字・脱字を修正したい(よくある)
- 複数の小さなコミットをまとめたい(粒度が大きいタスクだとよくある)
- コミットの順番を整理したい
- 不要なコミットを削除したい(よくある)
- 改修内容自体を再編集したい
分かりやすく整理された状態 にしてからプルリクを送信すると、レビュアーの負担を減らすことができます。
2. git rebase -i を実行すると何が起きるのか?
git rebase -i コマンドを実行すると、ターミナル上に “編集用の一覧” が表示されます。
この画面は、実際にリベースが始まる「前」のステップです。
イメージ:コマンドが「バッチファイルの下書き」を開く
-
rebase -iを実行 → 「どのように履歴を書き換えるか?」の編集画面が表示される - 編集を保存・閉じた時点で → 実際のリベース処理がスタートする
この編集画面では、対象コミットに対して pick / reword / edit などのコマンドを指定できます。行の順番を変えたり、不要な行を削除したりすることで、履歴の整理方法を自由に設計できます。
pick abc123 初期実装
reword def456 メッセージ修正
fixup ghi789 不要な修正を統合
上記のように編集し保存すれば、そのとおりに Git が履歴を書き換えていきます。
この時点ではまだ履歴は変わっておらず、編集画面で指定した指示通りに処理が走るのは保存後です。上記の例だと reword def456 メッセージ修正 のタイミングで手動での保存を求められます。
ポイント
- 編集画面は 「リベースの手順書」 のようなもの
- 保存・終了すると、Git がその順番に従って履歴再構築を開始する
具体的には、以下のようなことが可能です:
- コミットメッセージを修正(
reword) - コミットの順番を変更
- コミットを統合(
squash/fixup) - 不要なコミットを削除(
drop) - 過去のコミットの改修内容を修正(
edit)
これにより、履歴をすっきり整理し、分かりやすい状態にすることができます。
3. git rebase -i の基本操作
まず、履歴を編集したい範囲を指定して git rebase -i を実行します。
git rebase -i HEAD~5
HEAD~5 は 「現在のHEADから5つ前までのコミット」 を対象とする、という意味です。
直近5つのコミットが一覧表示され、編集できるようになります。
pick abc123 コミット1
pick def456 コミット2
pick ghi789 コミット3
pick jkl012 コミット4
pick mno345 コミット5
行頭のコマンドを書き換えることで、バッチのイメージで順番にリベース処理(コミット編集)が行われます。
※この画面はviモードで開きます。操作がよく分からない場合は escを押してから q! + enter で強制的に抜けることができます。詳しくは後述します。
Successfully rebased and updated refs/heads/main.
リベースが完了すると、このようなメッセージが表示されます。
4. コミットメッセージを修正する(reword)
過去のコミットメッセージを修正 したい場合は、対象の pick を reword に変更します。
pick abc123 コミット1
pick def456 コミット2
reword ghi789 修正が必要なコミット
pick jkl012 コミット4
pick mno345 コミット5
reword に変更してエディターを保存・閉じると、対象のコミットのメッセージ編集画面が表示されるので、そこで内容を自由に書き換えられます。
5. コミットの順番を変更する
git rebase -i のリストで 行の順番を入れ替えるだけ で、コミットの順序を変更できます。
pick abc123 コミット1
pick ghi789 コミット3 ← 3番目を2番目に移動
pick def456 コミット2
pick jkl012 コミット4
pick mno345 コミット5
➡ この状態でリベースを実行すると、新しい順番で履歴が整理されます。
順序に依存するコミットの場合はエラーになりますが、コードを書いている本人が分かることと思うので、うまくいかない時はabort(※後述)して検討し直してください。
6. コミットを統合する(squash / fixup)
複数のコミットを統合したい場合は、squash または fixup を使います。
「3番目 (ghi789) を基準に、5番目 (mno345) を統合する」
pick abc123 コミット1
pick def456 コミット2
pick ghi789 コミット3 ← これを基準にする
fixup mno345 コミット5 ← 3番目に統合
pick jkl012 コミット4
squash / fixup の違い
| 方法 | 動作 |
|---|---|
squash |
直前のコミットに統合し、メッセージも編集可能 |
fixup |
直前のコミットに統合し、メッセージはそのまま適用 |
7. 不要なコミットを削除する(drop)
履歴から完全に削除したいコミットがある場合は、drop を使います。
pick abc123 コミット1
pick def456 コミット2
drop ghi789 コミット3 ← これを削除
pick jkl012 コミット4
pick mno345 コミット5
該当行を削除しても同様に動作します。
pick abc123 コミット1
pick def456 コミット2
pick jkl012 コミット4
pick mno345 コミット5
8. 過去のコミットの内容を修正する(edit)
改修内容自体を変更 したい場合は、対象の pick を edit に変更します。
pick abc123 コミット1
pick def456 コミット2
edit ghi789 修正が必要なコミット
pick jkl012 コミット4
pick mno345 コミット5
この状態で git rebase -i を開始すると、Git は ghi789 のコミットで一時停止します。
その後、修正を加えて再コミットし、リベースを続行します。
# ファイルを編集する
vi 修正したいファイル # エディタは任意(VSCodeなどでもOK)
# ステージング
git add 修正したいファイル
# コミットを上書き
git commit --amend
# リベースを続行
git rebase --continue
コミット日時を変更したい場合
内容を変更せずに日時だけを修正したい場合は、以下のように --date オプションを使います。
# メッセージ・内容をそのままにして日時だけを変更
GIT_COMMITTER_DATE="2025-03-20T07:00:00" \
git commit --amend --no-edit --date "2025-03-20T07:00:00"
-
--no-edit: メッセージを変更せずに適用 - ISO 8601 形式(例:
2025-03-20T07:00:00)で指定 - 内容が変わっていない場合でも
--allow-emptyを付ければコミット可能
9. 履歴編集後の push
リベースによって履歴が書き換えられた場合、リモートに既に push していると通常の push ではエラーになります。
履歴を書き換えたあとは、リモートリポジトリに強制的に反映させるために、git push --force を使います。
git push --force
※強制プッシュは他の開発者に影響を与える可能性があるため、共有ブランチでは使用前に確認しましょう。
補足:コミット日時を編集する
git commit --amend に --date オプションを追加すると、コミット日時を変更することもできます。
git commit --amend --no-edit --date "2025-03-20T07:00:00"
-
--no-editを使えばメッセージはそのままで、日時だけを変更可能 - ISO 8601形式の日時で指定(例:2025年3月20日 午前7時)
これは、履歴の見た目を整えるために有効なテクニックです。
10. リベースを取り消す方法
リベース中に「やっぱりやめたい!」と思った場合は、以下を実行すると元の状態に戻ります。
git rebase --abort
.git/rebase-apply directory removed. Rebase aborted.
11. リベース完了後に元に戻す(git reflog + git reset --hard)
リベース完了後に「やっぱり戻したい!」場合は、git reflog と git reset --hard を使います。
git reflog
git reflog は、Git が記録している操作履歴を参照できるコマンドで、 「どの状態からどこに移動したか」 の履歴を一覧で確認できます。
HEAD@{3}: rebase (start): checkout HEAD~5
git reset --hard HEAD@{3}
リベース前の状態に戻ります。
12. インタラクティブリベースでの編集には vi の基本操作が必要
git rebase -i を使う際には、Git がデフォルトのエディタとして vi を使用します。多少分かる人向けに基本的な操作方法を列挙します。
vi の基本操作
-
編集モードに入る:
i(インサートモード) -
1行切り取る(削除):
dd -
切り取った行を貼り付ける:
p(カーソルの後に貼り付け)またはP(カーソルの前に貼り付け) -
操作を元に戻す:
u -
変更を確定して終了する:
ESC→:wq→ENTER -
変更を破棄して終了する:
ESC→:q!→ENTER
viは難しい???
vi に慣れない場合は、一般的なスクリーンエディタである nano に変更することもできます。
git config --global core.editor nano
これで、インタラクティブリベース時に nano を使うように設定できます。
13. トラブルシューティング早見表
| 現象・エラー | 対処法 |
|---|---|
vi から抜けられない |
ESC → :wq → ENTER(保存して終了)ESC → :q! → ENTER(保存せず終了) |
| リベース中に「Conflict」が出る |
git status で対象確認 → 該当ファイルを修正 → git add → git rebase --continue
|
| リベース中にやり直したい | git rebase --abort |
| リベース後に戻したくなった |
git reflog → git reset --hard HEAD@{n} で復元 |
rebase --continue で進まない |
git add で変更をステージ → 再度 git rebase --continue
|
| 編集中に意図しないファイルを変更してしまった |
git restore や git reset で取り消す(状況による) |
補足:操作を誤ったときの鉄則
- 慌てずに
git statusで状況確認 - まず
git logやgit reflogで履歴を確認 - 最悪の場合でも
reflogからほぼ必ず復元可能
14. まとめ
git rebase -i でできること
- コミットメッセージを修正(
reword) - 過去のコミットの内容を修正(
edit) - 不要なコミットを削除(
drop) - コミットを統合(
squash/fixup) - コミットの順番を変更
- コミット日時を変更(
--dateオプション)
vi の基本操作も理解しておくと便利
-
viを使いこなせるとスムーズにリベースできる -
nanoをエディタとして設定することも可能
git rebase -i は、Git 履歴を綺麗に整え、レビューしやすい形にするための強力なツールです。コミットメッセージの修正や統合、不要な履歴の削除まで、細かく制御できます。
インタラクティブリベースを使いこなして、誰にとっても読みやすく、レビューしやすい Git 履歴を目指しましょう!