ここに書いてあるように、
フックスクリプト置き場は自由に設定できるみたい。そこで、
git config --global init.templatedir '~/.git_template'
として、自分用のhookを書いていく。
注意点としては、ひとつしかテンプレートディレクトリを指定できないっぽいので、
会社とかで共通のhookの使用が前提となっている場合は他の方法を考える。
.git以下にはhook-loaderみたいなものをコピーして、実態は別の場所から参照、みたいな機能を用意できればいいのかな。
自分は特に差し迫って必要じゃないので作りませんが。
ここからが本題
さて、この間もついやってしまったが、ライブラリやアプリケーションのバージョンとgitのタグとを同時に管理しているのに、タグ付けしてpushしたあとに
バージョンを上げるのを忘れてしまう。
例を挙げると、githubでgit push --tagsしたあとにsetup.pyやversion.rbの中を更新しわすれるパターン。
pre-push-hookとかpre-merge-hookはない(欲しい)。
私は幸いにもgit-flowを使っており、releaseブランチやhotfixブランチの中にバージョン記述がある。
それをpre-commit-hookを使い、コミット前にチェックする。
流れ
git flow release start 0.2
# 作業
git commit # この時にhook発動
# 作業
g flow release finish 0.2
慣れないbashで頑張って書きました。
https://raw.github.com/aflc/.git_template/master/hooks/pre-commit
設定
.gitconfigにこんな感じで書く。
# init.templatedirを設定すると、git initやcloneする度にhooksをコピーしてくれます
[init]
templatedir = ~/.git_template
[version-check-hook]
# mode = python
mode = all
python-path = "setup.py"
python-pattern = "[^a-zA-Z]*version=['\\\"]\\(.*\\)['\\\"].*"
ruby-path = "*/lib/*/version.rb"
ruby-pattern = "[^a-zA-Z]*VERSION = ['\\\"]\\(.*\\)['\\\"].*"
modeになにか文字列を入れて、
${mode}-pathにチェックするファイルのパターン、${mode}-patternに正規表現を入れる。
ダブルクオートや()はエスケープしてください。
ダブルクオートとバックスラッシュはそもそも.gitconfigでエスケープが必要なので気をつけてください。
また、行頭からマッチしにいくので行全体のパターンを書いてください。
例
git init repo
cd repo
git flow init
...
git touch setup.py
...
git flow release 0.2
ここまで作業が終わったとします。この時、setup.pyに以下の様に書いてあったとします。
from setuptools import setup
setup(name='repo',
version='0.1',
...
setup.py中のバージョン表記は0.2なのに、バージョン0.1でリリースしようとしているのがわかります。
この時、さっき作ったpre-commit hookが発動します。
git commit
[version-check-hook] Incompatible version found.
Your branch: 0.2
Matched version: 0.1
----
setup.py:3: version='0.1',
後は直してコミットすればOK。
最後に
スクリプトがとても汚くておそらくバグってるので誰か美しく作ってください。
今となってはPythonで書いても良かった気がする。