summaryrefslogtreecommitdiff
path: root/perl/Git/SVN/Editor.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl/Git/SVN/Editor.pm')
-rw-r--r--perl/Git/SVN/Editor.pm28
1 files changed, 26 insertions, 2 deletions
diff --git a/perl/Git/SVN/Editor.pm b/perl/Git/SVN/Editor.pm
index 755092f..3db1521 100644
--- a/perl/Git/SVN/Editor.pm
+++ b/perl/Git/SVN/Editor.pm
@@ -145,7 +145,8 @@ sub repo_path {
sub url_path {
my ($self, $path) = @_;
if ($self->{url} =~ m#^https?://#) {
- $path =~ s!([^~a-zA-Z0-9_./-])!uc sprintf("%%%02x",ord($1))!eg;
+ # characters are taken from subversion/libsvn_subr/path.c
+ $path =~ s#([^~a-zA-Z0-9_./!$&'()*+,-])#uc sprintf("%%%02x",ord($1))#eg;
}
$self->{url} . '/' . $self->repo_path($path);
}
@@ -345,7 +346,30 @@ sub M {
$self->close_file($fbat,undef,$self->{pool});
}
-sub T { shift->M(@_) }
+sub T {
+ my ($self, $m, $deletions) = @_;
+
+ # Work around subversion issue 4091: toggling the "is a
+ # symlink" property requires removing and re-adding a
+ # file or else "svn up" on affected clients trips an
+ # assertion and aborts.
+ if (($m->{mode_b} =~ /^120/ && $m->{mode_a} !~ /^120/) ||
+ ($m->{mode_b} !~ /^120/ && $m->{mode_a} =~ /^120/)) {
+ $self->D({
+ mode_a => $m->{mode_a}, mode_b => '000000',
+ sha1_a => $m->{sha1_a}, sha1_b => '0' x 40,
+ chg => 'D', file_b => $m->{file_b}
+ }, $deletions);
+ $self->A({
+ mode_a => '000000', mode_b => $m->{mode_b},
+ sha1_a => '0' x 40, sha1_b => $m->{sha1_b},
+ chg => 'A', file_b => $m->{file_b}
+ }, $deletions);
+ return;
+ }
+
+ $self->M($m, $deletions);
+}
sub change_file_prop {
my ($self, $fbat, $pname, $pval) = @_;