It's raining cats and dogs.

無駄なことなんてないはず

svn hook(pre-commit)を使ってコミットを拒否る

引き続きみんな大好きsvnネタ。集中管理バンザイ(泣

やりたいこと

コミット対象のファイルの中に特定の文字列が含まれていた時にコミットを拒否したい

svn hookについて

http://www.asahi-net.or.jp/~iu9m-tcym/svndoc/svn_pre-commit.html
の「設定方法の流れ」がわかりやすい
今回ボクがやりたいことはpre-commitを使うと実現できそう

pre-commitのファイルを作成する

リポジトリが置いてあるディレクトリの下にhooksというディレクトリがあって、その下にpre-commitという実行権限があるスクリプトを置いておけば良いらしい。
bashでもrubyでもperlでもpythonでも実行出来ればなんでもよさそう。
ちなみに僕はbash(sh)で書いた。

$ cd /path/to/repos/hogerepo/hooks
[/path/to/repos/hogerepo/hooks]$ vi pre-commit
#!/bin/sh

# 対象リポジトリ
REPOS="$1"
# トランザクション番号
TXN="$2"

# svnlookのパス
SVNLOOK="/usr/bin/svnlook"

# トランザクション番号とリポジトリ名を使ってコミット対象のリストを取得するためのコマンド
CHANGED_CMD="$SVNLOOK changed -t $TXN $REPOS"
# トランザクション番号とリポジトリ名を使ってコミット対象ファイルの中身を確認(cat)するためのコマンド
CAT_CMD="$SVNLOOK cat -t $TXN $REPOS"

for line in `$CHANGED_CMD`
do
  # .phpのファイル以外は無視
  if ! echo "$line" | grep -E '\.php$' ; then
    continue
  fi

  # ファイル内にhoge, fuga の文字があったらエラー
  if $CAT_CMD $line | grep -E 'hoge|fuga'; then
    echo "NG word error!!! in $line" >&2
    # 途中で終了する場合は0以外を返すらしい
    exit 1
  fi
done

exit 0

こんな感じ。svnlookというコマンドは初めて知った。

svnlook とは

作業コピーではなくリポジトリの中を確認するためのコマンド
http://www.caldron.jp/~nabetaro/svn/svnbook-1.4-final/svn.ref.svnlook.html
サブコマンドと併用して使う。

svnlook changed

svnlookのサブコマンド
トランザクション番号を指定すると、そのコミット(トランザクション)での対象ファイルリストが取れる。
リビジョンを指定するとそのリビジョンでコミットされたファイルリストが取れる。
http://www.caldron.jp/~nabetaro/svn/svnbook-1.4-final/svn.ref.svnlook.c.changed.html

svnlook cat

svnlookのサブコマンド
トランザクション番号を指定すると、そのコミット(トランザクション)の対象となるファイルの中身をコミット前でも見れる
リビジョンを指定するとそのリビジョンでコミットされた時のファイルの中身が見れる。
http://www.caldron.jp/~nabetaro/svn/svnbook-1.4-final/svn.ref.svnlook.c.cat.html

実行権限をつける

最後に、実行権限がないと動かないので実行権限をつけておく
[/path/to/repos/hogerepo/hooks]$ chmod 755 pre-commit


これで完了