読者です 読者をやめる 読者になる 読者になる

Subversion で ASCII 以外のファイル名を追加させない方法

エクスプローラ上ではファイル名の全角半角が判別しづらいので、思わぬ全角混じりのファイル名がリポジトリに入ってしまうことがある。
これを pre-commit で検知して防ぐ。
以下のスクリプトを hooks 以下に置いておくと

#!/usr/bin/perl
# -*- coding:utf-8 -*-

$ENV{LANG} = 'ja_JP.UTF-8';

use strict;
my $SVNLOOK='/usr/bin/svnlook';

sub main {
    my ( $repos, $txn ) = @_;
    my @cmd = ( $SVNLOOK, 'diff', "-t$txn", $repos );
    open my $pipe, '-|', @cmd or die $!;
    local $/ = undef;
    my $diff = <$pipe>;
    close $pipe;

    my @added = ( $diff =~ /^(?:Added|追加): (.*)/gm );
    my $error = 0;
    for my $path (@added) {
        if ( $path =~ /[^\x00-\x7f]/ ) {
            warn "Can't use non ascii filename: $path\n";
            $error = 1;
        }
    }
    exit $error;
}

if ( @ARGV != 2 ) {
    die "Usage: $0 REPOS TXN\n";
}
main( @ARGV );

ASCII 以外のファイル名を ci しようとした際にエラーになってくれる。

$ svn ci -m "added: utf-8 filename."  日本語.txt
追加しています  (バイナリ)  日本語.txt
ファイルのデータを送信中です.svn: コミットに失敗しました (詳しい理由は以下のとおりです):
svn: MERGE リクエスト (相手: '/svn/test/trunk') が失敗しました
svn: 'pre-commit' hook failed with error output:
Can't use non ascii filename: trunk/日本語.txt

svnlook コマンドで diff をみて ASCII 以外のファイル名が追加されそうになったら弾いているのだが、

$ENV{LANG} = 'ja_JP.UTF-8';

my @added = ( $diff =~ /^(?:Added|追加): (.*)/gm );

このあたりがどうにも気味が悪い。
LANG=C だと UTF-8 のファイル名が "?\227?\129?\130?\227?\129?\130.txt" のように diff に出てしまうのでこうしたのだけど……
# この "?" は化けてるんじゃなくて \x3f