From: Junio C Hamano <gitster@pobox.com>
To: Jeff King <peff@peff.net>
Cc: Teemu Likonen <tlikonen@iki.fi>, git@vger.kernel.org
Subject: [PATCH] git-add -i/-p: learn to unwrap C-quoted paths
Date: Mon, 16 Feb 2009 23:02:35 -0800 [thread overview]
Message-ID: <7v3aeda6lw.fsf_-_@gitster.siamese.dyndns.org> (raw)
In-Reply-To: <7v63jbf2v0.fsf@gitster.siamese.dyndns.org> (Junio C. Hamano's message of "Sun, 15 Feb 2009 20:00:03 -0800")
The underlying plumbing commands are not run with -z option, so the paths
returned from them need to be unquoted as needed.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Junio C Hamano <gitster@pobox.com> writes:
> I did not spell the specifics out because this change won't happen in any
> near future anyway, but my thinking was to give a way for "add -p" to
> either (1) internally run without quotepath regardless of the user's
> settings or (2) unquote the paths correctly when it learns the set of
> paths affected by the change.
>
> I think the right approach is (2), because you need to unquote pathnames
> with some byte values that even with core.quotepath=false will not pass
> unquoted *anyway*.
I deliberately avoided using :utf8 because pathnames to git are always
binary text, not necessarily utf8, and for the same reason I dropped the
"shortcut by first character", as the pathnames are stored as raw
sequence of bytes and using the first byte is obviously wrong. It would
be very much welcomed if somebody feels inclined to test and polish it.
This hopefully makes the discussion on default value for core.quotepath
independent of "git-add -i/-p".
git-add--interactive.perl | 55 ++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 52 insertions(+), 3 deletions(-)
diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index 5f129a4..064d4c6 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -3,6 +3,8 @@
use strict;
use Git;
+binmode(STDOUT, ":raw");
+
my $repo = Git->repository();
my $menu_use_color = $repo->get_colorbool('color.interactive');
@@ -91,6 +93,47 @@ if (!defined $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 {
my $fh;
open $fh, 'git update-index --refresh |'
@@ -104,7 +147,7 @@ sub refresh {
sub list_untracked {
map {
chomp $_;
- $_;
+ unquote_path($_);
}
run_cmd_pipe(qw(git ls-files --others --exclude-standard --), @ARGV);
}
@@ -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);
}
@@ -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;
@@ -168,6 +213,7 @@ sub list_modified {
}
elsif (($adddel, $file) =
/^ (create|delete) mode [0-7]+ (.*)$/) {
+ $file = unquote_path($file);
$data{$file}{INDEX_ADDDEL} = $adddel;
}
}
@@ -175,6 +221,7 @@ sub list_modified {
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',
@@ -196,6 +243,7 @@ sub list_modified {
}
elsif (($adddel, $file) =
/^ (create|delete) mode [0-7]+ (.*)$/) {
+ $file = unquote_path($file);
$data{$file}{FILE_ADDDEL} = $adddel;
}
}
@@ -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;
}
--
1.6.2.rc1.47.g30e1d8
next prev parent reply other threads:[~2009-02-17 7:04 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-02-15 18:40 "add -p" + filenames with UTF-8 multibyte characters = "No changes" Antonio García Domínguez
2009-02-15 18:59 ` Teemu Likonen
[not found] ` <2b8265360902151100n2eca0182odf9543c1dd8a7f98@mail.gmail.com>
2009-02-15 19:11 ` Teemu Likonen
2009-02-16 3:36 ` Jeff King
2009-02-16 4:00 ` Junio C Hamano
2009-02-17 7:02 ` Junio C Hamano [this message]
2009-02-17 8:09 ` [PATCH] git-add -i/-p: learn to unwrap C-quoted paths Teemu Likonen
2009-02-16 5:13 ` "add -p" + filenames with UTF-8 multibyte characters = "No changes" Teemu Likonen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7v3aeda6lw.fsf_-_@gitster.siamese.dyndns.org \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=peff@peff.net \
--cc=tlikonen@iki.fi \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).