{"thread":{"id":"61206","subject":"Bug: `git check-ignore -v` changes the exit code.","startedAt":"2024-03-26T22:07:38Z","lastAt":"2024-03-26T22:07:38Z","messageCount":1,"participants":["Michael G Schwern"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"491615","messageId":"ddeef5fe-d208-49e1-bbf1-5563df3dcf51@pobox.com","threadId":"61206","inReplyTo":null,"subject":"Bug: `git check-ignore -v` changes the exit code.","fromName":"Michael G Schwern","fromEmail":"schwern@pobox.com","sentAt":"2024-03-26T22:07:35Z","receivedAt":"2024-03-26T22:07:38Z","isPatch":false,"sender":{"key":"schwern@pobox.com","avatar":"https://avatars.githubusercontent.com/u/25888?v=4"},"body":"Thank you for filling out a Git bug report!\nPlease answer the following questions to help us understand your issue.\n\nWhat did you do before the bug happened? (Steps to reproduce your issue)\n\n$ tree\n.\n├── dir_b\n│   ├── sub\n│   │   └── test\n│   └── test\n└── top\n\n$ cat .gitignore\n*\n\n!/dir_b/\n!/dir_b/**\n\n$ git status --ignored\nOn branch main\n\nNo commits yet\n\nUntracked files:\n   (use \"git add <file>...\" to include in what will be committed)\n\tdir_b/\n\nIgnored files:\n   (use \"git add -f <file>...\" to include in what will be committed)\n\t.gitignore\n\ttop\n\nnothing added to commit but untracked files present (use \"git add\" to track)\n\n\nWhat did you expect to happen? (Expected behavior)\n\n$ git check-ignore dir_b/sub/test\n$ echo $?\n1\n\n$ git check-ignore -v dir_b/sub/test\n$ echo $?\n1\n\n\nWhat happened instead? (Actual behavior)\n\n$ git check-ignore dir_b/sub/test\n$ echo $?\n1\n\n$ git check-ignore -v dir_b/sub/test\n.gitignore:4:!/dir_b/**\tdir_b/sub/test\n$ echo $?\n0\n\nWhat's different between what you expected and what actually happened?\n\nFirst, `git check-ignore -v` should have exited with 1 because that is \ndefined as \"None of the provided paths are ignored\". Exiting with 0, \n\"One or more of the provided paths is ignored\", is clearly incorrect.\n\nSecond, it's confusing that `git check-ignore -v` shows matches to \nnegation patterns. The documentation says \"Instead of printing the paths \nthat are excluded, for each path that matches an exclude pattern, print \nthe exclude pattern together with the path.\" which seems pretty clear, \nbut then there's this parenthetical... \"(Matching an exclude pattern \nusually means the path is excluded, but if the pattern begins with \"!\" \nthen it is a negated pattern and matching it means the path is NOT \nexcluded.)\" which *implies* -v is also going to show unignored files, \nbut it's unclear.\n\nAn additional problem is the use of \"excluded\" to mean \"ignored\" and \n\"exclude pattern\" which includes negated patterns which include. Oy.\n\nThe existence of --non-matching makes this extra confusing. The casual \nreader can think \"non-matching\" means \"paths which are not ignored\" \nrather than \"paths which match no pattern\". Again, the misunderstanding \nhinges on realizing \"exclude pattern\" includes negated patterns which \ninclude.\n\nAnything else you want to add:\n\n`git check-ignore`, `git check-ignore -v`, and `git status --ignored` \nshould all agree at least on what is ignored.\n\nVerbose flags should not change the behavior of a command, they should \nonly add to its output. `git check-ignore` shows only ignored paths \nwhile `git check-ignore -v` also shows unignored paths. One could argue \nonly the exit status is the true behavior, but people look at the \noutput. See \nhttps://stackoverflow.com/questions/78216866/file-in-the-same-path-one-can-be-git-trace-but-others-cannot#comment137908188_78216923 \nfor a real example of this causing confusion.\n\nI think the issue is that `git check-ignore` is for checking which files \nare ignored. Users expect --verbose to also show them why their file was \nignored, but --verbose also shows unignored files. This is unexpected. \nThe change in the exit status exacerbates the problem.\n\nIt would help to talk about \"ignored files\" rather than \"excluded \nfiles\". It's called \"check-ignore\" and users edit their \".gitignore\" fie \nand read the \"gitignore\" docs (.git/exclude being rarely used).\n\nI would also simply say \"pattern\". This avoids the confusion that \n\"exclude patterns\" sometimes unexclude. gitignore only says \"pattern\" \nand never says \"exclude pattern\". This also avoids the confusing \n\"negated exclude pattern\", that is just a \"negated pattern\".\n\nIdeally, I'd make --verbose just show the path + the last matched \npattern. Separate flag(s) change what is shown.\n\n-v, --verbose\nPrint the matching pattern and the path.\n\n-a, --all-matching\nShow paths which match any pattern. If the path matches a negated \npattern (the pattern begins with \"!\") it will be shown despite not being \nignored.\n\nThe current behavior would be `git check-ignore -v -a <path>...`.\n\nIf -v has to remain backwards compatible, I would suggest...\n\n-v, --verbose\nPrint the matching pattern and the path. If the match is a negated \npattern (the pattern begins with \"!\") the path is not ignored.\n\n\nPlease review the rest of the bug report below.\nYou can delete any lines you don't wish to share.\n\n\n[System Info]\ngit version:\ngit version 2.43.2\ncpu: x86_64\nno commit associated with this build\nsizeof-long: 8\nsizeof-size_t: 8\nshell-path: /bin/sh\nfeature: fsmonitor--daemon\nuname: Darwin 23.3.0 Darwin Kernel Version 23.3.0: Wed Dec 20 21:28:58 \nPST 2023; root:xnu-10002.81.5~7/RELEASE_X86_64 x86_64\ncompiler info: clang: 15.0.0 (clang-1500.1.0.2.5)\nlibc info: no libc information available\n$SHELL (typically, interactive shell): /bin/bash\n\n\n[Enabled Hooks]\n"}]}