コミットメッセージ中に diff を表示したらいろいろ捗った

変更をコミットする時に、大抵の人は git diff --cached なんかを使ってコミット内容を確認してからコミットすると思う*1
ただ、この「コミット前に git diff --cached」作戦は、少なくとも

  • commit --amend の時
  • squash する時

にはうまく適用できない*2


これではちょっと不便なので、コンソールから diff を確認できないならコミットメッセージ中に表示させたらいいじゃない、というわけでやってみた。



イメージとしてはこんな感じ。


デフォルトの(何もしていない)コミットメッセージ:

(えーと、pangram.txt の何を修正したんだっけ?)
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch testing
# Changes to be committed:
#   (use "git reset HEAD ..." to unstage)
#
#       modified:   pangram.txt
#

diff を表示させたコミットメッセージ:

(そうそう、pangram.txt の typo を修正したんだった)
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch testing
# Changes to be committed:
#   (use "git reset HEAD ..." to unstage)
#
#       modified:   pangram.txt
#
#
# diff --git a/pangram.txt b/pangram.txt
# index 3b8357c..84102df 100644
# --- a/pangram.txt
# +++ b/pangram.txt
# @@ -1 +1 @@
# -The quick brwon fox jumps over the lazy dog
# +The quick brown fox jumps over the lazy dog


やり方は簡単、 git フック (prepare-commit-msg) を仕込むだけ。


prepare-commit-msg

#!/bin/sh

case "$2,$3" in
    commit,HEAD)
        echo "# " >> "$1"
        git diff --cached HEAD^ | sed -e 's/^/# /g' >> "$1"
        ;;
    ,|template,|squash,)
        echo "# " >> "$1"
        git diff --cached | sed -e 's/^/# /g' >> "$1"
        ;;
    *)
        ;;
esac

これを .git/hooks において、必要に応じて実行権限を付ければ完了。

ただし、-c または -C オプションを指定してコミットした場合、実際のコミットメッセージに diff の内容が含まれてしまうので要注意。



このフックスクリプトgithub においてる他、前回 の git-hooks スクリプトでもインストールできるので、お好きにどうぞ。

*1:特に git add -p を使った時なんかは

*2:実際にやろうと思ったら、一旦コミットをキャンセルして変更を確認後、再度コミットすればいけるかと