]> git.ipfire.org Git - thirdparty/git.git/commitdiff
git-svn: factor out _collapse_dotdot function
authorMichael G. Schwern <schwern@pobox.com>
Sat, 28 Jul 2012 09:38:28 +0000 (02:38 -0700)
committerEric Wong <normalperson@yhbt.net>
Thu, 2 Aug 2012 21:43:58 +0000 (21:43 +0000)
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>
perl/Git/SVN/Utils.pm
t/Git-SVN/Utils/collapse_dotdot.t [new file with mode: 0644]

index 246d1aa6010956353e11cee0b6e7e594234ce094..4925410dd1ebed4c279a124a25557fd4c767cd83 100644 (file)
@@ -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 (file)
index 0000000..1da1cce
--- /dev/null
@@ -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";
+}