Skip to content

Commit bf655fd

Browse files
Robert Ewaldgitster
authored andcommitted
git-svn: Translate invalid characters in refname
In git some characters are invalid as documented in git-check-ref-format. In subversion these characters might be valid, so a translation is required. This patch does this translation by url escaping characters, that are not allowed. Credit goes to Eric Wong, martin f. krafft and Jan Hudec Signed-off-by: Robert Ewald <[email protected]> Acked-by: Eric Wong <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 299726d commit bf655fd

File tree

1 file changed

+36
-3
lines changed

1 file changed

+36
-3
lines changed

git-svn.perl

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -938,8 +938,8 @@ sub resolve_local_globs {
938938
foreach (command(qw#for-each-ref --format=%(refname) refs/remotes#)) {
939939
next unless m#^refs/remotes/$ref->{regex}$#;
940940
my $p = $1;
941-
my $pathname = $path->full_path($p);
942-
my $refname = $ref->full_path($p);
941+
my $pathname = desanitize_refname($path->full_path($p));
942+
my $refname = desanitize_refname($ref->full_path($p));
943943
if (my $existing = $fetch->{$pathname}) {
944944
if ($existing ne $refname) {
945945
die "Refspec conflict:\n",
@@ -1239,7 +1239,40 @@ sub new {
12391239
$self;
12401240
}
12411241

1242-
sub refname { "refs/remotes/$_[0]->{ref_id}" }
1242+
sub refname {
1243+
my ($refname) = "refs/remotes/$_[0]->{ref_id}" ;
1244+
1245+
# It cannot end with a slash /, we'll throw up on this because
1246+
# SVN can't have directories with a slash in their name, either:
1247+
if ($refname =~ m{/$}) {
1248+
die "ref: '$refname' ends with a trailing slash, this is ",
1249+
"not permitted by git nor Subversion\n";
1250+
}
1251+
1252+
# It cannot have ASCII control character space, tilde ~, caret ^,
1253+
# colon :, question-mark ?, asterisk *, space, or open bracket [
1254+
# anywhere.
1255+
#
1256+
# Additionally, % must be escaped because it is used for escaping
1257+
# and we want our escaped refname to be reversible
1258+
$refname =~ s{([ \%~\^:\?\*\[\t])}{uc sprintf('%%%02x',ord($1))}eg;
1259+
1260+
# no slash-separated component can begin with a dot .
1261+
# /.* becomes /%2E*
1262+
$refname =~ s{/\.}{/%2E}g;
1263+
1264+
# It cannot have two consecutive dots .. anywhere
1265+
# .. becomes %2E%2E
1266+
$refname =~ s{\.\.}{%2E%2E}g;
1267+
1268+
return $refname;
1269+
}
1270+
1271+
sub desanitize_refname {
1272+
my ($refname) = @_;
1273+
$refname =~ s{%(?:([0-9A-F]{2}))}{chr hex($1)}eg;
1274+
return $refname;
1275+
}
12431276

12441277
sub svm_uuid {
12451278
my ($self) = @_;

0 commit comments

Comments
 (0)