Skip to content

Commit f5530b8

Browse files
Eric Wonggitster
authored andcommitted
git-svn: support for funky branch and project names over HTTP(S)
SVN requires that paths be URI-escaped for HTTP(S) repositories. file:// and svn:// repositories do not need these rules. Additionally, accessing individual paths inside repositories (check_path() and get_log() do NOT require escapes to function and in fact it breaks things). Noticed-by: Michael J. Cohen <mjc@cruiseplanners.com> Signed-off-by: Eric Wong <normalperson@yhbt.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 4f3d370 commit f5530b8

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

git-svn.perl

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3068,6 +3068,25 @@ BEGIN
30683068
}
30693069
}
30703070

3071+
sub escape_uri_only {
3072+
my ($uri) = @_;
3073+
my @tmp;
3074+
foreach (split m{/}, $uri) {
3075+
s/([^\w.-])/sprintf("%%%02X",ord($1))/eg;
3076+
push @tmp, $_;
3077+
}
3078+
join('/', @tmp);
3079+
}
3080+
3081+
sub escape_url {
3082+
my ($url) = @_;
3083+
if ($url =~ m#^(https?)://([^/]+)(.*)$#) {
3084+
my ($scheme, $domain, $uri) = ($1, $2, escape_uri_only($3));
3085+
$url = "$scheme://$domain$uri";
3086+
}
3087+
$url;
3088+
}
3089+
30713090
sub new {
30723091
my ($class, $url) = @_;
30733092
$url =~ s!/+$!!;
@@ -3092,10 +3111,11 @@ sub new {
30923111
]);
30933112
my $config = SVN::Core::config_get_config($config_dir);
30943113
$RA = undef;
3095-
my $self = SVN::Ra->new(url => $url, auth => $baton,
3114+
my $self = SVN::Ra->new(url => escape_url($url), auth => $baton,
30963115
config => $config,
30973116
pool => SVN::Pool->new,
30983117
auth_provider_callbacks => $callbacks);
3118+
$self->{url} = $url;
30993119
$self->{svn_path} = $url;
31003120
$self->{repos_root} = $self->get_repos_root;
31013121
$self->{svn_path} =~ s#^\Q$self->{repos_root}\E(/|$)##;
@@ -3203,7 +3223,7 @@ sub gs_do_switch {
32033223

32043224
my $full_url = $self->{url};
32053225
my $old_url = $full_url;
3206-
$full_url .= "/$path" if length $path;
3226+
$full_url .= '/' . escape_uri_only($path) if length $path;
32073227
my ($ra, $reparented);
32083228
if ($old_url ne $full_url) {
32093229
if ($old_url !~ m#^svn(\+ssh)?://#) {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/sh
2+
#
3+
# Copyright (c) 2007 Eric Wong
4+
#
5+
6+
test_description='git-svn funky branch names'
7+
. ./lib-git-svn.sh
8+
9+
test_expect_success 'setup svnrepo' "
10+
mkdir project project/trunk project/branches project/tags &&
11+
echo foo > project/trunk/foo &&
12+
svn import -m '$test_description' project \"$svnrepo/pr ject\" &&
13+
rm -rf project &&
14+
svn cp -m 'fun' \"$svnrepo/pr ject/trunk\" \
15+
\"$svnrepo/pr ject/branches/fun plugin\" &&
16+
svn cp -m 'more fun!' \"$svnrepo/pr ject/branches/fun plugin\" \
17+
\"$svnrepo/pr ject/branches/more fun plugin!\" &&
18+
start_httpd
19+
"
20+
21+
test_expect_success 'test clone with funky branch names' "
22+
git svn clone -s \"$svnrepo/pr ject\" project &&
23+
cd project &&
24+
git rev-parse 'refs/remotes/fun%20plugin' &&
25+
git rev-parse 'refs/remotes/more%20fun%20plugin!' &&
26+
cd ..
27+
"
28+
29+
test_expect_success 'test dcommit to funky branch' "
30+
cd project &&
31+
git reset --hard 'refs/remotes/more%20fun%20plugin!' &&
32+
echo hello >> foo &&
33+
git commit -m 'hello' -- foo &&
34+
git svn dcommit &&
35+
cd ..
36+
"
37+
38+
stop_httpd
39+
40+
test_done

0 commit comments

Comments
 (0)