コミット時に自動的にメールを飛ばすようにする

リポジトリサーバーに入ります。


$ ssh repos.server.co.jp
リポジトリディレクトリ内のhooksフォルダに入ります。

$ cd /path/to/repos/hooks

$ ls -al
drwxrwxr-x 2 root svn_group 512 8 16 16:58 .
drwxrwxr-x 7 root svn_group 512 7 30 13:49 ..
-rw-rw-r-- 1 root svn_group 2015 7 30 13:49 post-commit.tmpl
-rw-rw-r-- 1 root svn_group 1638 7 30 13:49 post-lock.tmpl
-rw-rw-r-- 1 root svn_group 2255 7 30 13:49 post-revprop-change.tmpl
-rw-rw-r-- 1 root svn_group 1567 7 30 13:49 post-unlock.tmpl
-rw-rw-r-- 1 root svn_group 2940 7 30 13:49 pre-commit.tmpl
-rw-rw-r-- 1 root svn_group 2044 7 30 13:49 pre-lock.tmpl
-rw-rw-r-- 1 root svn_group 2764 7 30 13:49 pre-revprop-change.tmpl
-rw-rw-r-- 1 root svn_group 1985 7 30 13:49 pre-unlock.tmpl
-rw-rw-r-- 1 root svn_group 2137 7 30 13:49 start-commit.tmpl
それぞれが各イベント時のフックスクリプトのテンプレートです。「.tmpl」を削除し、実行権限を変更(chmod a+x)することで自動的に実行されるようになります。

「コミット後」のタイミングは「post-commit」です。ちなみに「コミット前」は「pre-commit」で、コミットログのチェックやプログラムの構文チェック(例:php -l)とかはこのタイミングでやると良いです。

post-commit.tmplの内容は、


#!/bin/sh
#
# (コメントたくさん)
#

REPOS="$1"
REV="$2"

commit-email.pl "$REPOS" "$REV" commit-watchers@example.org
log-commit.py --repository "$REPOS" --revision "$REV"
そんな内容だったので、これを、

#!/bin/sh
#
# (コメントたくさん)
#

REPOS="$1"
REV="$2"
TO="飛ばしたい@メールアドレス"

/path/to/repos/hooks/commit-email.pl "$REPOS" "$REV" $TO
としておきました。で、上記の「commit-email.pl」が実際メールを飛ばすperlスクリプトで、これは、下記のようにインストール時に配置されてるサンプルを持ってきました。

$ cp /usr/local/share/subversion/hook-scripts/commit-email.pl /path/to/repos/hooks/
commit-email.plに加えた内容は下記の通り。
あまり日本語に考慮されてなかったので、Jcodeを使って日本語化したり戻したりセコセコやってます。
あと、コミットログが「no send」から始まっている場合、メールを飛ばさないようにするとか、隠しコマンドを仕込んだりしてます。

$ diff /usr/local/share/subversion/hook-scripts/commit-email.pl /path/to/repos/hooks/commit-email.pl
40a41
> use Jcode; # add
50,51c51,52
< #$sendmail = "/usr/sbin/sendmail";
< $smtp_server = "127.0.0.1";
---
> $sendmail = "/usr/sbin/sendmail"; # comment in
> #$smtp_server = "127.0.0.1"; # comment out
66a68,71
>
> my $no_send_flag = 0; # add
>
>
74a80
> $ENV{'LANG'} = "ja_JP.UTF-8"; # add
92a99
> $ENV{'LANG'} = ""; # add
355a363
> $ENV{'LANG'} = "ja_JP.UTF-8"; # add
356a365
> $ENV{'LANG'} = ""; # add
449a464,466
> if (lc(join('', @log)) =~ /^no send/){ # add
> $no_send_flag = 1; # add
> } # add
586c603,604
< if (defined $sendmail and @email_addresses)
---
> # if (defined $sendmail and @email_addresses) # comment out
> if (defined $sendmail and @email_addresses and $no_send_flag == 0) # add
592,593c610,613
< print SENDMAIL @head, @body;
< print SENDMAIL @difflines if $diff_wanted;
---
> #print SENDMAIL @head, @body; # comment out
> #print SENDMAIL @difflines if $diff_wanted; # comment out
> print SENDMAIL @head, jcode(join("", @body))->utf8; # add
> print SENDMAIL jcode(join("", @difflines))->utf8 if $diff_wanted; # add
最終的には、commit-email.pl と post-commit の2ファイルが増えた状態となります。

$ ls -al
drwxrwxr-x 2 root svn_group 512 8 16 16:58 .
drwxrwxr-x 7 root svn_group 512 7 30 13:49 ..
-rwxrwxr-x 1 root svn_group 25025 8 16 16:58 commit-email.pl
-rwxrwxr-x 1 root svn_group 2079 8 9 20:38 post-commit
-rw-rw-r-- 1 root svn_group 2015 7 30 13:49 post-commit.tmpl
-rw-rw-r-- 1 root svn_group 1638 7 30 13:49 post-lock.tmpl
-rw-rw-r-- 1 root svn_group 2255 7 30 13:49 post-revprop-change.tmpl
-rw-rw-r-- 1 root svn_group 1567 7 30 13:49 post-unlock.tmpl
-rw-rw-r-- 1 root svn_group 2940 7 30 13:49 pre-commit.tmpl
-rw-rw-r-- 1 root svn_group 2044 7 30 13:49 pre-lock.tmpl
-rw-rw-r-- 1 root svn_group 2764 7 30 13:49 pre-revprop-change.tmpl
-rw-rw-r-- 1 root svn_group 1985 7 30 13:49 pre-unlock.tmpl
-rw-rw-r-- 1 root svn_group 2137 7 30 13:49 start-commit.tmpl
これでコミット完了時に自動的にメールが飛ぶようになり、チームメイトに周知できます。

Subversion実践入門:達人プログラマに学ぶバージョン管理(第2版)