/git-hooks

Gitのフックスクリプト集・・・になる予定

Primary LanguagePerl

Git-Hooks

これは何?

Redmine等のITS/BTSとGitとCIツールを使った開発を支援するためのフックスクリプト集です。 シェルスクリプトとPure Perlで書かれているため、 msysgitを使っている方ならインストールスクリプトを実行するだけで導入できます。

動作環境

  • Gitがインストールされ、パスが通っていること
  • Perl5.8.8以降がインストールされていること
  • curlにパスが通っていること(push後のCIジョブ起動を使用しない場合不要)
  • sh(bashを想定)がインストールされていること

動作確認はWindows7上のmsysgitを使用しています。 それ以外の環境ではそのままでは動かない可能性もあります。

テストを実行する場合は、上記のほかにTest::MoreとTest::MockObjectが必要になります。

インストール方法

Windowsでファイル仮想化機能を無効にしている方はGit-Hooksが書き込みに行くファイル、 ディレクトリへの権限を設定する必要があります。 単にインストールするだけなら管理者権限で実行することで可能ですが、 git hooks updateなどでエラーになります。

一番簡単な方法は、標準構成を使用する方法です。 msysgitを使っている方なら、Install.PLが置かれた場所でgit bashを開き、

perl Install.PL msys

を実行するだけです(実行後には親ディレクトリごと削除しても構いません)。 この方法は一番手軽ですが、構成をカスタマイズすることはできません。 msysと指定している部分を環境に合わせて指定してください。

対応している環境は、Install.PLを引数なしで起動すると一覧できます。 現在はmsysとlinuxに対応しています。

構成をカスタマイズする場合や、対応されていない環境にインストールする場合は、 configsディレクトリ内にInstall-xxx.plを作成、編集してください。 xxxは環境を表し、Install.PLの第一引数として渡す文字列となります。 Install-xxx.plの各設定項目の意味は以下の通りです。

gitcmddir

Gitのサブコマンドを格納しているディレクトリを指定してください。 msysでは/usr/libexec/git-coreですが、 環境によっては/usr/local/libexec/git-coreの場合もあります。

gitconfig

Git-Hooksが使用する環境変数を書き込むファイルを指定してください。 通常はシェルの起動時に読み込まれるファイルを指定します。 bashを使っている場合は~/.bashrcのままでいいはずです。

この設定はInstall.PLの第二引数により上書き可能です。 ただし、exportによって環境変数を設定するため、csh系のシェルには対応していません。

templatedir

Gitのフックスクリプトのテンプレートを格納しているディレクトリを指定してください。 msysでは/usr/share/git-core/templates/hooksですが、 環境によっては/usr/local/share/git-core/templates/hooksの場合もあります。

githookshome

実際に実行されるスクリプトを配置するディレクトリを指定してください。 msys環境では/c/Apps/Git-Hooksを設定しています。

usesymlink

シンボリックリンクを使用するかどうかをtrue/falseで指定してください。 msys環境ではfalseを設定しています。

使い方

フックスクリプトなので、必要なタイミングで自動的に起動されます。 現在、

  • masterブランチでのコミット拒否
  • チケットIDの自動入力
  • チケットIDが無いコミットを含むpushの拒否
  • push後にCIを起動

に対応しています。

masterブランチでのコミット拒否

masterブランチは、Gitのデフォルトのブランチです。 このブランチは常に安定した状態になっていることが望ましいので、 全ての作業をほかのブランチで行い、masterブランチではそれらをマージするだけに留めるべきです。 Git-Hooksでは、masterブランチにいる状態でのコミットを拒否するようになっています。

例外として、一番初めのコミットのみ無条件で成功します。

チケットIDの自動入力

分散バージョン管理システムでは、チケットの粒度とコミットの粒度が一対一に対応しません。 一つのチケットに対して複数回コミットすることが普通です。 しかし、チケットIDを手入力するのは非常に面倒です。

これを解決するために、ブランチ名にチケットIDを含ませてコミット時に自動でチケットIDを追加する機能が含まれています。 この機能を使用する場合は、ブランチ名の中に「id/チケットID」を含む必要があります。 例えば、以下のブランチ名の場合、チケットIDの自動入力が行われます。

  • id/42
  • bug/id/10
  • id/1/memo/memo/memo
  • issue/id/20/memo/memo/memo

命名規則に沿ったブランチ名を持つブランチ上でコミットした場合、コミットメッセージの最後に 「 refs #チケットID」が追加されます。

すでにチケットIDが存在した場合は何も行いません。 チケットIDを追加するタイミングはコミットの直前なので、-mやユーザ入力によってチケットIDを入力した場合、 そちらを優先します。

チケットIDが無いコミットを含むpushの拒否

