git rebase -i
(インタラクティブモード)を利用すると、コミット履歴をきれいに整理できます。例えば、複数のコミットをまとめたり、コミットの順序を変更したり、過去のコミットメッセージを変更したりすることができます。
この記事ではgit rebase -i
で複数のコミットをまとめる方法についてわかりやすく解説します。
git rebase -iで複数のコミットをまとめる方法
まず、次のようなコミット履歴があるとします。
$ git log --oneline --reverse
...(略)
220e1ab commit A
5335e3d commit B
df58e03 commit C
2810a5a (HEAD -> main) commit D
今回は、git rebase -i
で「commit A
とcommit B
」及び「commit C
とcommit D
」のコミットをそれぞれまとめてみましょう。
手順を以下に示します。
複数のコミットをまとめる手順
git rebase -i
コマンドを実行する- テキストエディタでコミットをまとめる
- コミットメッセージを修正する
では上記の手順について順番に説明します。
git rebase -iコマンドを実行する
git rebase -i
(または、git rebase --interactive
)コマンドを実行します。
git rebase -i HEAD~~~~
#以下のコマンドでも可能
git rebase --interactive HEAD~~~~
git rebase -i HEAD~4
git rebase --interactive HEAD~4
上記のコマンドはHEAD
から4つ分のコミットを対象にリベースを開始するコマンドです。
テキストエディタでコミットをまとめる
git rebase -i
コマンドを実行すると、するとテキストエディタ(たいていvim)が開き、HEAD
から4つ分のコミットが表示されます。
pick 220e1ab commit A
pick 5335e3d commit B
pick df58e03 commit C
pick 2810a5a commit D
# Rebase df00432..2810a5a onto df00432 (4 commands)
(以下略)
今回は、「commit A
とcommit B
」及び「commit C
とcommit D
」のコミットをまとめたいので、以下に示すように、統合先のコミット(残したいコミット)の pick
はそのままにして、統合によって消したいコミットの pick
を s
または squash
に変更します(今回はs
に変更しています)。なお、文字を変更する際には、まずiキーを押してインサートモードに切り替えます。インサートモードでpick
をs
に変更したら escキーでインサートモードを終了し、:wqを入力した後、Enterキーを押してテキストエディタを閉じます。
pick 220e1ab commit A
s 5335e3d commit B
pick df58e03 commit C
s 2810a5a commit D
# Rebase df00432..2810a5a onto df00432 (4 commands)
(以下略)
コミットメッセージを修正する
先ほどの手順でEnterキーを押すと、以下に示すように、コミットメッセージを編集するテキストエディタが開きます。
# This is a combination of 2 commits.
# This is the 1st commit message:
commit A
# This is the commit message #2:
commit B
# Please enter the commit message for your changes. Lines starting
(以下略)
iキーを押してインサートモードに切り替え、必要に応じて、コミットメッセージを修正しましょう。今回は、以下に示すように残したいコミットのコミットメッセージをcommit A
からcommit A and commit B
に変更しました。
# This is a combination of 2 commits.
# This is the 1st commit message:
commit A and commit B
# This is the commit message #2:
# ここを消した!!
# Please enter the commit message for your changes. Lines starting
(以下略)
コミットメッセージの修正が終わったら、escキーでインサートモードを終了し、:wqを入力した後、Enterキーを押しましょう。
Enterキーを押すと、再度コミットメッセージを編集するテキストエディタが開きます。
「commit A
とcommit B
」及び「commit C
とcommit D
」のコミットをまとめているので、コミットメッセージを修正するテキストエディタが2回開きます。「commit A
とcommit B
」のみのコミットをまとめた場合、コミットメッセージを修正するテキストエディタは1回しか開きません。
# This is a combination of 2 commits.
# This is the 1st commit message:
commit C
# This is the commit message #2:
commit D
# Please enter the commit message for your changes. Lines starting
(以下略)
同様に、コミットメッセージを修正します。今回は、以下に示すように残したいコミットのコミットメッセージをcommit C
からcommit C and commit D
に変更しました。
# This is a combination of 2 commits.
# This is the 1st commit message:
commit C and commit D
# This is the commit message #2:
# ここを消した!!
# Please enter the commit message for your changes. Lines starting
(以下略)
これで「commit A
とcommit B
」及び「commit C
とcommit D
」のコミットをまとめることができました。
では次に、git log
コマンドを用いて、実際にコミットがまとまっているかを確認してみましょう。
git logコマンドでコミットがまとまっているかを確認する
git log
コマンドを実行してコミットがまとまっているかを確認してみましょう。
$ git log --oneline --reverse
...(略)
b6da499 commit A and commit B # ← コミットのハッシュ値(b6da499...)は新たな値が割り振られている
3260cb9 (HEAD -> main) commit C and commit D # ← コミットのハッシュ値(3260cb9...)は新たな値が割り振られている
$ git log --reverse -2
commit b6da4997d6b75fe769ad176146c45718bd25be05
Author: user01 <user01@example.com>
Date: Thu Oct 24 16:30:55 2024 +0900 # ← コミットの変更日時はpickのほう(各squashの1つ前のコミットのほう)になる
commit A and commit B
commit 3260cb929f29f723b5ad79e84a01f1690ed87e8b (HEAD -> main)
Author: user01 <user01@example.com>
Date: Thu Oct 24 16:31:12 2024 +0900 # ← コミットの変更日時はpickのほう(各squashの1つ前のコミットのほう)になる
commit C and commit D
上記コマンドの実行結果を見ると、コミットがまとまっていることが分かります。なお、コミットのハッシュ値は新たな値が割り振られます。また、コミットの変更日時はpick
のほう(各squash
の1つ前のコミットのほう)になります。
本記事のまとめ
この記事ではgit rebase -i
で複数のコミットをまとめる方法について、以下の内容を説明しました。
git rebase -i
コマンドの実行方法git rebase -i HEAD~n
コマンドで、HEADからnつ分のコミットを対象にリベースを開始します。
- 複数のコミットをまとめる方法
pick
をs
またはsquash
に変更することで、複数のコミットを1つにまとめることができます。
- コミットメッセージの修正
- 統合後のコミットメッセージを編集して、わかりやすい内容に更新できます。
git log
コマンドでの確認git log --oneline
コマンドで、コミットが正常にまとめられているかを確認します。コミットをまとめると、新しいコミットハッシュ値が割り振られ、変更日時はpickのほうの日時が反映されます。
お読み頂きありがとうございました。