🎃

【git】rebase -i squashを使ってコミットをまとめる方法メモ

2022/02/05に公開

はじめに

pushする前の細かいcommitをrebaseでまとめる際、vimの操作含め、毎回ググっていたので、手順をまとめてみました。

この記事は主に以下サイトのsquashの部分のみの抜粋に自分のメモを追加した内容になります。
こちらのサイトではrebaseの他の使い方や、図も入っていてわかりやすく説明されてます。
こちらも参考にしてみてください。
http://tkengo.github.io/blog/2013/05/16/git-rebase-reference/

この記事がどなたかの参考になれば幸いです。
また、もし間違い等ございましたらご指摘いただけるとありがたいです。

rebaseについて

rebaseでは以下が出来ます。今回はsquash使ったまとめ方のみの記事になります。

  • コミットメッセージを編集する
  • コミットをまとめる
  • コミットを分割する
  • コミットの順番を移動させる
  • コミットを削除する

squash

rebase -i でコミットをまとめる際、
編集画面でまとめたいコミットを指定するkeyword(?)みたいなもの。
squashが指定されたコミットはその1つ前のコミットとまとめられます。

環境

MacOS 12.1
zsh

手順

  1. terminalでコマンド使って、まとめたいcommitをvimで表示する。
  2. 表示されたcommit一覧で、まとめたいcommitを選択
  3. commitメッセージを編集
  4. vimを保存して終了
  5. (おまけ) rebaseをミスったときにやめて元に戻す方法
  6. (おまけ) 今回使うVimの基本操作

以下手順の詳細です。

1. terminalでrebaseコマンド使って、まとめたいcommitをvimで表示する。(誤解していたので修正)

以下が構文

git rebase -i <commit>

<commit>には'commitID~数字'で編集したいcommitを指定する。
このcommitの指定方法がちょっとややこしいです。

例として以下のようなcommitがあったとします。
HEADはcommit_id_5とします。

commit_id_5 commitメッセージ(2022/03/20)
commit_id_4  commitメッセージ(2022/03/19)
commit_id_3  commitメッセージ(2022/03/18)
commit_id_2  commitメッセージ(2022/03/17)
commit_id_1  commitメッセージ(2022/03/16)

rebaseの編集画面で編集したいcommitの指定例

HEADから1つ遡ったcommitまで表示する場合
commitをHEADから指定する場合はHEAD~(数字)でcommitIDを範囲指定する。
今回はHEAD自身含めるとコミットは2つなので指定する数字は2になります。
※このHEADから指定する方法だけ覚えておけばいいかも。

コマンド
git rebase -i HEAD~2

すると、以下のようなvimでrebaseを編集する画面(ribase指示書と呼ぶ?)が表示されます。
※HEADはcommit_id_5だとします。

vimで表示されるrebaseの編集画面
pick commit_id_4 commitメッセージ(2022/03/19)
pick commit_id_5 commitメッセージ(2022/03/20)	

# (以下には指示書の書き方説明とかが書いてある。)
# Rebase cce19c9..aebf22c onto b8e5722
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
# ...	

上と同じくcommit_id_4とcommit_id_5をrebaseするが、HEADを使わないでcommit指定する場合
HEADを使わずに、過去のcommitIDを使ってrebaseするcommit指定する場合は、rebaseしたいcommitの一つ前のcommitを指定します。
この時、vimのrebase -iの編集画面では指定されたcommitより新しいcommitがすべて表示されます。
~(数字)で指定していない場合はコマンドで指定したcommitは表示されません。
rebaseで指定するのはcommit_id_3のみになります。

コマンド
git rebase -i commit_id_3
vimで表示されるrebaseの編集画面
pick commit_id_4  commitメッセージ(2022/03/19)
pick commit_id_5  commitメッセージ(2022/03/20)

# 省略	

