
Gitのレポジトリに.pre-commit-config.yamlファイルが用意されていて
pre-commitでリンターなどがかけられるようになっていても、
pre-commit install
を忘れてしまうとpre-commitが動作しません。
手動でやろうとするとどうしても忘れてしまうので、 自動化する方法についていくつかやってみたものについて。
pre-commit
Gitのhookの機能で.git/hooks/pre-commitにスクリプトを置いておくと コミット時に自動的に実行され、問題があるとコミットが中断されるようになります。
その実行内容を簡単に管理できるようにするのが その名もpre-commitというツール。
pre-commit install
を実行すると
pre-commitツールが管理するツールを実行するための
.git/hooks/pre-commitがインストールされます。
pre-commit
コマンドは
レポジトリルートに置かれた
.pre-commit-config.yamlという設定ファイルに従って
ツールを実行します。
.pre-commit-config.yamlや中で使うツールの設定などを適時レポジトリ内に追加しておけば コミット時に必要なチェックが行われ必要な形を担保できます。
ただ、pre-commit install
を忘れてしまうとコミット時のチェックが行われません。
結構忘れたまま過ごしてしまうこともあるので、Gitのレポジトリを取ってきたら中で必ず
pre-commit install
が実行された状態になるような方法をいくつか試してみました。
基本的にはPythonで uv を使って管理されているレポジトリを想定していますが、 Pythonじゃなくてもそのまま使える部分もありますし 必要に応じて調整すれば使えるはずです。
Git alias
~/.gitconfigに以下のようなaliasを設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
git clone
の代わりにgit cl
を使うと、
レポジトリをクローンした後に
特に最後の部分でレポジトリの中に.pre-commit-config.yamlがあればpre-commit install
を実行するようにしています。
pre-commit
コマンドはuvで管理される仮想環境化にあるのであればそれを使い、
そこにない場合にはグローバルにインストールされていればそれを使います。
そのため、その上で.uv.lockがあればuv sync
を実行して
仮想環境の準備もしておきます。
この方法だと.gitconfigさえdotfilesなどで管理しておけば
どの環境でもどうように使えますし、
またuv
などに関しても必要なものがあれば初期設定を追加することも出来ます。
これが一番簡単で確実な方法かな、と思います。 pre-commitに関してはこれでほぼほぼ問題ないはず。
ただ、あくまでaliasなので、普通にgit clone
したら出来ないですし、
ghqみたいなレポジトリ管理ツールなどを使う場合にも
適用されないので
それらのときでも同様のことをするためには必要に応じてwrapperを作るなどする必要があります。
Git init.templateDir
Gitではinit.templateDir
を.gitconfigに設定しておくと、
その中にあるhooksなどのディレクトリにあるファイルを
.git/hooksなどにコピーしてくれます。
.gitの中にはhoooksやinfoといったディレクトリが作られますが、 その中にあるファイルは元々Gitをインストールしたときに一緒にインストールされる git-core/templatesの中にあるものがコピーされます。
通常は$(git --exec-path)/../share/git-core/templates)
のような場所にあります。
ここのhooksにはpre-commit.sampleなどのhookのサンプルが置かれていて、
クローンしたレポジトリの.git/hooks/pre-commitはそのサンプルが入っている状態になります。
init.templateDir
にファイルを置いておくとこれらの代わりにinit.templateDir
で指定したディレクトリの中にあるファイルが
.gitにコピーされるようになります。
この設定のため、まず、.gitconfigに
1 2 |
|
のような設定を追加するか、もしくはコマンドで、
1
|
|
を実行して設定を追加します。
テンプレートディレクトリの場所はどこでも良いのでHOME直下に.git-templatesとして作ったり好きなように。
pre-commit
コマンドにはinit-templatedir
というサブコマンドがあり、これによって指定したテンプレートディレクトリにpre-commitファイルを追加することができます。
もしpre-commit
コマンドがグローバルにインストールされているのであれば、
1
|
|
で、~/.config/git-templates/hooks/pre-commitにpre-commitファイルが追加され、 次にCloneする際にこのファイルが追加されます。
一方、uvなどで管理している仮想環境化にpre-commit
コマンドがインストールされている場合には、
これだと別のものになってしまいます。
逆にその仮想環境化で作ったpre-commitファイルはそのレポジトリ専用のものになってしまいます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
最初のINSTALL_PYTHON
が<repo>/.venv/bin/python3
のような
Pythonのパスになってたりします。
これをいろいろな環境で完璧に合わせるのは難しいので最小限の状態にして かつ、pre-commitが設定されてないレポジトリでは実行しないように、
1 2 3 4 5 6 7 8 |
|
のようなスクリプトにしておくと
基本的にグローバルにインストールされているpre-commitコマンドが実行され、
必要であればレポジトリで仮想環境下に入って実行、もしくはuvならuv run git commit
などすれば
その仮想環境下のpre-commit
コマンドが実行されるようになります。
すべてのレポジトリにインストールされるので、.pre-commit-config.yamlがないレポジトリでは 実行しないようにしておく必要があります。
mise
miseはPythonだけでなく様々な言語の仮想環境を管理できるツールです。
このmiseを使っている場合に使える方法。
miseを有効にするために、レポジトリ.mise.tomlを作成しておく必要がありますが、 それを以下のような設定にしておきます。
1 2 3 4 5 6 7 8 9 10 |
|
miseにもhooksという機能がありますが、現状正式版にはなっていないため、
使うためにはexperimental = true
を設定しておく必要があります。
hooksはmiseの古いバージョンだと使えないかもしれないので 使えない場合はmiseのバージョンを更新してみてください。 (少なくともversion 2025.7.4だと使える)
hooksはディレクトリを移動するたびに実行されるcd
や特定のファイルが変更されたときに実行されるwatch_files
などがありますが、
enter
/leave
といったレポジトリ内に入った際や出た際に実行されるものもあります。
このenter
を使ってpre-comimt install
を実行するようにしておきます。
ここではpre-commit
コマンドがuvで仮想環境にインストールされるようになっているレポジトリを仮定しています。
もし、pre-commit
コマンドをレポジトリ依存ではなくグローバルなものとして使ってる場合には単にpre-commit install
に変更してください。
この方法の利点としては レポジトリ側での設定なのでレポジトリごとに必要に応じた設定ができること。
また、enter
の指定なので、仮に間違って.git/hooks/pre-commitファイルを消してしまっても
次にそのレポジトリに入ったときに追加されます。
上の2つのGitだけの設定に比べると一般性は下がりますが、 その分レポジトリごとに必要な設定ができるので便利です。
欠点としてはmiseを使ってないと意味がないということと、
enter
はレポジトリ下に入るたびに実行されるのでちょっと冗長かもしれないということ。
uv run pre-cmmit install
は場合によっては実行時間が気になることもあるかもしれません。
なので上のようにpre-commitがインストールされてないときだけ実行するようにしてあります。
また、毎回uv run
してしまうとuv sync
相当のことが毎回行われるのも場合によっては問題になるかもしれないので
基本的にはこのように必要なときだけ実行するようにしておいが方が良いと思います。
まとめ
cloneするときに、という点では最初のようなaliasを使えば pre-commitだけでなく、必要なものを自由に設定できるので 便利です。
ただ、cl
意外を使ってしまう場合があれば適用されないので
その場合を把握しておく必要があります。
init.templateDir
を使う方法は
pre-commitに関しては割と確実な方法ではありますが、
pre-commit関係ないレポジトリでも入れてしまったり、
どの環境のpre-commitを使うかで場合によって動かないこともあるので注意が必要です。
miseを使う方法だとレポジトリごとに必要な設定もできるので便利です ただmiseを使っていないと意味がないという欠点があります。 またレポジトリ側の設定なので自分で管理できるレポジトリでの話になります。
個人的な現状の設定としてはaliasとmiseの方法を入れてあります