svn中的pre-commit hook:无法从本地语言环境转换为UTF-8

时间:2010-02-08 18:38:41

标签: svn utf-8 hook

我的预提交挂钩有问题。

此挂钩测试是否在用户提交时锁定了文件。当出现错误情况时,应输出另一个用户正在锁定此文件,或者如果没有人锁定,则应显示“您没有锁定此文件消息(文件名)”。当文件的名称有一些像“ç”这样的拉丁字符并且乌龟在输出中显示这个时,会发生错误。

提交失败(详情如下): 使用输出阻止前提交挂钩(退出代码1)的提交: [错误输出无法从本地语言环境转换为UTF-8。]

你知道我怎么解决这个问题?

谢谢,

Alexandre

我的shell脚本在这里:

#!/bin/sh
REPOS="$1"
TXN="$2"
export LANG="en_US.UTF-8"
/app/svn/hooks/ensure-has-need-lock.pl "$REPOS" "$TXN"
if [ $? -ne 0 ]; then exit 1; fi
exit 0

我的perl在这里:

!/usr/bin/env perl  

#Turn on warnings the best way depending on the Perl version.   
BEGIN {   
  if ( $] >= 5.006_000)   
    { require warnings; import warnings; }                         
  else     
    { $^W = 1; }                  
}              

use strict;   
use Carp;   

&usage unless @ARGV == 2;   

my $repos        = shift;   
my $txn          = shift;    

my $svnlook = "/usr/local/bin/svnlook";   
my $user;   

my $ok = 1;   
  foreach my $program ($svnlook)   
    {   
      if (-e $program)   
        {   
          unless (-x $program)   
            {   
              warn "$0: required program $program' is not executable, ",   
                   "edit $0.\n";   
              $ok = 0;   
            }   
        }   
      else   
        {   
          warn "$0: required program $program' does not exist, edit $0.\n";   
          $ok = 0;   
        }   
    }   
  exit 1 unless $ok;   

  unless (-e $repos){   
      &usage("$0: repository directory $repos' does not exist.");   
  }   
  unless (-d $repos){   
      &usage("$0: repository directory $repos' is not a directory.");   
  }   

  foreach my $user_tmp (&read_from_process($svnlook, 'author', $repos, '-t', $txn))   
  {   
      $user = $user_tmp;   
  }   
  my @errors;           

  foreach my $transaction (&read_from_process($svnlook, 'changed', $repos, '-t', $txn)){  
    if ($transaction =~ /^U.  (.*[^\/])$/){   
      my $file = $1;   
      my $err = 0;   
      foreach my $locks (&read_from_process($svnlook, 'lock', $repos, $file)){   
        $err = 1;   
        if($locks=~ /Owner: (.*)/){   
          if($1 != $user){   
           push @errors, "$file : You are not locking this file!";    
          }   
        }   
      }   
      if($err==0){   
        push @errors, "$file : You are not locking this file!";   
      }   
    }   
    elsif($transaction =~ /^D.  (.*[^\/])$/){   
      my $file = $1;   
      my $tchan = &read_from_process($svnlook, 'lock', $repos, $file);   
      foreach my $locks (&read_from_process($svnlook, 'lock', $repos, $file)){   
        push @errors, "$1 : cannot delete locked Files";   
      }   
    }   
    elsif($transaction =~ /^A.  (.*[^\/])$/){   
      my $needs_lock;   
      my $path = $1;   
      foreach my $prop (&read_from_process($svnlook, 'proplist', $repos, '-t', $txn, '--verbose', $path)){   
          if ($prop =~ /^\s*svn:needs-lock : (\S+)/){   
            $needs_lock = $1;   
          }   
      }   
      if (not $needs_lock){   
        push @errors, "$path : svn:needs-lock is not set. Pleas ask TCC for support.";   
      }   
    }   
  }   
if (@errors)   
  {   
    warn "$0:\n\n",   
         join("\n", @errors), "\n\n";   
    exit 1;   
  }   
else   
  {   
    exit 0;   
  }   

sub usage   
{   
  warn "@_\n" if @_;   
  die "usage: $0 REPOS TXN-NAME\n";   
}   

sub safe_read_from_pipe   
{   
  unless (@_)   
    {   
      croak "$0: safe_read_from_pipe passed no arguments.\n";   
    }   
  print "Running @_\n";   
  my $pid = open(SAFE_READ, '-|');   
  unless (defined $pid)   
    {   
      die "$0: cannot fork: $!\n";   
    }   
  unless ($pid)   
    {   
      open(STDERR, ">&STDOUT")   
        or die "$0: cannot dup STDOUT: $!\n";   
      exec(@_)   
        or die "$0: cannot exec @_': $!\n";   
    }   
  my @output;   
  while (<SAFE_READ>)   
    {   
      chomp;   
      push(@output, $_);   
    }   
  close(SAFE_READ);   
  my $result = $?;   
  my $exit   = $result >> 8;   
  my $signal = $result & 127;   
  my $cd     = $result & 128 ? "with core dump" : "";   
  if ($signal or $cd)   
    {   
      warn "$0: pipe from @_' failed $cd: exit=$exit signal=$signal\n";   
    }   
  if (wantarray)   
    {   
      return ($result, @output);   
    }   
  else   
    {   
      return $result;   
    }   
}   

sub read_from_process   
  {   
  unless (@_)   
    {   
      croak "$0: read_from_process passed no arguments.\n";   
    }   
  my ($status, @output) = &safe_read_from_pipe(@_);   
  if ($status)   
    {   
      if (@output)   
        {   
          die "$0: @_' failed with this output:\n", join("\n", @output), "\n";   
        }   
      else   
        {   
          die "$0: @_' failed with no output.\n";   
        }   
    }   
  else   
    {   
      return @output;   
    }   
}

5 个答案:

答案 0 :(得分:5)

这是一个已知的颠覆错误,我也打了。 http://subversion.tigris.org/issues/show_bug.cgi?id=2487

为了解决我的问题,我使用了vi并执行了以下操作

我通常做一个:设置hls(突出显示搜索结果)后跟/ [^ - 〜] (搜索不在空格和波浪之间的任何字符,即 不是ASCII集中的可打印字符。)您可以添加选项卡 如果使用方括号内的字符(使用Ctrl-V Tab) 你的文件。用蓝色^ I显示为/ [^ - 〜^ I]。

在坎昆发现了一个有口音的人,但实际上并不是合法的拉丁字符。

答案 1 :(得分:2)

我通过编辑/ etc / apache2 / envvars解决了这个问题(在debian上) 并设置apache以使用机器区域设置运行(默认为C):

## The locale used by some modules like mod_dav
export LANG=C
## Uncomment the following line to use the system default locale instead:
#. /etc/default/locale  

^ ----取消注释此行以在apache中设置系统区域设置。

如果您不使用UTF-8语言环境,请手动设置UTF-8语言环境 只是为了apache:

export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

答案 2 :(得分:2)

我也遇到过这个问题而且它正在发生,因为我在提交消息中使用了一些特殊字符。 我刚删除了那些角色,它就像魅力一样。

特别查找撇号字符(当您从word文档中复制文本时)。

答案 3 :(得分:1)

您需要在httpd.conf文件中添加以下行。

SVNUseUTF8 on

你正在使用CentOS吗?这可能是一些操作系统问题,因为几乎不可能只通过谷歌找到这个技巧。

答案 4 :(得分:0)

在后提交脚本或提交消息中查找“或”,并检查它们是否为UTF-8格式。 如果不更改它们,并运行它对我有用。