git-svn: fix ls-tree usage with dash-prefixed paths
To find the blob object name given a tree and pathname, we were incorrectly calling "git ls-tree" with a "--" argument followed by the pathname of the file we wanted to get. git ls-tree <TREE> -- --dashed/path/name.c Unlike many command-line interfaces, the "--" alone does not symbolize the end of non-option arguments on the command-line. ls-tree interprets the "--" as a prefix to match against, thus the entire contents of the --dashed/* hierarchy would be returned because the "--" matches "--dashed" and every path under it. Thanks to Anton Gyllenberg for pointing me toward the Twisted repository as a real-world example of this case. Signed-off-by: Eric Wong <normalperson@yhbt.net>
Eric Wong committed
Mar 28, 2009 at 22:10 UTC
4f821012c3feb7c0a36be3849e971fbeff4fbc3b
1 file changed
+9
-6
git-svn.perl
+9
-6
@@ -3387,15 +3387,18 @@ sub delete_entry {
3387
return undef if ($gpath eq '');
3388
3389
# remove entire directories.
3390
- if (command('ls-tree', $self->{c}, '--', $gpath) =~ /^040000 tree/) {
3390
+ my ($tree) = (command('ls-tree', '-z', $self->{c}, "./$gpath")
3391
+ =~ /\A040000 tree ([a-f\d]{40})\t\Q$gpath\E\0/);
3392
+ if ($tree) {
3393
my ($ls, $ctx) = command_output_pipe(qw/ls-tree
3394
-r --name-only -z/,
3393
- $self->{c}, '--', $gpath);
3395
+ $tree);
3396
local $/ = "\0";
3397
while (<$ls>) {
3398
chomp;
3397
- $self->{gii}->remove($_);
3398
- print "\tD\t$_\n" unless $::_q;
3399
+ my $rmpath = "$gpath/$_";
3400
+ $self->{gii}->remove($rmpath);
3401
+ print "\tD\t$rmpath\n" unless $::_q;
3402
}
3403
print "\tD\t$gpath/\n" unless $::_q;
3404
command_close_pipe($ls, $ctx);
@@ -3414,8 +3417,8 @@ sub open_file {
3417
goto out if is_path_ignored($path);
3418
3419
my $gpath = $self->git_path($path);
3417
- ($mode, $blob) = (command('ls-tree', $self->{c}, '--', $gpath)
3418
- =~ /^(\d{6}) blob ([a-f\d]{40})\t/);
3420
+ ($mode, $blob) = (command('ls-tree', '-z', $self->{c}, "./$gpath")
3421
+ =~ /\A(\d{6}) blob ([a-f\d]{40})\t\Q$gpath\E\0/);
3422
unless (defined $mode && defined $blob) {
3423
die "$path was not found in commit $self->{c} (r$rev)\n";
3424
}