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>
This commit is contained in:
Michael G. Schwern 2012-07-28 02:38:28 -07:00 committed by Eric Wong
parent 82009f3048
commit 280ad88aa0
2 changed files with 36 additions and 1 deletions

View 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#^/##;

View File

@ -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";
}