Re: [bug] git check-ignore returns the wrong exit code with -v when only a negative pattern matches
On Thu, Sep 18, 2025 at 10:28:05AM -0700, David Goldstein wrote:
Show 13 quoted lines
> Hey folks, I think I found a git check-ignore bug. According to the
> docs, git check-ignore should only exit 0 if a file is ignored, but if
> an untracked file matches a negative pattern in .gitignore (or the
> file can be tracked if --no-index is also used), then git check-ignore
> -v <file> exits 0 when it should exit 1; without -v the exit code is
> correct (0).
>
> https://github.com/dgoldstein0/git_bug_repro has a self-contained
> reproduction + repeated explanation.
>
> This exists in all git versions I've tested, but I haven't tried to
> get the latest dev version to check if it's still a problem in the
> latest version.
I can reproduce it here with the latest version. I've never looked at the check-ignore code before, but it looks like the issue is something like:
1. We "count" ignored files by seeing if the matched "pattern"
variable is left non-NULL. 2. In non-verbose mode, we set the pattern to NULL when it is a
negative pattern. Makes sense. 3. In verbose mode, we don't do that because we need to show the
pattern. So we accidentally count the entry as ignored.So something like this makes your repo behave as you expected:
diff --git a/builtin/check-ignore.c b/builtin/check-ignore.c
index 644c9a414f..808c0e5ff4 100644
--- a/builtin/check-ignore.c
+++ b/builtin/check-ignore.c
@@ -117,7 +117,7 @@ static int check_ignore(struct dir_struct *dir,
}
if (!quiet && (pattern || show_non_matching))
output_pattern(pathspec.items[i].original, pattern);
- if (pattern)
+ if (pattern && !(pattern->flags & PATTERN_FLAG_NEGATIVE))
num_ignored++;
}
free(seen);
AFAICT it has been this way since the inception of the code. I haven't
ever used the exit code of check-ignore. I wonder if the current
behavior is actually useful, along the lines of "exit 0 if any output
was shown, and 1 otherwise". That would justify a difference in behavior
between running with "-v" and without. But again, I've never used the
exit code so I'm not sure in what circumstances it would be useful.
-Peff