ikachanでgitのpushをIRCチャンネルに通知する (追記アリ)

gitのpushがあるたびに、コミットをIRCで通知するようにする。

まずikachanサーバを立てる

適当なサーバにikachanをインストールする。ikachanはIRCにメッセージを通知するためのサーバで、これを設置することで、シェルスクリプトなどから簡単にIRCにメッセージをポストできる。

例えば、以下の様にcurlコマンドを叩くだけでIRCに通知できるようになる。

$ curl -F channel=\#catalyst-ja http://localhost:4979/join
$ curl -F channel=\#catalyst-ja -F message=hoge! http://localhost:4979/notice

gitのコミットにかかわらずちょっとした通知をガンガンIRCチャンネルに通知できるので便利です。

pushされるリポジトリにhookスクリプトを置く

以下のようなhookスクリプトを置く。共有gitリポジトリ以下のhooks/updateに置いて実行権限を与えると動作する。

#!/bin/sh

# repository name
REPO_NAME="hoge.git"

# IRC channnel
CHANNEL="#hoge"

# ikachan server
IKACHAN="http://172.16.1.22:4979"

curl -s -F channel=$CHANNEL -F message="$REPO_NAME#$1 updated:" $IKACHAN/notice 1> /dev/null &

git rev-list $3 ^$2 --reverse | while read COMMITID
do
    MSG=`git --no-pager log -1 --format='%an: %s' $COMMITID`
    curl \ -s -F channel=$CHANNEL -F message="$MSG" $IKACHAN/notice 1> /dev/null & 
done

チャンネル名やメッセージなど適当に書き換えて使う。実際に自分が使っている例だと、メッセージと一緒に、gitwebのdiff画面へのリンクも通知したりしている。

ちなみに、gitリポジトリWebDAVでホストしてるとサーバサイドフックが起動されないので注意。sshSmartHTTP経由でリポジトリはホストしましょう。

終わり

こういう通知スクリプトを置くと、IRCチャンネルを見てるとなんとなくgitリポジトリの動きがわかるようになる。いちいちgitリポジトリのウェブインターフェイスにアクセスするような手間が省けるし、人から自分のコミットのコードを見てもらえる頻度も高くなるのでおすすめ。 あとikachan++です。

追記: 1/31 非同期でフックを実行する

上のフックスクリプトの場合、IRCへの通知が同期的に行われるのでpushが終了するのに処理が終了するのを待たなければならない。gitのhookでブロックされるのとかありえん、などと各所から言われた気がしたのでもうすこしマシな方法を調べてみた。

単に上のスクリプトを外出しして nohup /path/to/command &で非同期に実行してやればいいだけでしょとか思って試したら、シェルスクリプト自体は非同期で実行されているっぽいものの、なぜか通知処理が終了するまでpushが終わらない。シェルスクリプトに関する知識が足りないせいか何故かよく分からなかった。だれか教えて下さい。

もう少し調べた結果、以下みたいに単にatコマンドに実行したいコマンドを流してやればいいことがわかった。

#!/bin/sh

# /path/to/notificationは上に書いたスクリプトを外出ししたもの
echo "/path/to/notification $1 $2 $3" | at now

atコマンドは指定した時間に一度だけコマンドを発行してくれるコマンドだが、at nowにコマンドを指定することで、別プロセスで即座にコマンドが実行される。これで、通知処理が非同期で実行されるようになってブロックされなくなりgitのpushが早くなった。よかったですね、まる。