{"thread":{"id":"57094","subject":"bug: git-add --patch any negative pathspec fails","startedAt":"2021-12-16T19:10:01Z","lastAt":"2021-12-16T20:03:00Z","messageCount":2,"participants":["Erik Cervin Edin","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"444250","messageId":"CA+JQ7M_Q2bgHWt_SFWdMCHkqqJr2K2VEqDfK4en_eXhs0o5JgQ@mail.gmail.com","threadId":"57094","inReplyTo":null,"subject":"bug: git-add --patch any negative pathspec fails","fromName":"Erik Cervin Edin","fromEmail":"erik@cervined.in","sentAt":"2021-12-16T19:09:24Z","receivedAt":"2021-12-16T19:10:01Z","isPatch":false,"sender":{"key":"erik@cervined.in","avatar":null},"body":"Steps to reproduce:\ngit-add -p -- ':!foo'\n\nExpected:\nAdd everything that doesn't match the pathspec.\n\nActual:\nfatal: empty string is not a valid pathspec. please use . instead if\nyou meant to match all paths\nCannot close git diff-index --cached --numstat --summary HEAD --\n:(exclude,prefix:0)bar  () at C:/Program\nFiles/Git/mingw64/libexec/git-core\\git-add--interactive line 242.\n\nRelevant trace:\n19:44:00.359141 run-command.c:667       trace: run_command: git\nadd--interactive --patch -- ':(exclude,prefix:0)bar' ''\nNote the added empty string pathspec\n\nAffects:\ngit version 2.31.1.windows.1\n"},{"id":"444255","messageId":"YbubciQn0eKq4iKc@coredump.intra.peff.net","threadId":"57094","inReplyTo":"CA+JQ7M_Q2bgHWt_SFWdMCHkqqJr2K2VEqDfK4en_eXhs0o5JgQ@mail.gmail.com","subject":"Re: bug: git-add --patch any negative pathspec fails","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2021-12-16T20:02:58Z","receivedAt":"2021-12-16T20:03:00Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Dec 16, 2021 at 08:09:24PM +0100, Erik Cervin Edin wrote:\n\n> Steps to reproduce:\n> git-add -p -- ':!foo'\n> \n> Expected:\n> Add everything that doesn't match the pathspec.\n> \n> Actual:\n> fatal: empty string is not a valid pathspec. please use . instead if\n> you meant to match all paths\n\nHmm. This is a regression from 728c573803 (Merge branch\n'ex/deprecate-empty-pathspec-as-match-all', 2017-11-06). But I think the\nfault is really in the earlier 859b7f1d0e (pathspec: don't error out on\nall-exclusionary pathspec patterns, 2017-02-07).\n\nIt works by adding an extra \"match everything\" pathspec internally, but\nit just passes the empty string as the \"original\" string to\ninit_pathspec_item(). And \"git add -p\" works by iterating over the\nparsed pathspec list and adding the result to the helper script's argv.\n\nSo either:\n\n  - it should instead make sure to pass the true original set of\n    pathspecs we got (so just the exclusion, not the \"match everything\"\n    one). This would work because those pathspecs are then interpreted\n    by further Git programs anyway (so they'd have their own \"match\n    everything\" logic internally).\n\n  - we should pass something better for the \"match everything\" pathspec.\n    The patch below does that, though I didn't think too hard on whether\n    the choice of \"something better\" would always be correct (e.g., if\n    we change directory internally, do we need to adjust \".\" to match\n    original cwd)?\n\n    It does fix your case, and it passes the test suite, but I have a\n    feeling this area is not very well tested (I doubt we even look at\n    the \"original\" string all that often).\n\ndiff --git a/pathspec.c b/pathspec.c\nindex ddeeba7911..5a0e083229 100644\n--- a/pathspec.c\n+++ b/pathspec.c\n@@ -628,8 +628,16 @@ void parse_pathspec(struct pathspec *pathspec,\n \t * that matches everything. We allocated an extra one for this.\n \t */\n \tif (nr_exclude == n) {\n-\t\tint plen = (!(flags & PATHSPEC_PREFER_CWD)) ? 0 : prefixlen;\n-\t\tinit_pathspec_item(item + n, 0, prefix, plen, \"\");\n+\t\tint plen;\n+\t\tconst char *orig;\n+\t\tif (flags & PATHSPEC_PREFER_CWD) {\n+\t\t\tplen = prefixlen;\n+\t\t\torig = \".\";\n+\t\t} else {\n+\t\t\tplen = 0;\n+\t\t\torig = \":/\";\n+\t\t}\n+\t\tinit_pathspec_item(item + n, 0, prefix, plen, orig);\n \t\tpathspec->nr++;\n \t}\n \n"}]}