Git の履歴を書き換える | git rebase -i
git rebase -i コマンド
git rebase を -i フラグ付きで実行すると、インタラクティブ rebase セッションが開始される。インタラクティブ rebase は、すべてのコミットをそのまま新しいベースへ移動するのではなく、対象となる個々のコミットを変更できる。これを使うと、既存の一連のコミットを削除、分割、修正、整理して履歴を整えられる。これは git commit --amend コマンドの拡張版だといえる。
使い方
git rebase -i <base>
インタラクティブ rebase セッションを使って、現在のブランチを <base> の上へ rebase するコマンドである。このコマンドを実行するとエディタが開き、rebase 対象の各コミットに対するコマンドを入力できる。ここでのコマンドは、各コミットを新しい起点へどのように移動するかを指定する。また、エディタ上でコミットの順序を直接編集して並べ替えることもできる。
補足説明
インタラクティブ rebase を使うと、見た目上の履歴を自由に作り直して整えられる。この機能により、開発中に雑多なコミットが繰り返された履歴が残っていても、後から見直して構成できるため、開発者はかなりの自由度を得られる。
多くの開発者は、master ブランチへマージする前に機能ブランチをきれいに見せるためにインタラクティブ rebase を使う。インタラクティブ rebase を使うと、重要でないコミットを 1 つにまとめ、不要なコミットを削除し、その他を整理してから「公式」リポジトリへコミットできる。事情を知らない人には、この機能開発が全体としてよく計画されたコミット列として順調に進んだように見える。
使用例
以下の例は、非インタラクティブな git rebase の説明ページにあった例を、インタラクティブコマンドの場合に書き換えたものである。
# Start a new feature
git checkout -b new-feature master
# Edit files
git commit -a -m "Start developing a feature"
# Edit more files
git commit -a -m "Fix something from the previous commit"
# Add a commit directly to master
git checkout master
# Edit files
git commit -a -m "Fix security hole"
# Begin an interactive rebasing session
git checkout new-feature
git rebase -i master
最後のコマンドでエディタが開き、new-feature ブランチ上の 2 つのコミットが関連情報とともに表示される。
pick 32618c4 Start developing a feature
pick 62eed47 Fix something from the previous commit
各コミットの前にある pick コマンドは、rebase の動作を指定する任意のコマンドに変更できる。ここでは squash コマンドを使って 2 つのコミットを結合できる。
pick 32618c4 Start developing a feature
squash 62eed47 Fix something from the previous commit
保存してエディタを閉じると rebase が開始される。このとき、結合されたスナップショットに対するコミットメッセージを入力するため、別のエディタウィンドウが開く。コミットメッセージを入力すると rebase が完了し、git log でコミットが結合されたことを確認できる。
Git チュートリアル: git rebase -i の使用例
ここで、結合されたコミットは元のどちらのコミットとも異なる ID を使うこと、つまりこのコミットは実際には新しいコミットであることを覚えておこう。
最後に、fast-forward マージを実行して、整理した機能ブランチを master ブランチへ統合する。
git checkout master
git merge new-feature
インタラクティブ rebase の威力は、書き換えられた master ブランチの履歴に現れる。ID が 62eed47 のコミットは、不要なものとして履歴から完全に姿を消している。事情を知らない人には、new-feature の開発者が有能で、必要最小限の整ったコミットだけで開発を完了したように見える。このように rebase は、プロジェクト履歴を整理し、わかりやすくする機能である。