RedmineなどのITS/BTSを使っている場合、コミットは何らかのチケットに属しているべきです。 Git-Hooksでは、チケットIDが無いコミットを含むpushを拒否するようになっています。

例外として、一番初めのコミットにチケットIDが無くても拒否しません。

push後にCIを起動

curlを使ってURLにアクセスするだけです。URLにアクセスするだけでJobが起動できないCIツールには対応していません。 想定しているCIツールはJenkinsです。

デフォルトでは有効になっていないので、リポジトリごとに有効にする必要があります。 この際、インストール時に導入されるサブコマンドを実行します。

git hooks on ci

このコマンドを実行すると、ジョブを起動するためのURLを訪ねてくるので、それを入力します。 コマンド起動時にジョブを起動するためのURLを指定することも可能です。

git hooks on ci http://ci-server/job

コマンド

Git-Hooksをインストールすると、Git-Hooksをメンテナンスするためのコマンドが使用できるようになります。

  • フックスクリプトを一覧表示する
  • 有効化されているフックスクリプトを一覧表示する
  • 無効化されているフックスクリプトを一覧表示する
  • フックスクリプトを有効化する
  • フックスクリプトを無効化する
  • フックスクリプトを更新する

現在はこの5つのコマンドが使用できます。

フックスクリプトを一覧表示する

Git-Hooksが対応しているフックスクリプトを一覧表示します。

git hooks list

あまり役には立ちません。

有効化されているフックスクリプトを一覧表示する

現在のリポジトリで有効なフックスクリプトを一覧表示します。

git hooks enabled

このコマンドはGitの作業ディレクトリ内で実行する必要があります。

無効化されているフックスクリプトを一覧表示する

現在のリポジトリで無効なフックスクリプトを一覧表示します。

git hooks disabled

このコマンドはGitの作業ディレクトリ内で実行する必要があります。

フックスクリプトを有効化する

現在のリポジトリのci以外のフックスクリプトを全て有効化します。

git hooks on

このコマンドはGitの作業ディレクトリ内で実行する必要があります。

有効化するフックスクリプトを指定することもできます。

git hooks on commit-msg pre-commit

これで、commit-msgとpre-commitが有効になります。 指定されたフックスクリプトがすでに有効になっている場合、何もしません。

フックスクリプトを無効化する

現在のリポジトリのフックスクリプトをci含め全て無効化します。

git hooks off

このコマンドはGitの作業ディレクトリ内で実行する必要があります。

無効化するフックスクリプトを指定することもできます。

git hooks off commit-msg pre-commit

これで、commit-msgとpre-commitが無効になります。 指定されたフックスクリプトがすでに無効になっている場合、何もしません。

フックスクリプトを更新する

フックスクリプトを更新します。

git hooks update

このフックスクリプトはローカルで行った変更をコミット済みかどうかは関係なく問答無用で破棄します。 そのため、独自の変更を行いたい場合はgithubのリポジトリを直接remoteにせずに、 一段階リポジトリを挟むといいでしょう。

チームで使う場合、導入者以外のPCにはスタートアップ時に実行するようにしておくことも考えられます。

Tips

git hooks updateで更新されるのは、処理本体が記述されたスクリプトです。 そのため、各リポジトリのフックスクリプトが更新されたとしても、 そちらは以降に作られたリポジトリにしか反映されません。 しかし、git hooks offで一旦無効化し、git hooks onで有効化することで そのリポジトリのフックスクリプトの更新が可能です。

git hooks onではciがonになりませんので、ciを使っていた場合はgit hooks on ciする必要があります。

dispatcherはこの方法では更新されませんが、dispatcher自体に更新の仕組みが入っていますので、 普通に使っていればdispatcherを気にする必要はありません。

構成

commands

Git-Hooks用のサブコマンドの本体が含まれています。

configs

インストール用スクリプトの設定ファイルと、フックスクリプトのリストを格納したファイルが含まれています。

hooks

実際に実行されるフックスクリプトと、関連するライブラリ、テストが含まれています。

templates

フックスクリプトのテンプレートディレクトリにコピーされるスクリプトの、元となるファイルが含まれています。

Install.PL

インストール用のスクリプトです。

install-config

インストール時に生成されるファイルです。Git-Hooksが使用しますので、削除しないでください。

NYSL

ライセンスに関するファイルです。 一読ください。

README.markdown

このファイルです。

今後やりたいこと

  • 高速化
  • もっときれいに
  • フックスクリプトレベルのテスト書く
  • git hooks list --verboseとか-vとかやるとon/offが表示される
  • git hooks enabled --verboseとか-vとかやるとhooks-listにないフックに?が付く
  • git hooks help [command]の実装