{"thread":{"id":"46229","subject":"[PATCH 2/5] Git::unquote_path() Handle '\\a'","startedAt":"2017-06-22T10:27:08Z","lastAt":"2017-06-30T15:06:29Z","messageCount":17,"participants":["Phillip Wood","Junio C Hamano","Jeff King"],"isPatch":true,"patchVersion":1,"patchTotal":5},"messages":[{"id":"322918","messageId":"20170622102622.26147-3-phillip.wood@talktalk.net","threadId":"46229","inReplyTo":"20170622102622.26147-1-phillip.wood@talktalk.net","subject":"[PATCH 2/5] Git::unquote_path() Handle '\\a'","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-06-22T10:26:19Z","receivedAt":"2017-06-22T10:27:08Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThe version copied from git-add--interactive did not handle quoted\npaths containing '\\a'.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n perl/Git.pm | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/perl/Git.pm b/perl/Git.pm\nindex 8afde87fc8162271ba178e0fff3e921f070ac621..889bf88cfcd34136e24e166fb3b72cced6debf9d 100644\n--- a/perl/Git.pm\n+++ b/perl/Git.pm\n@@ -1461,6 +1461,7 @@ when not using -z\n \n {\n \tmy %unquote_map = (\n+\t\t\"a\" => chr(7),\n \t\t\"b\" => chr(8),\n \t\t\"t\" => chr(9),\n \t\t\"n\" => chr(10),\n@@ -1487,7 +1488,7 @@ when not using -z\n \t\t\t\t\t$_ = $2;\n \t\t\t\t\tlast;\n \t\t\t\t}\n-\t\t\t\tif (/^([\\\\\\042btnvfr])(.*)$/) {\n+\t\t\t\tif (/^([\\\\\\042abtnvfr])(.*)$/) {\n \t\t\t\t\t$retval .= $unquote_map{$1};\n \t\t\t\t\t$_ = $2;\n \t\t\t\t\tlast;\n-- \n2.13.0\n\n"},{"id":"322919","messageId":"20170622102622.26147-2-phillip.wood@talktalk.net","threadId":"46229","inReplyTo":"20170622102622.26147-1-phillip.wood@talktalk.net","subject":"[PATCH 1/5] Git.pm Add unquote_path()","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-06-22T10:26:18Z","receivedAt":"2017-06-22T10:27:09Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nAdd unquote_path() from git-add--interactive so it can be used by\nother scripts. Note this is a straight copy, it does not handle\n'\\a'. That will be fixed in the next commit\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n perl/Git.pm | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++-\n 1 file changed, 52 insertions(+), 1 deletion(-)\n\ndiff --git a/perl/Git.pm b/perl/Git.pm\nindex bfce1f795dfa5fea05f4f96637a1ae2333038735..8afde87fc8162271ba178e0fff3e921f070ac621 100644\n--- a/perl/Git.pm\n+++ b/perl/Git.pm\n@@ -61,7 +61,8 @@ require Exporter;\n                 remote_refs prompt\n                 get_tz_offset get_record\n                 credential credential_read credential_write\n-                temp_acquire temp_is_locked temp_release temp_reset temp_path);\n+                temp_acquire temp_is_locked temp_release temp_reset temp_path\n+                unquote_path);\n \n \n =head1 DESCRIPTION\n@@ -1451,6 +1452,56 @@ sub prefix_lines {\n \treturn $string;\n }\n \n+=item unquote_path ( PATH )\n+\n+Unquote a quoted path containing c-escapes as returned by ls-files etc.\n+when not using -z\n+\n+=cut\n+\n+{\n+\tmy %unquote_map = (\n+\t\t\"b\" => chr(8),\n+\t\t\"t\" => chr(9),\n+\t\t\"n\" => chr(10),\n+\t\t\"v\" => chr(11),\n+\t\t\"f\" => chr(12),\n+\t\t\"r\" => chr(13),\n+\t\t\"\\\\\" => \"\\\\\",\n+\t\t\"\\\"\" => \"\\\"\"\n+\t);\n+\n+\tsub unquote_path {\n+\t\tlocal ($_) = @_;\n+\t\tmy ($retval, $remainder);\n+\t\tif (!/^\\042(.*)\\042$/) {\n+\t\t\treturn $_;\n+\t\t}\n+\t\t($_, $retval) = ($1, \"\");\n+\t\twhile (/^([^\\\\]*)\\\\(.*)$/) {\n+\t\t\t$remainder = $2;\n+\t\t\t$retval .= $1;\n+\t\t\tfor ($remainder) {\n+\t\t\t\tif (/^([0-3][0-7][0-7])(.*)$/) {\n+\t\t\t\t\t$retval .= chr(oct($1));\n+\t\t\t\t\t$_ = $2;\n+\t\t\t\t\tlast;\n+\t\t\t\t}\n+\t\t\t\tif (/^([\\\\\\042btnvfr])(.*)$/) {\n+\t\t\t\t\t$retval .= $unquote_map{$1};\n+\t\t\t\t\t$_ = $2;\n+\t\t\t\t\tlast;\n+\t\t\t\t}\n+\t\t\t\t# This is malformed -- just return it as-is for now.\n+\t\t\t\treturn $_[0];\n+\t\t\t}\n+\t\t\t$_ = $remainder;\n+\t\t}\n+\t\t$retval .= $_;\n+\t\treturn $retval;\n+\t}\n+}\n+\n =item get_comment_line_char ( )\n \n Gets the core.commentchar configuration value.\n-- \n2.13.0\n\n"},{"id":"322920","messageId":"20170622102622.26147-1-phillip.wood@talktalk.net","threadId":"46229","inReplyTo":null,"subject":"[PATCH 0/5] Move unquote_path() from git-add--interactive.perl to Git.pm","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-06-22T10:26:17Z","receivedAt":"2017-06-22T10:27:11Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nI'm using this in some scripts and it would be more convenient to have\nit available from Git.pm rather than copying and pasting it each time\nI need it. I think it should be useful to other people using Git.pm as\nwell. It is not uncommon to get a quoted path back from a command that\nneeds to be passed on the commandline of another command. While one\ncan use -z in many cases, that leaves the problem of having to quote\nthe path when printing it in error messages etc.\n\nPhillip Wood (5):\n  Git.pm Add unquote_path()\n  Git::unquote_path() Handle '\\a'\n  Git::unquote_path() throw an exception on bad path\n  Add tests for Git::unquote_path()\n  git-add--interactive.perl: Use unquote_path() from Git.pm\n\n git-add--interactive.perl | 43 +------------------------------------\n perl/Git.pm               | 54 ++++++++++++++++++++++++++++++++++++++++++++++-\n t/t9700/test.pl           |  7 ++++++\n 3 files changed, 61 insertions(+), 43 deletions(-)\n\n-- \n2.13.0\n\n"},{"id":"322921","messageId":"20170622102622.26147-4-phillip.wood@talktalk.net","threadId":"46229","inReplyTo":"20170622102622.26147-1-phillip.wood@talktalk.net","subject":"[PATCH 3/5] Git::unquote_path() throw an exception on bad path","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-06-22T10:26:20Z","receivedAt":"2017-06-22T10:27:12Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThis is what the other routines in Git.pm do if there's an error.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n perl/Git.pm | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/perl/Git.pm b/perl/Git.pm\nindex 889bf88cfcd34136e24e166fb3b72cced6debf9d..51cb3446088dd12e8fd93d47b95e29fab22a8466 100644\n--- a/perl/Git.pm\n+++ b/perl/Git.pm\n@@ -1493,8 +1493,8 @@ when not using -z\n \t\t\t\t\t$_ = $2;\n \t\t\t\t\tlast;\n \t\t\t\t}\n-\t\t\t\t# This is malformed -- just return it as-is for now.\n-\t\t\t\treturn $_[0];\n+\t\t\t\t# This is malformed\n+\t\t\t\tthrow Error::Simple(\"Invalid quoted path $_[0]\");\n \t\t\t}\n \t\t\t$_ = $remainder;\n \t\t}\n-- \n2.13.0\n\n"},{"id":"322922","messageId":"20170622102622.26147-6-phillip.wood@talktalk.net","threadId":"46229","inReplyTo":"20170622102622.26147-1-phillip.wood@talktalk.net","subject":"[PATCH 5/5] git-add--interactive.perl: Use unquote_path() from Git.pm","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-06-22T10:26:22Z","receivedAt":"2017-06-22T10:27:13Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nNot that we've copied unquote_path() to Git.pm use that copy instead\nof our own.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n git-add--interactive.perl | 43 +------------------------------------------\n 1 file changed, 1 insertion(+), 42 deletions(-)\n\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex 709a5f6ce6fbdb2da14084e94ae9df1db1c3d0a6..7ea3591edc056d4405b1f18800ffd2d0b351f93c 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -3,7 +3,7 @@\n use 5.008;\n use strict;\n use warnings;\n-use Git;\n+use Git qw(unquote_path);\n use Git::I18N;\n \n binmode(STDOUT, \":raw\");\n@@ -175,47 +175,6 @@ if (!defined $GIT_DIR) {\n }\n chomp($GIT_DIR);\n \n-my %cquote_map = (\n- \"b\" => chr(8),\n- \"t\" => chr(9),\n- \"n\" => chr(10),\n- \"v\" => chr(11),\n- \"f\" => chr(12),\n- \"r\" => chr(13),\n- \"\\\\\" => \"\\\\\",\n- \"\\042\" => \"\\042\",\n-);\n-\n-sub unquote_path {\n-\tlocal ($_) = @_;\n-\tmy ($retval, $remainder);\n-\tif (!/^\\042(.*)\\042$/) {\n-\t\treturn $_;\n-\t}\n-\t($_, $retval) = ($1, \"\");\n-\twhile (/^([^\\\\]*)\\\\(.*)$/) {\n-\t\t$remainder = $2;\n-\t\t$retval .= $1;\n-\t\tfor ($remainder) {\n-\t\t\tif (/^([0-3][0-7][0-7])(.*)$/) {\n-\t\t\t\t$retval .= chr(oct($1));\n-\t\t\t\t$_ = $2;\n-\t\t\t\tlast;\n-\t\t\t}\n-\t\t\tif (/^([\\\\\\042btnvfr])(.*)$/) {\n-\t\t\t\t$retval .= $cquote_map{$1};\n-\t\t\t\t$_ = $2;\n-\t\t\t\tlast;\n-\t\t\t}\n-\t\t\t# This is malformed -- just return it as-is for now.\n-\t\t\treturn $_[0];\n-\t\t}\n-\t\t$_ = $remainder;\n-\t}\n-\t$retval .= $_;\n-\treturn $retval;\n-}\n-\n sub refresh {\n \tmy $fh;\n \topen $fh, 'git update-index --refresh |'\n-- \n2.13.0\n\n"},{"id":"322923","messageId":"20170622102622.26147-5-phillip.wood@talktalk.net","threadId":"46229","inReplyTo":"20170622102622.26147-1-phillip.wood@talktalk.net","subject":"[PATCH 4/5] Add tests for Git::unquote_path()","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-06-22T10:26:21Z","receivedAt":"2017-06-22T10:27:16Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nCheck that unquote_path() handles spaces and escape sequences properly\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n t/t9700/test.pl | 7 +++++++\n 1 file changed, 7 insertions(+)\n\ndiff --git a/t/t9700/test.pl b/t/t9700/test.pl\nindex 1b75c919651a8126e2a327f3d9645d4377823726..34cd01366f92164ffcd712cb86dac4eb1cffa3f5 100755\n--- a/t/t9700/test.pl\n+++ b/t/t9700/test.pl\n@@ -133,6 +133,13 @@ close TEMPFILE3;\n unlink $tmpfile3;\n chdir($abs_repo_dir);\n \n+# unquoting paths\n+is(Git::unquote_path('abc'), 'abc', 'unquote unquoted path');\n+is(Git::unquote_path('\"abc def\"'), 'abc def', 'unquote simple quoted path');\n+is(Git::unquote_path('\"abc\\\"\\\\\\\\ \\a\\b\\t\\n\\v\\f\\r\\001\\040\"'),\n+\t\t     \"abc\\\"\\\\ \\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x01 \",\n+\t\t     'unquote escape sequences');\n+\n printf \"1..%d\\n\", Test::More->builder->current_test;\n \n my $is_passing = eval { Test::More->is_passing };\n-- \n2.13.0\n\n"},{"id":"322970","messageId":"xmqqlgojken5.fsf@gitster.mtv.corp.google.com","threadId":"46229","inReplyTo":"20170622102622.26147-2-phillip.wood@talktalk.net","subject":"Re: [PATCH 1/5] Git.pm Add unquote_path()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-06-22T19:26:22Z","receivedAt":"2017-06-22T19:26:29Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood@talktalk.net> writes:\n\n> Subject: Re: [PATCH 1/5] Git.pm Add unquote_path()\n\nSubject: [PATCH 1/5] Git.pm: add unquote_path()\n\nBut I think it is more customary to remove the implementation in the\nother file and adjust the existing callers to call this new one in\nthis same commit.  And then in follow-up commits, improve the\nimplementation in Git.pm.\n\nWhen that happens, the subject would become\n\nSubject: [PATCH 1/?] add-i: move unquote_path() to Git.pm\n\nand the first sentence in the body would be tweaked (\"move\nunquote_path() from ... to Git.pm so that ...\").\n\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> Add unquote_path() from git-add--interactive so it can be used by\n> other scripts. Note this is a straight copy, it does not handle\n> '\\a'. That will be fixed in the next commit\n\ns/next commit/&./\n\nGood to notice and document the lack of '\\a' which does get used by\nquote.c::sq_lookup[] when showing chr(7).\n\n> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n> ---\n>  perl/Git.pm | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++-\n>  1 file changed, 52 insertions(+), 1 deletion(-)\n>\n> diff --git a/perl/Git.pm b/perl/Git.pm\n> index bfce1f795dfa5fea05f4f96637a1ae2333038735..8afde87fc8162271ba178e0fff3e921f070ac621 100644\n> --- a/perl/Git.pm\n> +++ b/perl/Git.pm\n> @@ -61,7 +61,8 @@ require Exporter;\n>                  remote_refs prompt\n>                  get_tz_offset get_record\n>                  credential credential_read credential_write\n> -                temp_acquire temp_is_locked temp_release temp_reset temp_path);\n> +                temp_acquire temp_is_locked temp_release temp_reset temp_path\n> +                unquote_path);\n>  \n>  \n>  =head1 DESCRIPTION\n> @@ -1451,6 +1452,56 @@ sub prefix_lines {\n>  \treturn $string;\n>  }\n>  \n> +=item unquote_path ( PATH )\n> +\n> +Unquote a quoted path containing c-escapes as returned by ls-files etc.\n> +when not using -z\n> +\n> +=cut\n> +\n> +{\n> +\tmy %unquote_map = (\n\nThe original calls this cquote_map, partly because there may be\nother kinds of quoting possible.  I do not see a reason not to\nfollow suit here.\n\n> +\t\t\"b\" => chr(8),\n> +\t\t\"t\" => chr(9),\n> +\t\t\"n\" => chr(10),\n> +\t\t\"v\" => chr(11),\n> +\t\t\"f\" => chr(12),\n> +\t\t\"r\" => chr(13),\n> +\t\t\"\\\\\" => \"\\\\\",\n> +\t\t\"\\\"\" => \"\\\"\"\n\nIn an early part of \"sub unquote_path\" we see dq spelled as \"\\042\"\nand in the original cquote_map, this is also defined with \"\\042\".  I\ndo not think you want to change the above to make them inconsistent.\n\n> +\t);\n> +\n> +\tsub unquote_path {\n> +\t\tlocal ($_) = @_;\n> +\t\tmy ($retval, $remainder);\n> +\t\tif (!/^\\042(.*)\\042$/) {\n> +\t\t\treturn $_;\n> +\t\t}\n\nOther than that, I can see this is just a straight-copy, which is\nexactly what we want in an early step of a series like this.  Squash\nin a change to remove the original from add-i and adjust the caller\nto call this one (you may not have to do anything as it uses Git.pm\nalready, or perhaps \"use Git qw(unquote_path)\" or something?) and it\nwould be perfect ;-)\n\nThanks.\n\n"},{"id":"322971","messageId":"xmqqh8z7ke57.fsf@gitster.mtv.corp.google.com","threadId":"46229","inReplyTo":"20170622102622.26147-4-phillip.wood@talktalk.net","subject":"Re: [PATCH 3/5] Git::unquote_path() throw an exception on bad path","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-06-22T19:37:08Z","receivedAt":"2017-06-22T19:37:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood@talktalk.net> writes:\n\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> This is what the other routines in Git.pm do if there's an error.\n>\n> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n> ---\n>  perl/Git.pm | 4 ++--\n>  1 file changed, 2 insertions(+), 2 deletions(-)\n>\n> diff --git a/perl/Git.pm b/perl/Git.pm\n> index 889bf88cfcd34136e24e166fb3b72cced6debf9d..51cb3446088dd12e8fd93d47b95e29fab22a8466 100644\n> --- a/perl/Git.pm\n> +++ b/perl/Git.pm\n> @@ -1493,8 +1493,8 @@ when not using -z\n>  \t\t\t\t\t$_ = $2;\n>  \t\t\t\t\tlast;\n>  \t\t\t\t}\n> -\t\t\t\t# This is malformed -- just return it as-is for now.\n> -\t\t\t\treturn $_[0];\n> +\t\t\t\t# This is malformed\n> +\t\t\t\tthrow Error::Simple(\"Invalid quoted path $_[0]\");\n>  \t\t\t}\n\nOutput from \"git grep Error::Simple\" tells me that mostly we do not\nupcase the first word of the error message.  Perhaps this should\nfollow the convention.\n\nIt is a different matter that use of Error::Simple has been\ndiscouraged for quite some time (e.g. *1*) and we haven't been got\naround doing that.  When the clean-up happens, this code will have\nto be migrated to a different mechanism together with 30+ existing\nuses of it; in the scope of this series, throwing of Error::Simple \nis consistent with the remainder of Git.pm and is a good thing.\n\n[References]\n\n*1* https://public-inbox.org/git/1330809281-25774-1-git-send-email-jnareb@gmail.com/\n"},{"id":"322972","messageId":"xmqqd19vke2z.fsf@gitster.mtv.corp.google.com","threadId":"46229","inReplyTo":"20170622102622.26147-1-phillip.wood@talktalk.net","subject":"Re: [PATCH 0/5] Move unquote_path() from git-add--interactive.perl to Git.pm","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-06-22T19:38:28Z","receivedAt":"2017-06-22T19:38:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thanks.  I had some comments, mostly on the structure of the series,\nbut overall it was a pleasant read that takes the code in the right\ndirection.\n\n"},{"id":"323018","messageId":"20170622231844.d3fdo6c367h3ldve@sigill.intra.peff.net","threadId":"46229","inReplyTo":"20170622102622.26147-1-phillip.wood@talktalk.net","subject":"Re: [PATCH 0/5] Move unquote_path() from git-add--interactive.perl to Git.pm","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2017-06-22T23:18:44Z","receivedAt":"2017-06-22T23:18:51Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jun 22, 2017 at 11:26:17AM +0100, Phillip Wood wrote:\n\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n> \n> I'm using this in some scripts and it would be more convenient to have\n> it available from Git.pm rather than copying and pasting it each time\n> I need it. I think it should be useful to other people using Git.pm as\n> well. It is not uncommon to get a quoted path back from a command that\n> needs to be passed on the commandline of another command. While one\n> can use -z in many cases, that leaves the problem of having to quote\n> the path when printing it in error messages etc.\n\nGrepping around the calls to unquote_path in add--interactive, I\ndefinitely think many of them ought to be using \"-z\". But I don't think\nthat's a reason not to make unquote_path() more widely available. It\n_is_ generally useful.\n\nThe changes look sane to me. My biggest question is how add--interactive\nhandles the exceptions thrown by the refactored function on error. Since\nthese paths are coming from Git, it should be something never comes up,\nright? So failing hard is probably the best thing to do.\n\n-Peff\n"},{"id":"323557","messageId":"20170630094912.8653-2-phillip.wood@talktalk.net","threadId":"46229","inReplyTo":"20170630094912.8653-1-phillip.wood@talktalk.net","subject":"[PATCH 1/4] add -i move unquote_path() to Git.pm","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-06-30T09:49:09Z","receivedAt":"2017-06-30T09:49:47Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nMove unquote_path() from git-add--interactive to Git.pm so it can be\nused by other scripts. Note this is a straight copy, it does not\nhandle '\\a'. That will be fixed in the next commit.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n git-add--interactive.perl | 43 +-------------------------------------\n perl/Git.pm               | 53 ++++++++++++++++++++++++++++++++++++++++++++++-\n 2 files changed, 53 insertions(+), 43 deletions(-)\n\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex 709a5f6ce6fbdb2da14084e94ae9df1db1c3d0a6..7ea3591edc056d4405b1f18800ffd2d0b351f93c 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -3,7 +3,7 @@\n use 5.008;\n use strict;\n use warnings;\n-use Git;\n+use Git qw(unquote_path);\n use Git::I18N;\n \n binmode(STDOUT, \":raw\");\n@@ -175,47 +175,6 @@ if (!defined $GIT_DIR) {\n }\n chomp($GIT_DIR);\n \n-my %cquote_map = (\n- \"b\" => chr(8),\n- \"t\" => chr(9),\n- \"n\" => chr(10),\n- \"v\" => chr(11),\n- \"f\" => chr(12),\n- \"r\" => chr(13),\n- \"\\\\\" => \"\\\\\",\n- \"\\042\" => \"\\042\",\n-);\n-\n-sub unquote_path {\n-\tlocal ($_) = @_;\n-\tmy ($retval, $remainder);\n-\tif (!/^\\042(.*)\\042$/) {\n-\t\treturn $_;\n-\t}\n-\t($_, $retval) = ($1, \"\");\n-\twhile (/^([^\\\\]*)\\\\(.*)$/) {\n-\t\t$remainder = $2;\n-\t\t$retval .= $1;\n-\t\tfor ($remainder) {\n-\t\t\tif (/^([0-3][0-7][0-7])(.*)$/) {\n-\t\t\t\t$retval .= chr(oct($1));\n-\t\t\t\t$_ = $2;\n-\t\t\t\tlast;\n-\t\t\t}\n-\t\t\tif (/^([\\\\\\042btnvfr])(.*)$/) {\n-\t\t\t\t$retval .= $cquote_map{$1};\n-\t\t\t\t$_ = $2;\n-\t\t\t\tlast;\n-\t\t\t}\n-\t\t\t# This is malformed -- just return it as-is for now.\n-\t\t\treturn $_[0];\n-\t\t}\n-\t\t$_ = $remainder;\n-\t}\n-\t$retval .= $_;\n-\treturn $retval;\n-}\n-\n sub refresh {\n \tmy $fh;\n \topen $fh, 'git update-index --refresh |'\ndiff --git a/perl/Git.pm b/perl/Git.pm\nindex bfce1f795dfa5fea05f4f96637a1ae2333038735..35188842ef82c67f83f6d72fd37e38edb895328b 100644\n--- a/perl/Git.pm\n+++ b/perl/Git.pm\n@@ -61,7 +61,8 @@ require Exporter;\n                 remote_refs prompt\n                 get_tz_offset get_record\n                 credential credential_read credential_write\n-                temp_acquire temp_is_locked temp_release temp_reset temp_path);\n+                temp_acquire temp_is_locked temp_release temp_reset temp_path\n+                unquote_path);\n \n \n =head1 DESCRIPTION\n@@ -1451,6 +1452,56 @@ sub prefix_lines {\n \treturn $string;\n }\n \n+=item unquote_path ( PATH )\n+\n+Unquote a quoted path containing c-escapes as returned by ls-files etc.\n+when not using -z or when parsing the output of diff -u.\n+\n+=cut\n+\n+{\n+\tmy %cquote_map = (\n+\t\t\"b\" => chr(8),\n+\t\t\"t\" => chr(9),\n+\t\t\"n\" => chr(10),\n+\t\t\"v\" => chr(11),\n+\t\t\"f\" => chr(12),\n+\t\t\"r\" => chr(13),\n+\t\t\"\\\\\" => \"\\\\\",\n+\t\t\"\\\"\" => \"\\042\"\n+\t);\n+\n+\tsub unquote_path {\n+\t\tlocal ($_) = @_;\n+\t\tmy ($retval, $remainder);\n+\t\tif (!/^\\042(.*)\\042$/) {\n+\t\t\treturn $_;\n+\t\t}\n+\t\t($_, $retval) = ($1, \"\");\n+\t\twhile (/^([^\\\\]*)\\\\(.*)$/) {\n+\t\t\t$remainder = $2;\n+\t\t\t$retval .= $1;\n+\t\t\tfor ($remainder) {\n+\t\t\t\tif (/^([0-3][0-7][0-7])(.*)$/) {\n+\t\t\t\t\t$retval .= chr(oct($1));\n+\t\t\t\t\t$_ = $2;\n+\t\t\t\t\tlast;\n+\t\t\t\t}\n+\t\t\t\tif (/^([\\\\\\042btnvfr])(.*)$/) {\n+\t\t\t\t\t$retval .= $cquote_map{$1};\n+\t\t\t\t\t$_ = $2;\n+\t\t\t\t\tlast;\n+\t\t\t\t}\n+\t\t\t\t# This is malformed -- just return it as-is for now.\n+\t\t\t\treturn $_[0];\n+\t\t\t}\n+\t\t\t$_ = $remainder;\n+\t\t}\n+\t\t$retval .= $_;\n+\t\treturn $retval;\n+\t}\n+}\n+\n =item get_comment_line_char ( )\n \n Gets the core.commentchar configuration value.\n-- \n2.13.1\n\n"},{"id":"323558","messageId":"20170630094912.8653-5-phillip.wood@talktalk.net","threadId":"46229","inReplyTo":"20170630094912.8653-1-phillip.wood@talktalk.net","subject":"[PATCH 4/4] Add tests for Git::unquote_path()","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-06-30T09:49:12Z","receivedAt":"2017-06-30T09:49:50Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nCheck that unquote_path() handles spaces and escape sequences properly\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n t/t9700/test.pl | 7 +++++++\n 1 file changed, 7 insertions(+)\n\ndiff --git a/t/t9700/test.pl b/t/t9700/test.pl\nindex 1b75c919651a8126e2a327f3d9645d4377823726..34cd01366f92164ffcd712cb86dac4eb1cffa3f5 100755\n--- a/t/t9700/test.pl\n+++ b/t/t9700/test.pl\n@@ -133,6 +133,13 @@ close TEMPFILE3;\n unlink $tmpfile3;\n chdir($abs_repo_dir);\n \n+# unquoting paths\n+is(Git::unquote_path('abc'), 'abc', 'unquote unquoted path');\n+is(Git::unquote_path('\"abc def\"'), 'abc def', 'unquote simple quoted path');\n+is(Git::unquote_path('\"abc\\\"\\\\\\\\ \\a\\b\\t\\n\\v\\f\\r\\001\\040\"'),\n+\t\t     \"abc\\\"\\\\ \\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x01 \",\n+\t\t     'unquote escape sequences');\n+\n printf \"1..%d\\n\", Test::More->builder->current_test;\n \n my $is_passing = eval { Test::More->is_passing };\n-- \n2.13.1\n\n"},{"id":"323559","messageId":"20170630094912.8653-3-phillip.wood@talktalk.net","threadId":"46229","inReplyTo":"20170630094912.8653-1-phillip.wood@talktalk.net","subject":"[PATCH 2/4] Git::unquote_path() Handle '\\a'","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-06-30T09:49:10Z","receivedAt":"2017-06-30T09:49:51Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThe version copied from git-add--interactive did not handle quoted\npaths containing '\\a'.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n perl/Git.pm | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/perl/Git.pm b/perl/Git.pm\nindex 35188842ef82c67f83f6d72fd37e38edb895328b..f075b500c510d183074c0358fb24fefc72248125 100644\n--- a/perl/Git.pm\n+++ b/perl/Git.pm\n@@ -1461,6 +1461,7 @@ when not using -z or when parsing the output of diff -u.\n \n {\n \tmy %cquote_map = (\n+\t\t\"a\" => chr(7),\n \t\t\"b\" => chr(8),\n \t\t\"t\" => chr(9),\n \t\t\"n\" => chr(10),\n@@ -1487,7 +1488,7 @@ when not using -z or when parsing the output of diff -u.\n \t\t\t\t\t$_ = $2;\n \t\t\t\t\tlast;\n \t\t\t\t}\n-\t\t\t\tif (/^([\\\\\\042btnvfr])(.*)$/) {\n+\t\t\t\tif (/^([\\\\\\042abtnvfr])(.*)$/) {\n \t\t\t\t\t$retval .= $cquote_map{$1};\n \t\t\t\t\t$_ = $2;\n \t\t\t\t\tlast;\n-- \n2.13.1\n\n"},{"id":"323560","messageId":"20170630094912.8653-1-phillip.wood@talktalk.net","threadId":"46229","inReplyTo":"20170622102622.26147-1-phillip.wood@talktalk.net","subject":"[PATCH 0/4] Move unquote_path from git-add--interactive.perl to Git.pm","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-06-30T09:49:08Z","receivedAt":"2017-06-30T09:49:52Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThanks for the review Junio, I've amended the patches as you suggested.\n\nThe first patch now removes unquote_path() from add -i as well as\nadding it to Git.pm. I've fixed the naming issues (the version I sent\npreviously was copied from another script rather than directly from\nadd -i, I thought it was identical but must have changed it slightly\nwhen I copied the original and then forgotten I'd made some changes)\nI also expanded the documentation very slightly to mention parsing\ndiff -u as I think using -z isn't possible for that.\n\nThe error message in the third patch now starts with a lowercase letter.\n\nBest Wishes\n\nPhillip\n\nPhillip Wood (4):\n  add -i move unquote_path() to Git.pm\n  Git::unquote_path() Handle '\\a'\n  Git::unquote_path() throw an exception on bad path\n  Add tests for Git::unquote_path()\n\n git-add--interactive.perl | 43 +------------------------------------\n perl/Git.pm               | 54 ++++++++++++++++++++++++++++++++++++++++++++++-\n t/t9700/test.pl           |  7 ++++++\n 3 files changed, 61 insertions(+), 43 deletions(-)\n\n-- \n2.13.1\n\n"},{"id":"323561","messageId":"20170630094912.8653-4-phillip.wood@talktalk.net","threadId":"46229","inReplyTo":"20170630094912.8653-1-phillip.wood@talktalk.net","subject":"[PATCH 3/4] Git::unquote_path() throw an exception on bad path","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-06-30T09:49:11Z","receivedAt":"2017-06-30T09:49:54Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThis is what the other routines in Git.pm do if there's an error.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n perl/Git.pm | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/perl/Git.pm b/perl/Git.pm\nindex f075b500c510d183074c0358fb24fefc72248125..baf80d1ab038590c85bc5971483517cba606881f 100644\n--- a/perl/Git.pm\n+++ b/perl/Git.pm\n@@ -1493,8 +1493,8 @@ when not using -z or when parsing the output of diff -u.\n \t\t\t\t\t$_ = $2;\n \t\t\t\t\tlast;\n \t\t\t\t}\n-\t\t\t\t# This is malformed -- just return it as-is for now.\n-\t\t\t\treturn $_[0];\n+\t\t\t\t# This is malformed\n+\t\t\t\tthrow Error::Simple(\"invalid quoted path $_[0]\");\n \t\t\t}\n \t\t\t$_ = $remainder;\n \t\t}\n-- \n2.13.1\n\n"},{"id":"323562","messageId":"73f70ec5-b21f-e237-69a2-d0c4462d8c17@talktalk.net","threadId":"46229","inReplyTo":"20170622231844.d3fdo6c367h3ldve@sigill.intra.peff.net","subject":"Re: [PATCH 0/5] Move unquote_path() from git-add--interactive.perl to Git.pm","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2017-06-30T09:53:25Z","receivedAt":"2017-06-30T09:53:34Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 23/06/17 00:18, Jeff King wrote:\n> On Thu, Jun 22, 2017 at 11:26:17AM +0100, Phillip Wood wrote:\n> \n>> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>>\n>> I'm using this in some scripts and it would be more convenient to have\n>> it available from Git.pm rather than copying and pasting it each time\n>> I need it. I think it should be useful to other people using Git.pm as\n>> well. It is not uncommon to get a quoted path back from a command that\n>> needs to be passed on the commandline of another command. While one\n>> can use -z in many cases, that leaves the problem of having to quote\n>> the path when printing it in error messages etc.\n> \n> Grepping around the calls to unquote_path in add--interactive, I\n> definitely think many of them ought to be using \"-z\". But I don't think\n> that's a reason not to make unquote_path() more widely available. It\n> _is_ generally useful.\n>\n> The changes look sane to me. My biggest question is how add--interactive\n> handles the exceptions thrown by the refactored function on error. Since\n> these paths are coming from Git, it should be something never comes up,\n> right? So failing hard is probably the best thing to do.\n\nYes, my assumption was that the error shouldn't be triggered, and if it\nwas then it would be a sign of bigger problems.\n\nBest Wishes\n\nPhillip\n\n"},{"id":"323568","messageId":"xmqq60fdtt09.fsf@gitster.mtv.corp.google.com","threadId":"46229","inReplyTo":"20170630094912.8653-1-phillip.wood@talktalk.net","subject":"Re: [PATCH 0/4] Move unquote_path from git-add--interactive.perl to Git.pm","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-06-30T15:06:14Z","receivedAt":"2017-06-30T15:06:29Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Looks good.  Will queue.\n\nThanks.\n"}]}