summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael G. Schwern <schwern@pobox.com>2012-07-28 02:38:28 -0700
committerEric Wong <normalperson@yhbt.net>2012-08-02 21:43:58 +0000
commit280ad88aa0e851b2f2945222edb8e7b681a7574b (patch)
tree4c56e2de4aef88b6887589e3a9add119777ab677
parent82009f304826fcaf3188fb422769a7974ae78afa (diff)
downloadgit-280ad88aa0e851b2f2945222edb8e7b681a7574b.tar.gz
git-svn: factor out _collapse_dotdot function
The SVN API functions will not accept ../foo but their canonicalization functions will not collapse it. So we'll have to do it ourselves. _collapse_dotdot() works better than the existing regex did. This will be used shortly when canonicalize_path() starts using the SVN API. [ew: commit title] Signed-off-by: Eric Wong <normalperson@yhbt.net>
-rw-r--r--perl/Git/SVN/Utils.pm14
-rw-r--r--t/Git-SVN/Utils/collapse_dotdot.t23
2 files changed, 36 insertions, 1 deletions
diff --git a/perl/Git/SVN/Utils.pm b/perl/Git/SVN/Utils.pm
index 246d1aa601..4925410dd1 100644
--- a/perl/Git/SVN/Utils.pm
+++ b/perl/Git/SVN/Utils.pm
@@ -72,6 +72,18 @@ API as a file path.
=cut
+# Turn foo/../bar into bar
+sub _collapse_dotdot {
+ my $path = shift;
+
+ 1 while $path =~ s{/[^/]+/+\.\.}{};
+ 1 while $path =~ s{[^/]+/+\.\./}{};
+ 1 while $path =~ s{[^/]+/+\.\.}{};
+
+ return $path;
+}
+
+
sub canonicalize_path {
my ($path) = @_;
my $dot_slash_added = 0;
@@ -83,7 +95,7 @@ sub canonicalize_path {
# good reason), so let's do this manually.
$path =~ s#/+#/#g;
$path =~ s#/\.(?:/|$)#/#g;
- $path =~ s#/[^/]+/\.\.##g;
+ $path = _collapse_dotdot($path);
$path =~ s#/$##g;
$path =~ s#^\./## if $dot_slash_added;
$path =~ s#^/##;
diff --git a/t/Git-SVN/Utils/collapse_dotdot.t b/t/Git-SVN/Utils/collapse_dotdot.t
new file mode 100644
index 0000000000..1da1cce156
--- /dev/null
+++ b/t/Git-SVN/Utils/collapse_dotdot.t
@@ -0,0 +1,23 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Test::More 'no_plan';
+
+use Git::SVN::Utils;
+my $collapse_dotdot = \&Git::SVN::Utils::_collapse_dotdot;
+
+my %tests = (
+ "foo/bar/baz" => "foo/bar/baz",
+ ".." => "..",
+ "foo/.." => "",
+ "/foo/bar/../../baz" => "/baz",
+ "deeply/.././deeply/nested" => "./deeply/nested",
+);
+
+for my $arg (keys %tests) {
+ my $want = $tests{$arg};
+
+ is $collapse_dotdot->($arg), $want, "_collapse_dotdot('$arg') => $want";
+}