Merge branch 'cn/branch-set-upstream-to'
[gitweb.git] / perl / Git / SVN / Utils.pm
index f0b1b53a3ff98d044db98fd3939cab6862e234c1..4bb4dde89a3821ad7714c299b429f751cc98ebcc 100644 (file)
@@ -13,6 +13,7 @@ package Git::SVN::Utils;
        canonicalize_path
        canonicalize_url
        join_paths
+       add_path_to_url
 );
 
 
@@ -150,10 +151,25 @@ sub canonicalize_url {
 }
 
 
+sub _canonicalize_url_path {
+       my ($uri_path) = @_;
+
+       my @parts;
+       foreach my $part (split m{/+}, $uri_path) {
+               $part =~ s/([^~\w.%+-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg;
+               push @parts, $part;
+       }
+
+       return join('/', @parts);
+}
+
 sub _canonicalize_url_ourselves {
        my ($url) = @_;
-       $url =~ s#^([^:]+://[^/]*/)(.*)$#$1 . canonicalize_path($2)#e;
-       return $url;
+       if ($url =~ m#^([^:]+)://([^/]*)(.*)$#) {
+               my ($scheme, $domain, $uri) = ($1, $2, _canonicalize_url_path(canonicalize_path($3)));
+               $url = "$scheme://$domain$uri";
+       }
+       $url;
 }
 
 
@@ -188,4 +204,30 @@ sub join_paths {
        return $new_path .= "/$last_path";
 }
 
+
+=head3 add_path_to_url
+
+    my $new_url = add_path_to_url($url, $path);
+
+Appends $path onto the $url.  If $path is empty, $url is returned unchanged.
+
+=cut
+
+sub add_path_to_url {
+       my($url, $path) = @_;
+
+       return $url if !defined $path or !length $path;
+
+       # Strip trailing and leading slashes so we don't
+       # wind up with http://x.com///path
+       $url  =~ s{/+$}{};
+       $path =~ s{^/+}{};
+
+       # If a path has a % in it, URI escape it so it's not
+       # mistaken for a URI escape later.
+       $path =~ s{%}{%25}g;
+
+       return join '/', $url, $path;
+}
+
 1;