npmコマンドでよく書くパターンにGitで固定のファイルをステージしてコミットするというようなものがある。なんらかの処理を行うメインコマンドのpost
コマンドでよくやる。まれにその固定のファイルが更新されないこともあり、その時コミットしてしまうとcommit
サブコマンドが正常に(終了コード0で)終了しない。これを避けるためにはステージされることで更新があったかどうかをチェックする必要があることになる。それはdiff
サブコマンドの--exit-code
オプションを使うとうまく書くことができる。
例えば更新されているかもしれないfoo
というファイルをステージして、更新があった場合にのみコミットしたい、とすると以下のようにコマンドをつなげれば良い。
$ git add foo && git diff --cached --exit-code --quiet || git commit --message="Update foo"
add
サブコマンドでfoo
をステージした後、diff
サブコマンドを、
--cahced
オプションでステージしたファイルに絞り--exit-code
オプションで差分が見つかった場合に終了コード1を返すようにし--quiet
オプションで差分表示を隠す
このように実行すると、差分があった時だけ、つまりfoo
が更新されていた時だけcommit
サブコマンドが走る。またこのコマンド全体の終了コードも0になる(そのためnpmコマンドとして仕込んでもあの長い例外メッセージが出ない)。
Gitのサブコマンドのオプションは単純な機能の制御だけでなく、このようなコマンドやシェルスクリプトを書く上で役に立つものも多くある。しかし必要な時に探すのがすごい大変だ……。てっきりcommit
サブコマンドのオプションであるかと(--allow-empty
の逆としてあるかなと推察していた)ずっと探していて、まったく見つからなかった。