上の例で、commit_id_3も含めてrebaseの編集画面に表示したい場合
指定するcommitを編集画面でも表示したい場合は、commitID~(数字)として、範囲指定する必要があります。commitID~(数字)での範囲指定は、自分を含め自分よりも古いcommitを数字で遡って指定できます。
指定しているcommitIDのみ表示したいのであれば、範囲指定は~1になります。

コマンド
git rebase -i commit_id_3~1
vimで表示されるrebaseの編集画面
pick commit_id_3  commitメッセージ(2022/03/18)	
pick commit_id_4  commitメッセージ(2022/03/19)
pick commit_id_5  commitメッセージ(2022/03/20)	
# ~~省略~~

上の例で、commit_id_2(commit_id_3の一つ前のcommit)もrebase編集画面で表示したい場合
※こういう指定はあまり使わないと思いますが、ここが誤解していたポイントなので記述します
指定したcommitIDよりも古いcommitも含めて表示したいのであれば、~(数字)で2以上の数字を指定します。

コマンド
git rebase -i commit_id_3~2

上記のように書くと、commit_id_3自身とその一つ前のcommit(今回はcommit_id_2)が指定されます。
編集画面に表示されるのは、この2つのcommitと指定したcommitIDの後から一番新しいcommitIDまで(今回はcommit_id_4とcommit_id_5)が表示されます。

vimで表示されるrebaseの編集画面
pick commit_id_2 commitメッセージ(2022/03/17)
pick commit_id_3  commitメッセージ(2022/03/18)	
pick commit_id_4  commitメッセージ(2022/03/19)
pick commit_id_5 commitメッセージ(2022/03/20)	

2. 表示されたcommit一覧で、まとめたいcommitを選択

まとめたいコミットの左側のpick(何もしないという意味)を以下のように、squash(もしくはs)に変更する。

pick cce19c9 通信用のクラスの実装とテストの追加
squash 70b3379 メソッド名のタイポ修正
pick aebf22c テストが落ちてたので修正

squashを入れると一つ前のコミットとまとめられ、1つになる。
編集が終わったら、:wqで保存して終了。次へ進む。

3. commitメッセージを編集

以下のような画面になるので、編集してcommitメッセージを書く
(#はコメントアウト)
選択されているコミットのメッセージが書いてあるので、
コミットメッセージを編集する。
編集前

# This is a combination of 2 commits.
# The first commit's message is:

通信用のクラスの実装とテストの追加

# This is the 2nd commit message:

メソッド名のタイポ修正

# Please enter the commit message for your changes. Lines starting
...

編集後

通信用のクラスの実装とテストの追加

# Please enter the commit message for your changes. Lines starting
...

4. vimを保存して終了

編集終わったら、ノーマルモードに戻して、
:wqで保存してvim終了。

5. rebaseを中止して変更を元に戻す(rebaseでミスってやめたい時)

  • rebaseの編集画面(vim)は保存せずに:qで閉じる。
  • この時commitがrebaseされたように表示されるが、
    慌てずに、
git rebase --abort

これでrebaseを中断して元に戻る。

6. Vimの基本操作

今回特に使ったもの

  • 編集する(INSERTモード )にする
    aかi
  • 編集モードからノーマルモードに戻る
    esc
  • 1文字削除
    d
  • 1行削除
    dd
  • 保存しないで終了
    :q
  • 保存して終了
    :wq

他、参考にさせていただいたサイト

https://www.karakaram.com/git-rebase-i-usage/#abort

https://zenn.dev/ikuraikura/articles/12efefc5d69ad15c2eb1

https://qiita.com/tomoya1993/items/7b7dfffd3553e55601ef

git rebaseでのcommitの指定方法
https://qiita.com/tsuuuuu_san/items/f708a9f7ea8ab8eb6945

図が載っているのでわかりやすいです。
https://backlog.com/ja/git-tutorial/stepup/32/

https://www-creators.com/archives/2850

git commit --amend、rebaseを使ったコミットメッセージの変更方法
https://www.granfairs.com/blog/staff/git-commit-fix

最後に

読んでいただきありがとうございました!

Discussion