git rebase -i でコミットをまとめる(備忘録)

## 初めに
コミットをまとめる作業が頻繁にあります。
コマンドを中々覚えられず、その都度調べたりしているので、備忘録としてまとめます。
参考にしたURLがあり、そちらがとても分かりやすかったです。ありがとうございます。

# git rebase -i HEAD~【数字】

数字の部分にはまとめたいコミットの数を指定します。
3コミットをまとめたい場合は以下のようにします。

~~~:ターミナル
$ git rebase -i HEAD~3
~~~

# エディタ修正

以下のようなエディタが起動します。

~~~:ターミナル
pick d196455 データ取得新規API作成
pick 968362c レビューコメント修正1
pick d196455 レビューコメント修正2

# Rebase 3c1cd16..d196455 onto 3c1cd16 (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 <commit> = like "squash", but discard this commit's log message
# 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
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to botto
~~~

i で INSERTモードに切り替えて、修正コミットの「pick」を「s」に変更・保存します。
「s」はsquashのsです。
:w  で保存
:q! でファイルから出る

~~~:ターミナル
pick d196455 データ取得新規API作成
s 968362c レビューコメント修正1    ⬅︎ 変更
s d196455 レビューコメント修正2    ⬅︎ 変更

# Rebase 3c1cd16..d196455 onto 3c1cd16 (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 <commit> = like "squash", but discard this commit's log message
# 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
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to botto
~~~

するとコミットメッセージを編集するためのエディタが開きます。

~~~:ターミナル
# This is a combination of 3 commits.
# This is the 1st commit message:

データ取得新規API作成

# This is the commit message #2:

レビューコメント修正1

# This is the commit message #3:

レビューコメント修正2

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Wed Dec 11 23:52:55 2019 +0900
#
# interactive rebase in progress; onto f53176d
# Last commands done (3 commands done):
#    squash 968362c リスト2を修正
#    squash d196455 リスト1を修正
# No commands remaining.
~~~

コミットメッセージは「リスト1、リスト2を作成」だけあればいいので、他の2つは削除します。

~~~:ターミナル
# This is a combination of 3 commits.
# This is the 1st commit message:

データ取得新規API作成

# This is the commit message #2:

　　　　　　　　　　　　　⬅︎ 削除

# This is the commit message #3:

　　　　　　　　　　　　　⬅︎ 削除

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Wed Dec 11 23:52:55 2019 +0900
#
# interactive rebase in progress; onto f53176d
# Last commands done (3 commands done):
#    squash 968362c リスト2を修正
#    squash d196455 リスト1を修正
# No commands remaining.
~~~

この変更を保存するとrebaseが完了です。以下のように表示されれば問題なくrebaseできています。
:w で保存
:q! でファイルから出る

~~~:ターミナル
Successfully rebased and updated refs/heads/create_list.
~~~

最後に、リモートにpushをします。ここで要注意なのが、rebaseをしたことでコミットのハッシュ値が変わっているので、pushができなくなっています。この場合、git push に-f オプションを付けて、強制的にpushすることができます。

~~~:ターミナル
git push -f
~~~

# 参考

ありがとうございます🙇‍♂️

https://riri1904.hatenablog.com/entry/2019/12/21/100000