commitをまとめる方法

Gitを使っていると、修正を後で戻したりするために細かくコミットをすることが大いにあるが
それはそれとして、レビューの後はコミットを1つにまとめておきたい…

ということが往々にしてある。

その時のやり方をまとめておこうと思います。

例として、下記のように複数のコミットを用意した。

![image (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565426/51a8328f-7aaf-0556-8f81-e9d3eef4ba0f.png)

このコミットをまずまとめてみます。

### 1. どこまでのコミットを1つにまとめるか？

https://software.small-desk.com/development/2022/04/18/git-howto-mergecommitsintoone/

ターミナルから実行する場合は、git lolaのエイリアスを入れたほうがわかりやすくなりそうです。
SourceTreeなどであれば、ツリー上に履歴を見られるのでわかりやすいですが
ターミナルで見るにはgit lolaなどツリー上に見るコマンドを実行した方が分かりやすいです。

https://qiita.com/514daisuke/items/b2e4580f8b12f6762568

https://shon-blo.hatenablog.com/entry/2018/03/15/215137#git%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E8%BF%BD%E5%8A%A0%E3%82%A8%E3%82%A4%E3%83%AA%E3%82%A2%E3%82%B9

まずまとめるコミットIDを探して指定します。
念のため、git lolaの設定を行い、ターミナル上で視覚的にコミットログを見られるようにしておきます。

```
〇〇〇@DESKTOP-AVCHKHA MINGW64 /d/Git/git/MakingManual/src (develop)
$ git config --global alias.lola "log --graph --decorate --pretty=oneline --abbrev-commit --all"

〇〇〇@DESKTOP-AVCHKHA MINGW64 /d/Git/git/MakingManual/src (develop)
$ git lola
* 1f97483 (HEAD -> develop) test6 テスト.txtの内容を修正
* 7035988 test5 テスト.txtの名前を修正
* 2703134 test4 テスト.txt修正
* abb5a5b test3 テスト.txt修正
* feda558 test2 テスト.txt修正
* 0a7829e test1 テストクラス追加
* 7ba88b5 (origin/master) GitHub
* 53707c2 プッシュ
* e2bf30d (master) Merge remote-tracking branch 'origin/master'
|\
| * 9cc1aed Revert "AAA"
* | 18f9c5a Revert "AAA"
|/
* 538b2bb AAA
* f399c4b バージョン上げよう
* 2097c20 Merge remote-tracking branch 'origin/master'
|\
| * 236f75c (tag: 1) 初期作成
* | 9e1a13b Revert "初期作成 今日の日付を入れました。 スカッシュテストです"
* | 2e790d6 初期作成 今日の日付を入れました。 スカッシュテストです
|/
* 337fd36 Initial commit
```

今回に関しては、`0a7829e`のコミットIDまでの内容を1つのコミットにまとめてみます。

## 2．リベースを行う。
指定したコミットIDの1つ前を指定して、以下リベースのコマンドを行う。
今回は途中にマージコミットがないので、`-r`のオプションを指定しないとおそらくできない。

```
git rebase -i 7ba88b5
```

このコマンドを実行した結果、以下のようにリベースの際にコミットをそれぞれどう扱うか？を指定する画面が表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565426/cdc09be4-51af-69e5-ead9-7b94eb6e1b2a.png)

基本的に上に書いてあるpickの部分が、コミットをどうするかの部分なので
この情報を変えていく。

https://chaika.hatenablog.com/entry/2019/02/25/170000

今回は他のコミットメッセージを残す理由が無いので、基本的に`f(fix up)`の指定になるが
最初のコミットが、まとめるコミットメッセージとして利用するので、最初だけ`r(reword)`に指定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565426/9382ee12-df0c-c545-7119-f053ca80e71c.png)

これで保存をすると、コミットメッセージの編集画面が開くので指定するメッセージを入力する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565426/61549107-0820-fd3e-1310-aa6538be1d52.png)

保存をしたら、`git log --oneline`か`git lola`でコミットがまとまったかを確認する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565426/885fbb92-a48b-a212-7814-3cb735abb97b.png)

## 3. コミットした内容をプッシュする

もしローカルだけの場合であれば、単純にプッシュするだけでよい。
```
git push origin develop
```

しかし、すでにプッシュ済みの内容がある場合は、強制プッシュをする必要がある。
```
# git push リモート ローカルブランチ名:リモートブランチ名
git push -f origin develop:develop
```

## おまけ
### コミットのまとめに失敗しないために…
ブランチのコピーを取ったうえで、リベースをやることをお勧めする。
Git上でリベースができない場合は、`git rebase --abort`で戻せるのだが
一度リベースをしてしまうと、`git reflog`コマンドを実行して戻す必要が出てきてしまう。

https://qiita.com/getty104/items/cfd98f5f0ea89ef07bf0

また、コミットをまとめた後差分をチェックしたい、ということがあると思うので
ブランチのコピーをとっておいた方が最初はよいと思われる

https://qiita.com/yunano/items/f3133ea64efed762df2f

その場合は、リベースで1つにまとめた後コピーしたブランチの内容で
`git diff`コマンドで差分が無いことを確認しておこう。
差分がなければ問題なくまとめられている。

### マージされたコミットがある場合はどうすればいいのか？
これの最善策はまだ分かっていません。
`-r`のオプションで指定しないと、マージコミットを扱わないので指定する必要があるが…
`git rebase -i -r コミットID`

リベースをした場合、おそらくマージしたという情報が消えるためこうせざるを得ないと思っている。

1. ローカルブランチを対象になるブランチの最新状態にする
1. ローカルで修正した内容を1つにまとめて、コミットする
1. `git push -f ...`で強制プッシュしてまとめる

操作は複雑だが、最終的にコミットをまとめる＋履歴を見やすくするための操作になるかと思う。
今度はこちらの方を調べてみようかと思います。