git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [BUG] regarding `git add -p` and files containing wildcard characters
@ 2016-12-09  1:46 unixway.drive
  2016-12-09  5:37 ` Jeff King
  0 siblings, 1 reply; 2+ messages in thread
From: unixway.drive @ 2016-12-09  1:46 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 2937 bytes --]

`git add -p` behaves incorrectly if modified file contains any wildcard 
character. Consider 'random.diff' (attached). For this, interactive 
'add' would first ask to add hunk with two diff headers (or with some 
"random" header at the end):

     $ git add -p
     diff --git a/Random * b/Random *
     index 01e79c3..01f03ff 100644
     --- a/Random *
     +++ b/Random *
     @@ -1,3 +1,5 @@
      1
     +  a
      2
     +  b
      3
     diff --git a/Random Crap b/Random Crap
     index 01e79c3..b4373d5 100644
     --- a/Random Crap
     +++ b/Random Crap
     Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]? y

Then it will ask for some irrelevant hunk:

     @@ -1,3 +1,5 @@
      1
     +  whoa
      2
     +  dude
      3
     Stage this hunk [y,n,q,a,d,/,K,g,s,e,?]? y

…and, if confirmed, apply it to the wildcard-named file instead of what 
was confirmed for staging before:

     $ git diff --cached
     diff --git a/Random * b/Random *
     index 01e79c3..283ac91 100644
     --- a/Random *
     +++ b/Random *
     @@ -1,3 +1,5 @@
      1
     +  whoa
      2
     +  dude
      3

Then one can just repeat this over and over again (unless safely named 
files are resolved first):

     $ git add -p
     diff --git a/Random * b/Random *
     index 283ac91..04c92f1 100644
     --- a/Random *	
     +++ b/Random *	
     @@ -1,5 +1,5 @@
      1
     -  whoa
     +  a
      2
     -  dude
     +  b
      3
     diff --git a/Random Crap b/Random Crap
     index 01e79c3..283ac91 100644
     --- a/Random Crap	
     +++ b/Random Crap	
     Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]?

The problem is that `git-diff-files` does some globbing on the 'path' 
arguments on its own and has no option to disable that (and 
`git-add--interactive`'s `run_cmd_pipe` already handles all other sorts 
of unsafe characters like spaces and backticks well).

     $ strace -f -e trace=execve git add -p
     …
     [pid  1713] execve("/usr/lib/git-core/git",
         ["git", "diff-files", "-p", "--", "Random *"],
     [/* 36 vars */]) = 0
     …
     $ git diff-files -- 'Random *'
     :100644 100644 … … M	Random *
     :100644 100644 … … M	Random Crap

For all the eager people (although I doubt if anybody else is lazy 
enough to not bother with file names like these), this could be easily 
worked around like this:

diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index ee3d812..358d877 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -2,3 +2,3 @@

-use 5.008;
+use 5.014;
  use strict;
@@ -761,3 +761,5 @@ sub parse_diff {
         }
-       my @diff = run_cmd_pipe("git", @diff_cmd, "--", $path);
+       my @diff = run_cmd_pipe("git", @diff_cmd, "--", (
+               $path =~ s#[\[*?]#\\$&#gr
+       ));
         my @colored = ();

(Although a `git-diff-files` option is clearly a better solution that 
would cover tools other than `git-add--interactive` as well.)

[-- Attachment #2: random.diff --]
[-- Type: text/x-patch, Size: 278 bytes --]

diff --git a/Random * b/Random *
index 01e79c3..04c92f1 100644
--- a/Random *	
+++ b/Random *	
@@ -1,3 +1,5 @@
 1
+  a
 2
+  b
 3
diff --git a/Random Crap b/Random Crap
index 01e79c3..283ac91 100644
--- a/Random Crap	
+++ b/Random Crap	
@@ -1,3 +1,5 @@
 1
+  whoa
 2
+  dude
 3

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [BUG] regarding `git add -p` and files containing wildcard characters
  2016-12-09  1:46 [BUG] regarding `git add -p` and files containing wildcard characters unixway.drive
@ 2016-12-09  5:37 ` Jeff King
  0 siblings, 0 replies; 2+ messages in thread
From: Jeff King @ 2016-12-09  5:37 UTC (permalink / raw)
  To: unixway.drive; +Cc: git

On Fri, Dec 09, 2016 at 04:46:49AM +0300, unixway.drive@gmail.com wrote:

> The problem is that `git-diff-files` does some globbing on the 'path'
> arguments on its own and has no option to disable that (and
> `git-add--interactive`'s `run_cmd_pipe` already handles all other sorts of
> unsafe characters like spaces and backticks well).

I think the option you're looking for is:

  git --literal-pathspecs diff-files ... -- 'Random *'

I don't know if there are other commands run by add--interactive that
would want the same treatment. It might actually make sense to set
GIT_LITERAL_PATHSPECS=1 in the environment right after it expands the
list via ls-files.

> diff --git a/git-add--interactive.perl b/git-add--interactive.perl
> index ee3d812..358d877 100755
> --- a/git-add--interactive.perl
> +++ b/git-add--interactive.perl
> @@ -2,3 +2,3 @@
> 
> -use 5.008;
> +use 5.014;
>  use strict;
> @@ -761,3 +761,5 @@ sub parse_diff {
>         }
> -       my @diff = run_cmd_pipe("git", @diff_cmd, "--", $path);
> +       my @diff = run_cmd_pipe("git", @diff_cmd, "--", (
> +               $path =~ s#[\[*?]#\\$&#gr
> +       ));

This callsite covers "-p". It looks like list_modified() probably needs
similar treatment. Maybe others; I didn't look exhaustively.

-Peff

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2016-12-09  5:37 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-12-09  1:46 [BUG] regarding `git add -p` and files containing wildcard characters unixway.drive
2016-12-09  5:37 ` Jeff King

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).