Skip to content

Commit

Permalink
git svn: info: correctly handle absolute path args
Browse files Browse the repository at this point in the history
Calling "git svn info $(pwd)" would hit:
  "Reading from filehandle failed at ..."
errors due to improper prefixing and canonicalization.

Strip the toplevel path from absolute filesystem paths to ensure
downstream canonicalization routines are only exposed to paths
tracked in git (or SVN).

v2:
  Thanks to Andrej Manduch for originally noticing the issue
  and fixing my original version of this to handle
  more corner cases such as "/path/to/top/../top" and
  "/path/to/top/../top/file" as shown in the new test cases.

v3:
  Fix pathname portability problems pointed out by Johannes Sixt
  with a hint from brian m. carlson.

Cc: Johannes Sixt <j6t@kdbg.org>
Cc: "brian m. carlson" <sandals@crustytoothpaste.net>
Signed-off-by: Andrej Manduch <amanduch@gmail.com>
Signed-off-by: Eric Wong <normalperson@yhbt.net>
  • Loading branch information
Eric Wong committed Sep 14, 2014
1 parent 785a1c8 commit 4950eed
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 6 deletions.
39 changes: 33 additions & 6 deletions git-svn.perl
Original file line number Diff line number Diff line change
Expand Up @@ -1477,10 +1477,37 @@ sub cmd_commit_diff {
}
}


sub cmd_info {
my $path = canonicalize_path(defined($_[0]) ? $_[0] : ".");
my $fullpath = canonicalize_path($cmd_dir_prefix . $path);
my $path_arg = defined($_[0]) ? $_[0] : '.';
my $path = $path_arg;
if (File::Spec->file_name_is_absolute($path)) {
$path = canonicalize_path($path);

my $toplevel = eval {
my @cmd = qw/rev-parse --show-toplevel/;
command_oneline(\@cmd, STDERR => 0);
};

# remove $toplevel from the absolute path:
my ($vol, $dirs, $file) = File::Spec->splitpath($path);
my (undef, $tdirs, $tfile) = File::Spec->splitpath($toplevel);
my @dirs = File::Spec->splitdir($dirs);
my @tdirs = File::Spec->splitdir($tdirs);
pop @dirs if $dirs[-1] eq '';
pop @tdirs if $tdirs[-1] eq '';
push @dirs, $file;
push @tdirs, $tfile;
while (@tdirs && @dirs && $tdirs[0] eq $dirs[0]) {
shift @dirs;
shift @tdirs;
}
$dirs = File::Spec->catdir(@dirs);
$path = File::Spec->catpath($vol, $dirs);

$path = canonicalize_path($path);
} else {
$path = canonicalize_path($cmd_dir_prefix . $path);
}
if (exists $_[1]) {
die "Too many arguments specified\n";
}
Expand All @@ -1501,14 +1528,14 @@ sub cmd_info {
# canonicalize_path() will return "" to make libsvn 1.5.x happy,
$path = "." if $path eq "";

my $full_url = canonicalize_url( add_path_to_url( $url, $fullpath ) );
my $full_url = canonicalize_url( add_path_to_url( $url, $path ) );

if ($_url) {
print "$full_url\n";
return;
}

my $result = "Path: $path\n";
my $result = "Path: $path_arg\n";
$result .= "Name: " . basename($path) . "\n" if $file_type ne "dir";
$result .= "URL: $full_url\n";

Expand Down Expand Up @@ -1539,7 +1566,7 @@ sub cmd_info {
}

my ($lc_author, $lc_rev, $lc_date_utc);
my @args = Git::SVN::Log::git_svn_log_cmd($rev, $rev, "--", $fullpath);
my @args = Git::SVN::Log::git_svn_log_cmd($rev, $rev, "--", $path);
my $log = command_output_pipe(@args);
my $esc_color = qr/(?:\033\[(?:(?:\d+;)*\d*)?m)*/;
while (<$log>) {
Expand Down
30 changes: 30 additions & 0 deletions t/t9119-git-svn-info.sh
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,36 @@ test_expect_success 'info .' "
test_cmp_info expected.info-dot actual.info-dot
"

test_expect_success 'info $(pwd)' '
(cd svnwc; svn info "$(pwd)") >expected.info-pwd &&
(cd gitwc; git svn info "$(pwd)") >actual.info-pwd &&
grep -v ^Path: <expected.info-pwd >expected.info-np &&
grep -v ^Path: <actual.info-pwd >actual.info-np &&
test_cmp_info expected.info-np actual.info-np &&
test "$(sed -ne \"/^Path:/ s!/svnwc!!\" <expected.info-pwd)" = \
"$(sed -ne \"/^Path:/ s!/gitwc!!\" <actual.info-pwd)"
'

test_expect_success 'info $(pwd)/../___wc' '
(cd svnwc; svn info "$(pwd)/../svnwc") >expected.info-pwd &&
(cd gitwc; git svn info "$(pwd)/../gitwc") >actual.info-pwd &&
grep -v ^Path: <expected.info-pwd >expected.info-np &&
grep -v ^Path: <actual.info-pwd >actual.info-np &&
test_cmp_info expected.info-np actual.info-np &&
test "$(sed -ne \"/^Path:/ s!/svnwc!!\" <expected.info-pwd)" = \
"$(sed -ne \"/^Path:/ s!/gitwc!!\" <actual.info-pwd)"
'

test_expect_success 'info $(pwd)/../___wc//file' '
(cd svnwc; svn info "$(pwd)/../svnwc//file") >expected.info-pwd &&
(cd gitwc; git svn info "$(pwd)/../gitwc//file") >actual.info-pwd &&
grep -v ^Path: <expected.info-pwd >expected.info-np &&
grep -v ^Path: <actual.info-pwd >actual.info-np &&
test_cmp_info expected.info-np actual.info-np &&
test "$(sed -ne \"/^Path:/ s!/svnwc!!\" <expected.info-pwd)" = \
"$(sed -ne \"/^Path:/ s!/gitwc!!\" <actual.info-pwd)"
'

test_expect_success 'info --url .' '
test "$(cd gitwc; git svn info --url .)" = "$quoted_svnrepo"
'
Expand Down

0 comments on commit 4950eed

Please sign in to comment.