git-add -i/-p: learn to unwrap C-quoted paths
The underlying plumbing commands are not run with -z option, so the paths returned from them need to be unquoted as needed. Remove the now stale BUGS section from git-add documentaiton as suggested by Teemu Likonen. Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
1b7e543a6e
commit
8851f4800c
@ -263,13 +263,6 @@ diff::
|
|||||||
This lets you review what will be committed (i.e. between
|
This lets you review what will be committed (i.e. between
|
||||||
HEAD and index).
|
HEAD and index).
|
||||||
|
|
||||||
Bugs
|
|
||||||
----
|
|
||||||
The interactive mode does not work with files whose names contain
|
|
||||||
characters that need C-quoting. `core.quotepath` configuration can be
|
|
||||||
used to work this limitation around to some degree, but backslash,
|
|
||||||
double-quote and control characters will still have problems.
|
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
--------
|
--------
|
||||||
linkgit:git-status[1]
|
linkgit:git-status[1]
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
use strict;
|
use strict;
|
||||||
use Git;
|
use Git;
|
||||||
|
|
||||||
|
binmode(STDOUT, ":raw");
|
||||||
|
|
||||||
my $repo = Git->repository();
|
my $repo = Git->repository();
|
||||||
|
|
||||||
my $menu_use_color = $repo->get_colorbool('color.interactive');
|
my $menu_use_color = $repo->get_colorbool('color.interactive');
|
||||||
@ -91,6 +93,47 @@ if (!defined $GIT_DIR) {
|
|||||||
}
|
}
|
||||||
chomp($GIT_DIR);
|
chomp($GIT_DIR);
|
||||||
|
|
||||||
|
my %cquote_map = (
|
||||||
|
"b" => chr(8),
|
||||||
|
"t" => chr(9),
|
||||||
|
"n" => chr(10),
|
||||||
|
"v" => chr(11),
|
||||||
|
"f" => chr(12),
|
||||||
|
"r" => chr(13),
|
||||||
|
"\\" => "\\",
|
||||||
|
"\042" => "\042",
|
||||||
|
);
|
||||||
|
|
||||||
|
sub unquote_path {
|
||||||
|
local ($_) = @_;
|
||||||
|
my ($retval, $remainder);
|
||||||
|
if (!/^\042(.*)\042$/) {
|
||||||
|
return $_;
|
||||||
|
}
|
||||||
|
($_, $retval) = ($1, "");
|
||||||
|
while (/^([^\\]*)\\(.*)$/) {
|
||||||
|
$remainder = $2;
|
||||||
|
$retval .= $1;
|
||||||
|
for ($remainder) {
|
||||||
|
if (/^([0-3][0-7][0-7])(.*)$/) {
|
||||||
|
$retval .= chr(oct($1));
|
||||||
|
$_ = $2;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
if (/^([\\\042btnvfr])(.*)$/) {
|
||||||
|
$retval .= $cquote_map{$1};
|
||||||
|
$_ = $2;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
# This is malformed -- just return it as-is for now.
|
||||||
|
return $_[0];
|
||||||
|
}
|
||||||
|
$_ = $remainder;
|
||||||
|
}
|
||||||
|
$retval .= $_;
|
||||||
|
return $retval;
|
||||||
|
}
|
||||||
|
|
||||||
sub refresh {
|
sub refresh {
|
||||||
my $fh;
|
my $fh;
|
||||||
open $fh, 'git update-index --refresh |'
|
open $fh, 'git update-index --refresh |'
|
||||||
@ -104,7 +147,7 @@ sub refresh {
|
|||||||
sub list_untracked {
|
sub list_untracked {
|
||||||
map {
|
map {
|
||||||
chomp $_;
|
chomp $_;
|
||||||
$_;
|
unquote_path($_);
|
||||||
}
|
}
|
||||||
run_cmd_pipe(qw(git ls-files --others --exclude-standard --), @ARGV);
|
run_cmd_pipe(qw(git ls-files --others --exclude-standard --), @ARGV);
|
||||||
}
|
}
|
||||||
@ -141,7 +184,8 @@ sub list_modified {
|
|||||||
|
|
||||||
if (@ARGV) {
|
if (@ARGV) {
|
||||||
@tracked = map {
|
@tracked = map {
|
||||||
chomp $_; $_;
|
chomp $_;
|
||||||
|
unquote_path($_);
|
||||||
} run_cmd_pipe(qw(git ls-files --exclude-standard --), @ARGV);
|
} run_cmd_pipe(qw(git ls-files --exclude-standard --), @ARGV);
|
||||||
return if (!@tracked);
|
return if (!@tracked);
|
||||||
}
|
}
|
||||||
@ -153,6 +197,7 @@ sub list_modified {
|
|||||||
if (($add, $del, $file) =
|
if (($add, $del, $file) =
|
||||||
/^([-\d]+) ([-\d]+) (.*)/) {
|
/^([-\d]+) ([-\d]+) (.*)/) {
|
||||||
my ($change, $bin);
|
my ($change, $bin);
|
||||||
|
$file = unquote_path($file);
|
||||||
if ($add eq '-' && $del eq '-') {
|
if ($add eq '-' && $del eq '-') {
|
||||||
$change = 'binary';
|
$change = 'binary';
|
||||||
$bin = 1;
|
$bin = 1;
|
||||||
@ -168,6 +213,7 @@ sub list_modified {
|
|||||||
}
|
}
|
||||||
elsif (($adddel, $file) =
|
elsif (($adddel, $file) =
|
||||||
/^ (create|delete) mode [0-7]+ (.*)$/) {
|
/^ (create|delete) mode [0-7]+ (.*)$/) {
|
||||||
|
$file = unquote_path($file);
|
||||||
$data{$file}{INDEX_ADDDEL} = $adddel;
|
$data{$file}{INDEX_ADDDEL} = $adddel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,6 +221,7 @@ sub list_modified {
|
|||||||
for (run_cmd_pipe(qw(git diff-files --numstat --summary --), @tracked)) {
|
for (run_cmd_pipe(qw(git diff-files --numstat --summary --), @tracked)) {
|
||||||
if (($add, $del, $file) =
|
if (($add, $del, $file) =
|
||||||
/^([-\d]+) ([-\d]+) (.*)/) {
|
/^([-\d]+) ([-\d]+) (.*)/) {
|
||||||
|
$file = unquote_path($file);
|
||||||
if (!exists $data{$file}) {
|
if (!exists $data{$file}) {
|
||||||
$data{$file} = +{
|
$data{$file} = +{
|
||||||
INDEX => 'unchanged',
|
INDEX => 'unchanged',
|
||||||
@ -196,6 +243,7 @@ sub list_modified {
|
|||||||
}
|
}
|
||||||
elsif (($adddel, $file) =
|
elsif (($adddel, $file) =
|
||||||
/^ (create|delete) mode [0-7]+ (.*)$/) {
|
/^ (create|delete) mode [0-7]+ (.*)$/) {
|
||||||
|
$file = unquote_path($file);
|
||||||
$data{$file}{FILE_ADDDEL} = $adddel;
|
$data{$file}{FILE_ADDDEL} = $adddel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -302,7 +350,8 @@ sub find_unique_prefixes {
|
|||||||
}
|
}
|
||||||
%search = %{$search{$letter}};
|
%search = %{$search{$letter}};
|
||||||
}
|
}
|
||||||
if ($soft_limit && $j + 1 > $soft_limit) {
|
if (ord($letters[0]) > 127 ||
|
||||||
|
($soft_limit && $j + 1 > $soft_limit)) {
|
||||||
$prefix = undef;
|
$prefix = undef;
|
||||||
$remainder = $ret;
|
$remainder = $ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user