Bug: `git check-ignore -v` changes the exit code.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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]





[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux