git commit する前に、確認をしよう。自動で!
ホシイです。本日は git の小ネタをひとつ。
git commit されているものがいつもそのまま動くとは限らない
便利 script を git clone して、そのまま実行!したら、しょうもないエラーに … といったことは残念ながら、めずらしいことではありません。
commit されているものがいつもただしいなんて、いつから錯覚していた…? なんて、よくあることです。レビュアーを責めても時間は返ってきません。
たとえば設定ファイルを yaml で書いていたとして、その yaml に syntax error が残ったまま commit & push してしまった、なんていう経験はないでしょうか?
こういった問題は作業者の気の緩みによって起きるものである、気合で解決だ! …というのは難しいものです。
commit 前にチェックしよう、自動で。
git には様々なタイミングでかんたんに hook 処理を追加することができます。git init
された場所であれば、.git/hooks/
にすでに、いくつも sample を見つけることができます。
たとえば .git/hooks/pre-commit.sample
の中身を見ると、sh script でいくつかのチェックをして、失敗したときには exit 1
すればいいらしいことがわかります。
pre-commit という名前なのですから、きっと commit 前に走って、失敗すれば commit も抑制されるのでしょう。今回の目的に合いそうです。
試してみよう
.git/hooks/pre-commit
という名前で以下のような中身のファイルを作成しておきます。
#!/bin/sh
exit 1
これで、なんでもいいので試しに commit してみましょう。
$ git commit
fatal: cannot exec '.git/hooks/pre-commit': Permission denied
ふふふ。permission も付与しておきます。
$ chmod u+x .git/hooks/pre-commit
気を取り直してもう一度。
$ git commit
…? 何も起きていないように見えますが、実際、何も起きていなくて、commit もどうやらされていないようです。このようにチェックで失敗になったときはエラーメッセージが出力されるように、じぶんで pre-commit script 内に書いておくのがよさそうです。
いくつかの追加の問題を解決する
これでやりたいことはできるようになりました。が、いくつか問題があります。
ルールはこの git repo での作業をするメンバー全員に課したいので、ルールを記述してある .git/hooks
を git commit
しておきたいところですが、.git
は git 管理できない場所です。
これを解決するために、pre-commit script を git 管理下に置くため、hooks path を .git/hooks/
から .githooks/
に変更します。
git config --local core.hooksPath .githooks
これで、hooks を git 管理できるようになりました。ただし、これでは git clone したひとが上記コマンドを手元で実行しないといけません。忘れずにやりましょう!のルールは必ず忘れます。なんとか自動化したいところです。
解決方法の一例として、VSCode の devcontainer を利用している git repo の場合は devcontainer.json
に以下のように書いておく方法があります。
{
"postCreateCommand": "git config --local core.hooksPath .githooks",
}
これで、devcontainer が生成されたときに自動で git config が実行されるようになりました。
まとめ
git clone
した repo で作業する際、commit 前に自動でチェックする仕組みを入れることができました。
汎用性が高い仕組みなので、他にもいろいろなことに活用できそうです。