Re: [bug] git-ls-files sometimes does not list files with pathspec magic ":(exclude)"

2 messages, 2 authors, 2021-01-14 · open the first message on its own page

Re: [bug] git-ls-files sometimes does not list files with pathspec magic ":(exclude)"

From: Junio C Hamano <hidden>
Date: 2021-01-14 02:09:03

Thomas Haller [off-list ref] writes:
      git ls-files -- src/platform/ ":(exclude)shared/n-acd"
This does look interesting.

$ git ls-files -- src/platform/ ":(exclude)shared/n-acd"
$ git ls-files -- src/platform/ ":(exclude)??????/?????"
$ git ls-files -- src/platform/ ":(exclude)??????/????"
$ git ls-files -- src/platform/ ":(exclude)??????/???"
$ git ls-files -- src/platform/ ":(exclude)??????/??"
$ git ls-files -- src/platform/ ":(exclude)??????/?"

None of the above gives any output.  And the '/' seems to be a red
herring.  None of the below (where the '/' in the exclude pathspec
is replaced with a single '?') gives any output, either.

$ git ls-files -- src/platform/ ":(exclude)????????????"
$ git ls-files -- src/platform/ ":(exclude)???????????"
$ git ls-files -- src/platform/ ":(exclude)??????????"
$ git ls-files -- src/platform/ ":(exclude)?????????"
$ git ls-files -- src/platform/ ":(exclude)????????"

But if we add one more "?" to the longuest ones, i.e.

$ git ls-files -- src/platform/ ":(exclude)?????????????"
$ git ls-files -- src/platform/ ":(exclude)shared/n-acd?"

we start seeing output.

What is curious is that the longest problematic negative pathspec,
"shared/n-acd" or "????????????", have the same length as
"src/platform" without the trailing slash.

    "shared/n-acd"
    "src/platform/"
    "????????????"

The rule IIUC is that a path must match one of the positive pathspec
and none of the negative pathspec, but it looks as if there is some
bogus optimization based on string length.

An experiment.  These ought to do the same as the first exacmple:

$ git ls-files -- src/platform/ ":(exclude)shared/n-ac[d]"
$ git ls-files -- src/platform/ ":(exclude)shared/n-[acd][acd][acd]"

but probably because of the character class [d], it seems to
defeat/bypass the broken "optimization" and gives what we expect
back.

I'll have to go back to the desk where I have a development
environment (not an end user enviornment) to dig deeper, but this is
intriguing.  I'll look more later unless somebody else beats me to
it.

Thanks for a report.

Re: [bug] git-ls-files sometimes does not list files with pathspec magic ":(exclude)"

From: Jeff King <hidden>
Date: 2021-01-14 20:21:57

On Wed, Jan 13, 2021 at 06:07:56PM -0800, Junio C Hamano wrote:
The rule IIUC is that a path must match one of the positive pathspec
and none of the negative pathspec, but it looks as if there is some
bogus optimization based on string length.
I dug a little on this earlier this morning, but didn't get far enough
to have any confidence that I wasn't barking totally up the wrong tree.
But I found the way the "prefix" is passed match_pathspec to be
confusing. This seems to make the problem go away:
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index c8eae899b8..93796404bd 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -232,7 +232,7 @@ static void show_ce(struct repository *repo, struct dir_struct *dir,
 	    is_submodule_active(repo, ce->name)) {
 		show_submodule(repo, dir, ce->name);
 	} else if (match_pathspec(repo->index, &pathspec, fullname, strlen(fullname),
-				  max_prefix_len, ps_matched,
+				  0, ps_matched,
 				  S_ISDIR(ce->ce_mode) ||
 				  S_ISGITLINK(ce->ce_mode))) {
 		tag = get_tag(ce, tag);
which I guess is likewise disabling the same optimization you're talking
about. But that probably means the bug is in match_pathspec().

(I probably won't look further at this for a while, so please continue
your prodding; I just wanted to drop what little knowledge I came up
with).

-Peff
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help