Re: Bug: git add :!x . exits with error when x is in .gitignore
- From
- Remy D. Farley <one-d-wide@protonmail.com>
- Date
- Feb 2, 2026, 21:25 UTC
- Message-ID
- <20260202212420.1185803-1-one-d-wide@protonmail.com>
- In-Reply-To
- <1d560aa1-d452-47f5-aaf2-4cb1ccdab100@gmail.com>
Show 26 quoted lines
> Thanks for the report and the patch! I also agree that the behavior you > described seems like a bug. > > However, though I'm new to git community, I still have concerns about > the fix in 'dir.c': > > > - if (!pathspec || !pathspec->nr) > > + if (!pathspec || !pathspec->nr || pathspec->magic & PATHSPEC_EXCLUDE) > > return 0; > > > I tried to analyze the logic and I believe this patch breaks the basic > functionality of the negative pathspec (:!): > > (I didn't check the caller of exclude_matches_pathspec and I only focus > on the function itself. Tell me if I'm wrong :) > > By returning 0 whenever PATHSPEC_EXCLUDE is set globally, > exclude_matches_pathspec will report "no match" for all files, > effectively disabling the exclusion mechanism entirely. > > Instead of fixing the issue with ignored files, this patch causes valid > exclusions to be ignored. > > We must check if the specific path matches the exclude pattern, not > short-circuit based on the global flag.
Oops. Somehow I was convinced struct pathspec represents only a single path. This way something like this would silently succeed, without actually indexing x:
touch x echo x >.gitignore git add -n ":(exclude)smth/else" x
Thank you for pointing out.
> It will be great if we set a test script for this. I will be working on > it in the next few days.
--- dir.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/dir.c b/dir.c index b00821f2..ed6b99e3 100644 --- a/dir.c +++ b/dir.c @@ -2280,6 +2280,9 @@ static int exclude_matches_pathspec(const char *path, int pathlen, const struct pathspec_item *item = &pathspec->items[i]; int len = item->nowildcard_len; + if (item->magic & PATHSPEC_EXCLUDE) + continue; + if (len == pathlen && !ps_strncmp(item, item->match, path, pathlen)) return 1;
-- 2.51.2