はじめに
今まで個人プロジェクトでは正直コミットログは適当でも良いのではないかと思ってました。コミットログはレビューしやすくするためのもので、レビュワーがいないならやる意味ないのかなと。
ただ最近以下の手順を試してみたところ、レビュー関係なく開発体験が良くなった感覚がありました。
- PRまでの作業手順を考えて最初にコミットを積んでおく
- 実装を行う
git commit --fixupとgit rebase -i --autosquashで指定したコミットに変更を取り込む- 実装が一通り終わるまで2に戻る
- PRを出す
特に最初のPRまでの作業手順を考えて最初にコミットを積んでおくが重要でして、PRを出すまでの作業手順(それも1コミットという非常に小さい単位で)を強制的に最初に言語化することが求められます。頭で作業順番をぼやっと考えることが多いと思いますが、明文化することでよりやるべきことを鮮明になった気がします。
またgit commit --fixupとgit rebase -i --autosquashについて巷にかなりやり方が出回っているかと思いますが、手順で一番わかりづらい箇所だと思いますし書き残しておきます。
空のコミットを作成する方法
変更がない状態でも空のコミットを作成することができます。
$ git commit --allow-empty -m <なにかしらのメッセージ>
指定したコミットに変更を加える方法
1: 修正を行いgit addする
最初にしておいたコミットに対して、後から修正を行っていきます。まずはいつも通り何かしらの機能を実装を行い、git addします。
# 現在のディレクトリ(カレントディレクトリ)とそのサブディレクトリ内のすべての変更されたファイルをステージングエリアに追加する $ git add .
2: git commit --fixupでコミットする
次に--fixupオプションを利用してコミットを行います。
# 過去の特定のコミットに対して、そのコミットを修正するための新しいコミットを作成する $ git commit --fixup <ターゲットのコミットハッシュ>
重要なのは変更を結合したい過去のコミットハッシュを指定してあげることです。つまり最初に積んでおいたコミットから、今回の実装に関連するものを指定するというわけですね。
コミットハッシュの確認方法はなんでもよいかと思いますが、例えばgit log --onelineあたりが王道でしょうか。
# Gitのコミットログを非常に簡潔な1行形式で表示する $ git log --oneline
git commit --fixupを実行すると、コミットメッセージが自動的にfixup! feat: hogeのような形になります。このfixup!プレフィックスが、次のrebaseで統合されるための目印になってます。
3: git rebase --autosquashを実行する
最後に--autosquashを活用してfixup!プレフィックスがついたコミットをターゲットのコミットに統合します。
$ git rebase -i --autosquash <ターゲットのコミットよりも前のコミットハッシュ>
rebase使っている方はおなじみかと思いますが、ターゲットのコミットよりも前のコミットを指定する必要があるので注意です。ターゲットのコミットの親コミットのハッシュを指定しておけば問題ありません。
-i(--interactive)はテキストエディタ上で確認・編集できるようになるオプションでして、私はいつもつけていますがなくても大丈夫です。
この状態でgit logを確認すればfixup!コミットが消えているはずです。最後にforce pushすれば完成です。
$ git push --force-with-lease origin <ブランチ名>