Skip to content

Commit

Permalink
Merge branch 'jc/maint-add-p-unquote' into maint
Browse files Browse the repository at this point in the history
* jc/maint-add-p-unquote:
  git-add -i/-p: learn to unwrap C-quoted paths
  • Loading branch information
Junio C Hamano committed Mar 11, 2009
2 parents 5f7b338 + 8851f48 commit 6c3b3e1
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 10 deletions.
7 changes: 0 additions & 7 deletions Documentation/git-add.txt
Original file line number Diff line number Diff line change
Expand Up @@ -263,13 +263,6 @@ diff::
This lets you review what will be committed (i.e. between
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
--------
linkgit:git-status[1]
Expand Down
55 changes: 52 additions & 3 deletions git-add--interactive.perl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
use strict;
use Git;

binmode(STDOUT, ":raw");

my $repo = Git->repository();

my $menu_use_color = $repo->get_colorbool('color.interactive');
Expand Down Expand Up @@ -91,6 +93,47 @@ sub run_cmd_pipe {
}
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 {
my $fh;
open $fh, 'git update-index --refresh |'
Expand All @@ -104,7 +147,7 @@ sub refresh {
sub list_untracked {
map {
chomp $_;
$_;
unquote_path($_);
}
run_cmd_pipe(qw(git ls-files --others --exclude-standard --), @ARGV);
}
Expand Down Expand Up @@ -141,7 +184,8 @@ sub list_modified {

if (@ARGV) {
@tracked = map {
chomp $_; $_;
chomp $_;
unquote_path($_);
} run_cmd_pipe(qw(git ls-files --exclude-standard --), @ARGV);
return if (!@tracked);
}
Expand All @@ -153,6 +197,7 @@ sub list_modified {
if (($add, $del, $file) =
/^([-\d]+) ([-\d]+) (.*)/) {
my ($change, $bin);
$file = unquote_path($file);
if ($add eq '-' && $del eq '-') {
$change = 'binary';
$bin = 1;
Expand All @@ -168,13 +213,15 @@ sub list_modified {
}
elsif (($adddel, $file) =
/^ (create|delete) mode [0-7]+ (.*)$/) {
$file = unquote_path($file);
$data{$file}{INDEX_ADDDEL} = $adddel;
}
}

for (run_cmd_pipe(qw(git diff-files --numstat --summary --), @tracked)) {
if (($add, $del, $file) =
/^([-\d]+) ([-\d]+) (.*)/) {
$file = unquote_path($file);
if (!exists $data{$file}) {
$data{$file} = +{
INDEX => 'unchanged',
Expand All @@ -196,6 +243,7 @@ sub list_modified {
}
elsif (($adddel, $file) =
/^ (create|delete) mode [0-7]+ (.*)$/) {
$file = unquote_path($file);
$data{$file}{FILE_ADDDEL} = $adddel;
}
}
Expand Down Expand Up @@ -302,7 +350,8 @@ sub find_unique_prefixes {
}
%search = %{$search{$letter}};
}
if ($soft_limit && $j + 1 > $soft_limit) {
if (ord($letters[0]) > 127 ||
($soft_limit && $j + 1 > $soft_limit)) {
$prefix = undef;
$remainder = $ret;
}
Expand Down

0 comments on commit 6c3b3e1

Please sign in to comment.