All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
From: Michael G Schwern <schwern@pobox.com>
To: git@vger.kernel.org
Subject: Bug: `git check-ignore -v` changes the exit code.
Date: Tue, 26 Mar 2024 15:07:35 -0700	[thread overview]
Message-ID: <ddeef5fe-d208-49e1-bbf1-5563df3dcf51@pobox.com> (raw)

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]

                 reply	other threads:[~2024-03-26 22:07 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ddeef5fe-d208-49e1-bbf1-5563df3dcf51@pobox.com \
    --to=schwern@pobox.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.