Gitを使っていると、修正を後で戻したりするために細かくコミットをすることが大いにあるが
それはそれとして、レビューの後はコミットを1つにまとめておきたい…
ということが往々にしてある。
その時のやり方をまとめておこうと思います。
例として、下記のように複数のコミットを用意した。
このコミットをまずまとめてみます。
1. どこまでのコミットを1つにまとめるか?
ターミナルから実行する場合は、git lolaのエイリアスを入れたほうがわかりやすくなりそうです。
SourceTreeなどであれば、ツリー上に履歴を見られるのでわかりやすいですが
ターミナルで見るにはgit lolaなどツリー上に見るコマンドを実行した方が分かりやすいです。
まずまとめるコミット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
このコマンドを実行した結果、以下のようにリベースの際にコミットをそれぞれどう扱うか?を指定する画面が表示される。
基本的に上に書いてあるpickの部分が、コミットをどうするかの部分なので
この情報を変えていく。
今回は他のコミットメッセージを残す理由が無いので、基本的にf(fix up)
の指定になるが
最初のコミットが、まとめるコミットメッセージとして利用するので、最初だけr(reword)
に指定する。
これで保存をすると、コミットメッセージの編集画面が開くので指定するメッセージを入力する。
保存をしたら、git log --oneline
かgit lola
でコミットがまとまったかを確認する。
3. コミットした内容をプッシュする
もしローカルだけの場合であれば、単純にプッシュするだけでよい。
git push origin develop
しかし、すでにプッシュ済みの内容がある場合は、強制プッシュをする必要がある。
# git push リモート ローカルブランチ名:リモートブランチ名
git push -f origin develop:develop
おまけ
コミットのまとめに失敗しないために…
ブランチのコピーを取ったうえで、リベースをやることをお勧めする。
Git上でリベースができない場合は、git rebase --abort
で戻せるのだが
一度リベースをしてしまうと、git reflog
コマンドを実行して戻す必要が出てきてしまう。
また、コミットをまとめた後差分をチェックしたい、ということがあると思うので
ブランチのコピーをとっておいた方が最初はよいと思われる
その場合は、リベースで1つにまとめた後コピーしたブランチの内容で
git diff
コマンドで差分が無いことを確認しておこう。
差分がなければ問題なくまとめられている。
マージされたコミットがある場合はどうすればいいのか?
これの最善策はまだ分かっていません。
-r
のオプションで指定しないと、マージコミットを扱わないので指定する必要があるが…
git rebase -i -r コミットID
リベースをした場合、おそらくマージしたという情報が消えるためこうせざるを得ないと思っている。
- ローカルブランチを対象になるブランチの最新状態にする
- ローカルで修正した内容を1つにまとめて、コミットする
-
git push -f ...
で強制プッシュしてまとめる
操作は複雑だが、最終的にコミットをまとめる+履歴を見やすくするための操作になるかと思う。
今度はこちらの方を調べてみようかと思います。