Git Mailing List Archive mirror
 help / color / mirror / Atom feed
* Bug: `git check-ignore -v` changes the exit code.
@ 2024-03-26 22:07 Michael G Schwern
  0 siblings, 0 replies; only message in thread
From: Michael G Schwern @ 2024-03-26 22:07 UTC (permalink / raw
  To: git

Thank you for filling out a Git bug report!
Please answer the following questions to help us understand your issue.

What did you do before the bug happened? (Steps to reproduce your issue)

$ tree
.
├── dir_b
│   ├── sub
│   │   └── test
│   └── test
└── top

$ cat .gitignore
*

!/dir_b/
!/dir_b/**

$ git status --ignored
On branch main

No commits yet

Untracked files:
   (use "git add <file>..." to include in what will be committed)
	dir_b/

Ignored files:
   (use "git add -f <file>..." to include in what will be committed)
	.gitignore
	top

nothing added to commit but untracked files present (use "git add" to track)


What did you expect to happen? (Expected behavior)

$ git check-ignore dir_b/sub/test
$ echo $?
1

$ git check-ignore -v dir_b/sub/test
$ echo $?
1


What happened instead? (Actual behavior)

$ git check-ignore dir_b/sub/test
$ echo $?
1

$ git check-ignore -v dir_b/sub/test
.gitignore:4:!/dir_b/**	dir_b/sub/test
$ echo $?
0

What's different between what you expected and what actually happened?

First, `git check-ignore -v` should have exited with 1 because that is 
defined as "None of the provided paths are ignored". Exiting with 0, 
"One or more of the provided paths is ignored", is clearly incorrect.

Second, it's confusing that `git check-ignore -v` shows matches to 
negation patterns. The documentation says "Instead of printing the paths 
that are excluded, for each path that matches an exclude pattern, print 
the exclude pattern together with the path." which seems pretty clear, 
but then there's this parenthetical... "(Matching an exclude pattern 
usually means the path is excluded, but if the pattern begins with "!" 
then it is a negated pattern and matching it means the path is NOT 
excluded.)" which *implies* -v is also going to show unignored files, 
but it's unclear.

An additional problem is the use of "excluded" to mean "ignored" and 
"exclude pattern" which includes negated patterns which include. Oy.

The existence of --non-matching makes this extra confusing. The casual 
reader can think "non-matching" means "paths which are not ignored" 
rather than "paths which match no pattern". Again, the misunderstanding 
hinges on realizing "exclude pattern" includes negated patterns which 
include.

Anything else you want to add:

`git check-ignore`, `git check-ignore -v`, and `git status --ignored` 
should all agree at least on what is ignored.

Verbose flags should not change the behavior of a command, they should 
only add to its output. `git check-ignore` shows only ignored paths 
while `git check-ignore -v` also shows unignored paths. One could argue 
only the exit status is the true behavior, but people look at the 
output. See 
https://stackoverflow.com/questions/78216866/file-in-the-same-path-one-can-be-git-trace-but-others-cannot#comment137908188_78216923 
for a real example of this causing confusion.

I think the issue is that `git check-ignore` is for checking which files 
are ignored. Users expect --verbose to also show them why their file was 
ignored, but --verbose also shows unignored files. This is unexpected. 
The change in the exit status exacerbates the problem.

It would help to talk about "ignored files" rather than "excluded 
files". It's called "check-ignore" and users edit their ".gitignore" fie 
and read the "gitignore" docs (.git/exclude being rarely used).

I would also simply say "pattern". This avoids the confusion that 
"exclude patterns" sometimes unexclude. gitignore only says "pattern" 
and never says "exclude pattern". This also avoids the confusing 
"negated exclude pattern", that is just a "negated pattern".

Ideally, I'd make --verbose just show the path + the last matched 
pattern. Separate flag(s) change what is shown.

-v, --verbose
Print the matching pattern and the path.

-a, --all-matching
Show paths which match any pattern. If the path matches a negated 
pattern (the pattern begins with "!") it will be shown despite not being 
ignored.

The current behavior would be `git check-ignore -v -a <path>...`.

If -v has to remain backwards compatible, I would suggest...

-v, --verbose
Print the matching pattern and the path. If the match is a negated 
pattern (the pattern begins with "!") the path is not ignored.


Please review the rest of the bug report below.
You can delete any lines you don't wish to share.


[System Info]
git version:
git version 2.43.2
cpu: x86_64
no commit associated with this build
sizeof-long: 8
sizeof-size_t: 8
shell-path: /bin/sh
feature: fsmonitor--daemon
uname: Darwin 23.3.0 Darwin Kernel Version 23.3.0: Wed Dec 20 21:28:58 
PST 2023; root:xnu-10002.81.5~7/RELEASE_X86_64 x86_64
compiler info: clang: 15.0.0 (clang-1500.1.0.2.5)
libc info: no libc information available
$SHELL (typically, interactive shell): /bin/bash


[Enabled Hooks]

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-03-26 22:07 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-26 22:07 Bug: `git check-ignore -v` changes the exit code Michael G Schwern

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).