コミットの順番を編集して、もっと見やすく! rebaseコマンドとは?
2つ目はrebaseコマンドです。-iオプションを使うことで、コミット履歴をインタラクティブに書き換えることができます。コミットの順番を入れ替えたり、まとめたり、削除したり、編集したりできます。前で説明したcommit --amendに比べてより幅広い範囲のコミットに対して処理を行うことができます。例えば、以下のような場面で使えます。
例:コミット同士を合わせたい
以下のようなログがあったとします。
% git log --oneline 5f5af18 (HEAD -> main) コメントの誤字を修正2 a3261df 計算方法の修正 1e192b3 コメントの誤字を修正 8737dee テストコードを追加 78ae336 メニューを実装
上から数えて3つ目に「コメントの誤字を修正」があり、上から数えて1つ目にも同じ内容のコミットがあります。後から「ここにも誤字があった」と気づいたような場合です。この2つのコミットは同じ内容なので合わせて1つにしてしまいたいところです。このような場合にrebaseを利用します。
% git rebase -i 8737dee
-iオプションとともに、操作の起点となるコミットハッシュを指定します。ポイントは、操作したいコミットのさらに1つ昔を指定します。今回であれば、「コメントの誤字を修正」コミットまで操作したいため、さらに1つ昔の「テストコードを追加」コミットのハッシュである8737deeを指定します。rebase -iコマンドを実行すると、以下のようにコミットを編集できるエディタが開きます。
pick 1e192b3 コメントの誤字を修正 pick a3261df 計算方法の修正 pick 5f5af18 コメントの誤字を修正2 # Rebase 8737dee..5f5af18 onto 8737dee (3 commands) # # Commands: # p, pick <commit> = use commit # r, reword <commit> = use commit, but edit the commit message # e, edit <commit> = use commit, but stop for amending # s, squash <commit> = use commit, but meld into previous commit # f, fixup [-C | -c] <commit> = like "squash" but keep only the previous # commit's log message, unless -C is used, in which case # keep only this commit's message; -c is same as -C but # opens the editor # x, exec <command> = run command (the rest of the line) using shell # b, break = stop here (continue rebase later with 'git rebase --continue') # d, drop <commit> = remove commit # l, label <label> = label current HEAD with a name # t, reset <label> = reset HEAD to a label # m, merge [-C <commit> | -c <commit>] <label> [# <oneline>] # create a merge commit using the original merge commit's
エディタ上部には修正対象となるコミットが並びます。上がより過去のコミット、下により現在に近いコミットが並びます。各行には左から、コマンド、コミットのハッシュ、コミットのメッセージの順に並んでいます。一番左のコマンドが、「そのコミットをどうするのか」を表しています。上記はエディタを開いた直後の状態です。初期状態ではすべてのコミットに対してpickが指定されています。エディタ下部の説明によると「use commit」となっており「そのままこのコミットを利用する」ということになります。
今回は、1e192b3 コメントの誤字を修正と5f5af18 コメントの誤字を修正2を合わせます。「コミットを並び替えて、合わせる」という順番で操作します。
まずは並び替えます。並び替えは、エディタ上でコピーペーストなどを利用して順番を変えます。以下、並び替えた状態です。
pick 1e192b3 コメントの誤字を修正 pick 5f5af18 コメントの誤字を修正2 pick a3261df 計算方法の修正
今回は、1e192b3 コメントの誤字を修正に5f5af18 コメントの誤字を修正2を合わせます。そのため、5f5af18 コメントの誤字を修正2のコマンドをsquashに変更します。
pick 1e192b3 コメントの誤字を修正 squash 5f5af18 コメントの誤字を修正2 pick a3261df 計算方法の修正
この状態で保存してエディタを閉じます。コンフリクトなどがなければ、以下のようにコミットメッセージの修正を行えるエディタが開きます。
# This is a combination of 2 commits. # This is the 1st commit message: コメントの誤字を修正 # This is the commit message #2: コメントの誤字を修正2 # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit.
2つのコミットを合わせようとしているため、2つのコミットのメッセージがそれぞれ表示されます。今回は「コメントの誤字を修正」にしたいので、「コメントの誤字を修正2」の方を削除して保存します。rebaseコマンドはこの名称の通り「baseを付け替えるコマンド」すなわち、「ブランチの分岐元を変えるコマンド」と捉えることができます。ブランチの分岐元を変えるため、ブランチを作ってから追加してきたコミット1つずつに変更が適応されていきます。結果として、複数回コンフリクトしたり、コミットメッセージ変更エディタが開いたり、ということがあります。1つずつ対応しましょう。
最後まで対応すると、以下のようにメッセージが表示されます。これで完了です。
% git rebase --continue [detached HEAD 1b2ad97] 計算方法の修正 1 file changed, 1 insertion(+) Successfully rebased and updated refs/heads/main.
コミットログを確認します。
% git log --oneline 1b2ad97 (HEAD -> main) 計算方法の修正 2941dda コメントの誤字を修正 8737dee テストコードを追加 78ae336 メニューを実装
以下、rebase実行前のログです。
5f5af18 (HEAD -> main) コメントの誤字を修正2 a3261df 計算方法の修正 1e192b3 コメントの誤字を修正 8737dee テストコードを追加 78ae336 メニューを実装
「コメントの誤字を修正」コミットが1つになり、「テストコードを追加」以降のコミットのコミットハッシュが変わっていることがわかります。
rebaseコマンドはとても便利なコマンドですが、慣れるまで時間がかかるコマンドだと思います。いきなり複雑なことをするのではなく、簡単なことからやってみて徐々に慣れていくのが良いでしょう。試したことがない方は是非やってみてください。心配な方は実行前にバックアップ用の別ブランチを作ってから行うことをオススメします。reflogやresetコマンドを使うことでGitの操作を戻すことも可能ですが、こちらも慣れや知識が必要ですので使う際は要注意となります。
