はじめに
個人開発やチーム開発において、作業中のコミット履歴が「WIP」「typo修正」「動作確認」といった細かく雑多なコミットで埋め尽くされてしまうことはよくあります。
これらのコミットをそのままメインブランチにマージしてしまうと、後から「どのコミットで何が実装されたか」を追うことが極めて困難になります。
Gitの インタラクティブ・リベース(git rebase -i) を使用すると、マージやプルリクエストを作成する前に、コミットの統合(Squash)、メッセージの変更(Reword)、順序の入れ替えなどを自由に行うことができます。本記事では、このインタラクティブ・リベースの具体的なフローと活用コマンドを解説します。
1. インタラクティブ・リベースとは?
git rebase -i は、過去のコミット履歴を再編集するためのインタラクティブ(対話型)モードのコマンドです。
実行するとエディタが開き、コミットの一覧に対して「どのような操作を行うか」を指示するファイル(指示書)を編集し、保存することで一括適用します。
主な用途
- Squash(統合): 「typo修正」や「少し調整」のような細かなコミットを、1つの大きな機能追加コミットにまとめる。
- Reword(メッセージ編集): コミットメッセージの誤字を修正したり、より分かりやすい内容に変更する。
- Drop(削除): 不要になった一時的なコミットを履歴から消去する。
- Edit(分割や修正): 過去のコミットの時点でファイルを修正し直す。
2. 基本的な操作手順
それでは、実際にリベースを実行する手順を見ていきましょう。
ステップ1: リベース対象の範囲を指定する
現在のブランチの、過去3つのコミットを編集したい場合は以下を実行します。
git rebase -i HEAD~3
特定のブランチ(例: main)から分岐した後のコミットをすべて対象にする場合は、分岐元のブランチ名を指定することもできます。
git rebase -i main
ステップ2: 指示書(Todoリスト)の編集
コマンドを実行すると、ターミナルで設定しているテキストエディタ(VimやVS Codeなど)が開き、以下のような内容が表示されます。
pick a1b2c3d WIP: ログイン機能の実装開始
pick e5f6g7h typo修正
pick i9j0k1l ログイン画面のバリデーション追加
# Rebase a1b2c3d..i9j0k1l onto z9y8x7w
# ...
- 注意: コミットは上が古く、下が新しいものの順に並んでいます。
- 各行の先頭にある
pickという単語を書き換えることで、そのコミットをどう処理するかを指定します。
主なアクションコマンド
| コマンド | 短縮形 | 動作 |
|---|---|---|
| pick | p | そのままコミットを採用する(デフォルト) |
| reword | r | コミットメッセージを書き換える |
| edit | e | コミットを採用するが、処理を一時停止してファイルを再編集できる状態にする |
| squash | s | 1つ上の古いコミットに統合する(メッセージも合体する) |
| fixup | f | 1つ上の古いコミットに統合する(メッセージは破棄し、上のメッセージを維持する) |
| drop | d | コミットを削除する |
実際に編集した指示書の例
「typo修正」と「バリデーション追加」を最初のコミットに統合し、メッセージを新しく整理したい場合は以下のように書き換えます。
pick a1b2c3d WIP: ログイン機能の実装開始
f e5f6g7h
s i9j0k1l
e5f6g7hはfixup (f)にし、メッセージを破棄してa1b2c3dに統合します。i9j0k1lはsquash (s)にし、統合しつつメッセージの再編集プロンプトを開きます。
エディタを保存して閉じると、リベース処理が始まります。
ステップ3: コミットメッセージの最終編集
squash を指定した場合、次に「統合後の新しいコミットメッセージ」を入力するエディタが開きます。
# This is a combination of 2 commits.
# This is the 1st commit message:
WIP: ログイン機能の実装開始
# This is the commit message #2:
ログイン画面のバリデーション追加
これらを綺麗に整理して保存します。
feat: ログイン機能の実装とバリデーションの追加
- メールアドレスとパスワードの入力フォーム実装
- 入力エラー時の赤枠バリデーション表示を追加
保存して閉じると、リベースが完了し、3つあったコミットが綺麗な1つのコミットにまとまります。
3. リベース中のトラブル対処法
コンフリクト(競合)が発生した場合、リベースは一時停止します。
- 競合ファイルを修正する: ソースコードの衝突箇所を手動で修正します。
- ステージングに追加する:
git add <ファイル名>を実行します(コミットはしません)。 - リベースを続行する:
以下を実行すると、リベースが再開されます。
git rebase --continue
もしリベースの途中でパニックになり、最初からやり直したい場合は、以下のコマンドで安全にリベース前の状態に戻すことができます。
git rebase --abort
4. 運用の注意点(ゴールデンルール)
インタラクティブ・リベースは非常に強力ですが、以下の絶対ルールを守る必要があります。
警告すでに共有リポジトリ(GitHub等)の共有ブランチ(mainやdevelopなど)にプッシュされ、他の開発者が作業ベースにしているコミットに対して rebase を行ってはいけません。
履歴のハッシュ値が書き換わってしまうため、他のメンバーのリポジトリと整合性が取れなくなり、強制プッシュ(force push)による競合やコード消失の原因になります。
リベースを行うのは、**「自分が作成したローカルの作業ブランチ」「まだマージされていない自分のプルリクエスト用のブランチ」**だけに限定しましょう。
まとめ
git rebase -i をマスターすると、開発中は細かくコミットを打って作業を保存し、プルリクエストを作成する直前に「1つの綺麗なコミット」にまとめ直すという、美しく柔軟なGit運用が可能になります。ぜひ活用してみてください。
