@matheusbsbs / matheus-bagliano / commits / f5530b8833
Fork 0

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>

Eric Wong committed Nov 11, 2007 at 23:37 UTC f5530b8833bcaa423cd53d133d3de3fa0173fbf3
2 files changed +62 -2
git-svn.perl
+22 -2
@@ -3068,6 +3068,25 @@ BEGIN {
3068 }
3069 }
3070
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 +
3090 sub new {
3091 my ($class, $url) = @_;
3092 $url =~ s!/+$!!;
@@ -3092,10 +3111,11 @@ sub new {
3111 ]);
3112 my $config = SVN::Core::config_get_config($config_dir);
3113 $RA = undef;
3095 - my $self = SVN::Ra->new(url => $url, auth => $baton,
3114 + my $self = SVN::Ra->new(url => escape_url($url), auth => $baton,
3115 config => $config,
3116 pool => SVN::Pool->new,
3117 auth_provider_callbacks => $callbacks);
3118 + $self->{url} = $url;
3119 $self->{svn_path} = $url;
3120 $self->{repos_root} = $self->get_repos_root;
3121 $self->{svn_path} =~ s#^\Q$self->{repos_root}\E(/|$)##;
@@ -3203,7 +3223,7 @@ sub gs_do_switch {
3223
3224 my $full_url = $self->{url};
3225 my $old_url = $full_url;
3206 - $full_url .= "/$path" if length $path;
3226 + $full_url .= '/' . escape_uri_only($path) if length $path;
3227 my ($ra, $reparented);
3228 if ($old_url ne $full_url) {
3229 if ($old_url !~ m#^svn(\+ssh)?://#) {
t/t9118-git-svn-funky-branch-names.sh new
+40
@@ -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