svnlook changed -t トランザクション名 リポジトリパス
スクリプトの先頭のコメントにあるような pre-commit フックスクリプトを別に用意するか または Unix 系の OS の場合、スクリプトを pre-commit という名前で保存する必要がある。
check-commit-changed.pl
#!/usr/bin/perl
###############################################################################
#
# check-commit-changed.pl
#
# svnlook changed を利用して意図していないファイル/ディレクトリのコミットを
# 拒否するスクリプト。pre-commit (pre-commit.bat) から呼び出すことが前提
#
# pre-commit.bat の例
# set REPOS=%1
# set TXN=%2
#
# set PATH=C:\Program Files\Subversion\bin
# c:\Perl\bin\perl.exe %REPOS%\hooks\check-commit-changed.pl %REPOS% %TXN%
# exit %ERRORLEVEL%
#
# pre-commit の例 (for UNIX)
# #!/bin/sh
# REPOS=%1
# TXN=%2
#
# set PATH=/usr/bin
# /usr/bin/perl $REPOS/hooks/check-commit-changed.pl $REPOS $TXN || exit 1
#
# スクリプトの動作原理
# 1. svnlook を以下のコマンド引数で呼び出す
# svnlook changed -t トランザクション名 リポジトリパス
# 2. svnlook の出力を解析する
# 3. 意図していない修正があった場合 STDERR にメッセージを出力して終了コード1 を返す
#
###############################################################################
# !!! 適宜書き換えて !!!
# svnlook の絶対パスを指定する
# または呼び出し側の pre-commit または pre-commit.bat で環境変数 PATH に
# svnlook のパスを設定しても OK
$SVNLOOK = "svnlook";
# pre-commit (pre-commit.bat) からの引数
$REPOS = $ARGV[0];
$TXN = $ARGV[1];
# debug オプション
$debug = 0;
# svnlook のコマンドライン引数
$svnlook_cmd = "$SVNLOOK changed -t $TXN $REPOS";
# svnlook を(パイプで)実行
open IN, "$svnlook_cmd |";
@svnlook_output = ();
$veto_files = 0;
while( $data = <IN> )
{
push @svnlook_output, $data;
# svnlook changed の出力フォーマット
#
# 参考: http://svn.apache.org/repos/asf/subversion/trunk/subversion/svnlook/main.c : print_changed_tree
# 参考: http://svn.apache.org/repos/asf/subversion/trunk/subversion/svnlook/main.c : print_changed_tree
#
# XYZ filepath (from node:rXXX)
#
# X = "A", "D", "U", "_"
# Y = " ", "U"
# Z = " ", "+"
#
# " " は "_" で表すとする
# 1. A__ filepath
# 2. A_+ filepath (from copynode:rXXX)
# 3. D__ filepath
# 4. U__ filepath
# 5. UU_ filepath
# 6. _U_ filepath
#
# 1列目
# A → ファイル or ディレクトリの追加
# D → ファイル or ディレクトリの削除
# U → ファイル or ディレクトリの更新
#
# 2列目
# U → 属性の更新
#
$file = $data;
$file =~ s!^....!!; # 先頭の4文字を消す
$file =~ s!\(from .+\)!!; # (from copynode:rXXX)を消す
$file =~ s!\s+$!!; # 末尾の空白を消す
if( $data =~ /^D/ )
{
# ファイル or ディレクトリ削除は許可
next;
}
# ファイルパスを元にコミットの可否を判断する
if( !is_allowed_to_commit( $file ) )
{
print STDERR "We are NOT allowed to commit temporary files ($file)\n";
$veto_files++;
}
}
close IN;
if( $veto_files > 0 )
{
print STDERR "You tried to commit $veto_files files or dirs which are NOT allowed to.\n";
if( $debug )
{
print STDERR "svnlook output is\n";
print STDERR @svnlook_output;
}
exit 1;
}
exit 0;
############################################################################3
#
# ファイルパスを元にコミットを許可するか拒否するか判断する関数
#
# 戻り値
# 1: コミットを許可する
# 0: コミットを拒否する
#
# !!! 適宜書き換えて !!!
############################################################################3
sub is_allowed_to_commit
{
my $file = shift;
if( $file =~ /obj(fre|chk)_(\w+)/ ) # object dir check
{
return 0;
}
elsif( $file =~ /build(fre|chk)_(\w+)\.(log|err|wrn)/ ) # build log
{
return 0;
}
elsif( $file =~ /(\w+)\.(\w+)\.user$/ ) # build log
{
return 0;
}
elsif( $file =~ /_objects\.mac$/ )
{
return 0;
}
elsif( $file =~ /\.ncb$/ )
{
return 0;
}
elsif( $file =~ /\.opt$/ )
{
return 0;
}
elsif( $file =~ /\.plg$/ )
{
return 0;
}
elsif( $file =~ /\.suo$/ )
{
return 0;
}
elsif( $file =~ /\.obj$/ )
{
return 0;
}
elsif( $file =~ /\.res$/ )
{
return 0;
}
elsif( $file =~ /\.exp$/ )
{
return 0;
}
elsif( $file =~ /\.idb$/ )
{
return 0;
}
elsif( $file =~ /\.ilk$/ )
{
return 0;
}
elsif( $file =~ /mt\.dep$/ )
{
return 0;
}
elsif( $file =~ /(vc(\d+))\.pdb$/ )
{
return 0;
}
elsif( $file =~ /BuildLog\.htm$/ )
{
return 0;
}
return 1;
}
E:\tmp\pre-commit\work>svn ci -m "test" 追加しています test test test.ncb 追加しています test.ncb 追加しています test.obj 追加しています test.opt 追加しています test.plg 追加しています test.suo ファイルのデータを送信しています ................................................................................................... svn: コミットに失敗しました (詳しい理由は以下のとおりです): svn: Commit blocked by pre-commit hook (exit code 1) with output: We are NOT allowed to commit temporary files (trunk/test test test.ncb) We are NOT allowed to commit temporary files (trunk/test.ncb) We are NOT allowed to commit temporary files (trunk/test.obj) We are NOT allowed to commit temporary files (trunk/test.opt) We are NOT allowed to commit temporary files (trunk/test.plg) We are NOT allowed to commit temporary files (trunk/test.suo) You tried to commit 6 files or dirs which are NOT allowed to.