On Wed, Apr 16, 2025 at 9:20 PM Lucas Seiki Oshiro <lucasseikioshiro@xxxxxxxxx> wrote: > > > > Yes ls-files is also a great example, I will add them in the test. > > > I was going to suggest you to use `git ls-files -o 'f**'` in your test, > which would eliminate the need of `git add` and `git reset`. However, I > just found that the bug doesn't happen here: > > ``` > git init > touch foo 'f*' 'f**' f bar > git ls-files -o 'f*' > ``` > > Here (I'm using the current `next`, currently at `fd585f7`), > `git ls-files -o 'f*'` list the files correctly: > > ``` > f > f* > f** > foo > ``` > > I also tried with `git grep`: > > ``` > git init > touch foo 'f*' 'f**' f bar > for f in *; do echo 123 > "$f"; done > git add -A > git grep 123 -- 'f*' > > and somehow it worked: > > ``` > f:1:123 > f*:1:123 > f**:1:123 > foo:1:123 > ``` > > So, if I'm not doing anything wrong, it looks that it is not solely > related to pathspecs, but related to pathspecs when used with some other > commands. hmmm... > > > I think for the pathspec and glob specific commands almost all the commands > > share the same code, so it should work the same for all. > > > I also though the same, but somehow it behaves differently at least with > `ls-files` and `grep`. Perhaps it will need further investigation on how > some commands behave correctly and some don't. I would start by > inspecting other commands that uses pathspecs (some that I remember: > checkout, log, show, stash, status, ls-files, grep) and see if they work > correctly or not, then compare the two groups and see what differs > between them under the hook. That is interesting given that this part of code <prune function in add.c> while (--i >= 0) { struct dir_entry *entry = *src++; if (dir_path_match(repo->index, entry, pathspec, prefix, seen)) *dst++ = entry; } takes part in dir_path_match Which traces to *Exact Match* problem that was found and from ls files if (!index_name_is_other(istate, ent->name, ent->len)) continue; show_dir_entry(istate, tag_other, ent); Where show_dir_entry calls static void show_dir_entry(struct index_state *istate, const char *tag, struct dir_entry *ent) { int len = max_prefix_len; if (len > ent->len) die("git ls-files: internal error - directory entry not superset of prefix"); /* If ps_matches is non-NULL, figure out which pathspec(s) match. */ if (ps_matched) dir_path_match(istate, ent, &pathspec, len, ps_matched); Something like this So I think the argument values are making the difference but I'm still unsure.