{"thread":{"id":"58146","subject":"BUG: git-check-ignore documentation doesn't come close to describing what it really does","startedAt":"2022-07-12T23:03:01Z","lastAt":"2022-07-19T06:27:29Z","messageCount":5,"participants":["Britton Kerin","Elijah Newren","Junio C Hamano","Britton Leo Kerin"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"458921","messageId":"CAC4O8c9izkV5vbnE6MH8-RwnxRbUONxJxYZO+hb1J0ewuDtX+w@mail.gmail.com","threadId":"58146","inReplyTo":null,"subject":"BUG: git-check-ignore documentation doesn't come close to describing what it really does","fromName":"Britton Kerin","fromEmail":"britton.kerin@gmail.com","sentAt":"2022-07-12T23:02:47Z","receivedAt":"2022-07-12T23:03:01Z","isPatch":false,"sender":{"key":"britton.kerin@gmail.com","avatar":"https://avatars.githubusercontent.com/u/7434164?v=4"},"body":"It begins:\n\n       For each pathname given via the command-line or from a file via\n--stdin, check whether\n       the file is excluded by .gitignore (or other input files to the\nexclude mechanism) and output\n       the path if it is excluded.\n\nIn fact it just reports matches from .gitignore etc:\n\n     $ cat .gitignore\n     *.o\n     !*.dont_ignore\n     $ ls\n     bar.o.dont_ignore  foo.o\n     $ git check-ignore -v -n *\n     .gitignore:2:!*.dont_ignore bar.o.dont_ignore\n     .gitignore:1:*.o foo.o\n     $ # Even more confusing without -v -n:\n     $ git check-ignore *\n     bar.o.dont_ignore\n     foo.o\n\nThe EXIT STATUS section is even more wrong:\n\n     EXIT STATUS\n            0\n                One or more of the provided paths is ignored.\n\n            1\n                None of the provided paths are ignored.\n\n            128\n                A fatal error was encountered.\n\nbut:\n\n     $ if git check-ignore foo.o.dont_ignore; then echo exited true;\nelse echo exited false; fi\n     foo.o.dont_ignore\n     exited true\n     $\n\nIMO the behavior of git-check-ignore is the correct and useful\nbehavior and the documentation should simply be fixed to reflect the\nfact that it just lists matching entries rather than wrongly claiming\nthat it returns the overall result of the ignore calculation.\n\nBritton\n"},{"id":"458928","messageId":"CABPp-BG5qjp9Rx+=CCeLMiOH2Bqpa3kmBWRWdu7fTtPM-H=3kA@mail.gmail.com","threadId":"58146","inReplyTo":"CAC4O8c9izkV5vbnE6MH8-RwnxRbUONxJxYZO+hb1J0ewuDtX+w@mail.gmail.com","subject":"Re: BUG: git-check-ignore documentation doesn't come close to describing what it really does","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-07-13T00:17:23Z","receivedAt":"2022-07-13T00:17:44Z","isPatch":false,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"Hi,\n\nThanks for the report.\n\nOn Tue, Jul 12, 2022 at 4:34 PM Britton Kerin <britton.kerin@gmail.com> wrote:\n>\n> It begins:\n>\n>        For each pathname given via the command-line or from a file via\n> --stdin, check whether\n>        the file is excluded by .gitignore (or other input files to the\n> exclude mechanism) and output\n>        the path if it is excluded.\n\nI suspect we're having an aliasing problem that you're not\nrecognizing.  \"ignored\" and \"excluded\" are used interchangeably, note\nthat patterns from the $GIT_DIR/info/exclude files and patterns from\nthe file pointed to by core.excludesFile are also lumped together with\nthe patterns from all the .gitignore files (see the gitignore manual\npage).  Further, the internal code refers to them all as \"excludes\"\nnot as \"ignores\".\n\n(And then we adopted the same syntax for sparse checkouts, except we\nused it to mark things that should be included, and we referred\neveryone to the documentation about \"excludes\" to learn the format for\nwhat to \"include\".  Ugh.)\n\n>\n> In fact it just reports matches from .gitignore etc:\n\nYes, it outputs the paths that are excluded, as the documentation\nsaid.  Perhaps there's a way to reword it to make this clearer?  I\ndon't think we can get rid of the alias given the fact that\n$GIT_DIR/info/exclude and core.excludesFile are hard-coded and must be\nkept for backward compatibility.  But suggestions to improve the\nwording would be great.\n\nMaybe it'd be as simple as replacing \"is excluded\" with \"matches an\nignore/exclude rule\"?\n\n>      $ cat .gitignore\n>      *.o\n>      !*.dont_ignore\n>      $ ls\n>      bar.o.dont_ignore  foo.o\n>      $ git check-ignore -v -n *\n>      .gitignore:2:!*.dont_ignore bar.o.dont_ignore\n>      .gitignore:1:*.o foo.o\n>      $ # Even more confusing without -v -n:\n>      $ git check-ignore *\n>      bar.o.dont_ignore\n>      foo.o\n>\n> The EXIT STATUS section is even more wrong:\n>\n>      EXIT STATUS\n>             0\n>                 One or more of the provided paths is ignored.\n\n\"is ignored\", meaning \"matches an ignore/exclude rule\".  Perhaps we\nshould update the docs with that textual change?\n\n>             1\n>                 None of the provided paths are ignored.\n\nand replace \"are ignored\" with the same phrase here?\n\n>\n>             128\n>                 A fatal error was encountered.\n>\n> but:\n>\n>      $ if git check-ignore foo.o.dont_ignore; then echo exited true;\n> else echo exited false; fi\n>      foo.o.dont_ignore\n\nSo the filename matched one of the rules, causing the filename to be printed.\n\n>      exited true\n\nand it returned a 0 exit status, since one of the provided paths was\nignored, as documented.\n\n>      $\n>\n> IMO the behavior of git-check-ignore is the correct and useful\n> behavior\n\nI'm with you here.\n\n> and the documentation should simply be fixed\n\nYes, I agree it's easy to misinterpret.  Would my suggested changes help?\n\n> to reflect the\n> fact that it just lists matching entries rather than wrongly claiming\n> that it returns the overall result of the ignore calculation.\n\nI think I understood where the problems were in the documentation that\ncould lead to misinterpretations in the other two cases you mentioned\nearlier in your email, but I don't understand this one.  Even the\nfirst sentence you quoted included the phrase that it could \"output\nthe path\", so I'm not sure where you think it claims that it'd return\nthe overall result of the ignore calculation.  Could you point out\nwhat in the document led you to believe it was claiming this?  Maybe I\ncould suggest wording improvements for it as well.  Or maybe you have\nsome.\n"},{"id":"458994","messageId":"xmqqtu7lc587.fsf@gitster.g","threadId":"58146","inReplyTo":"CABPp-BG5qjp9Rx+=CCeLMiOH2Bqpa3kmBWRWdu7fTtPM-H=3kA@mail.gmail.com","subject":"Re: BUG: git-check-ignore documentation doesn't come close to describing what it really does","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-07-13T17:06:16Z","receivedAt":"2022-07-13T17:06:26Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n> I suspect we're having an aliasing problem that you're not\n> recognizing.  \"ignored\" and \"excluded\" are used interchangeably, note\n> that patterns from the $GIT_DIR/info/exclude files and patterns from\n> the file pointed to by core.excludesFile are also lumped together with\n> the patterns from all the .gitignore files (see the gitignore manual\n> page).  Further, the internal code refers to them all as \"excludes\"\n> not as \"ignores\".\n\nAll true.\n\n> Yes, it outputs the paths that are excluded, as the documentation\n> said.  Perhaps there's a way to reword it to make this clearer?  I\n> don't think we can get rid of the alias given the fact that\n> $GIT_DIR/info/exclude and core.excludesFile are hard-coded and must be\n> kept for backward compatibility.  But suggestions to improve the\n> wording would be great.\n>\n> Maybe it'd be as simple as replacing \"is excluded\" with \"matches an\n> ignore/exclude rule\"?\n\nI smell a continuation of 7ec8125f (check-ignore: fix documentation\nand implementation to match, 2020-02-18), which appears in 2.26 and\nlater (the way the negative entries in the ignore/exclude mechanism\ngets handled has changed in Git 2.26, and the documentation has been\nupdated).\n\n\"Is excluded\" is perfectly fine, I think.  The first use of that\nverb in the documentation should be a bit more careful, e.g. \"is\nexcluded (aka ignored)\" or something.\n\n>> IMO the behavior of git-check-ignore is the correct and useful\n>> behavior\n>\n> I'm with you here.\n\nYup, with the old \"huh?\" fixed in Git 2.26 (which was there simply\nbecause check-ignore was not used to be a serious end-user facing\nprogram but was more of a debugging aid), I think the behaviour of\nthe command we have today is what we want.\n\n>> and the documentation should simply be fixed\n>\n> Yes, I agree it's easy to misinterpret.  Would my suggested changes help?\n>\n>> to reflect the\n>> fact that it just lists matching entries rather than wrongly claiming\n>> that it returns the overall result of the ignore calculation.\n>\n> I think I understood where the problems were in the documentation that\n> could lead to misinterpretations in the other two cases you mentioned\n> earlier in your email, but I don't understand this one.  Even the\n> first sentence you quoted included the phrase that it could \"output\n> the path\", so I'm not sure where you think it claims that it'd return\n> the overall result of the ignore calculation.  Could you point out\n> what in the document led you to believe it was claiming this?  Maybe I\n> could suggest wording improvements for it as well.  Or maybe you have\n> some.\n\nIt does return *the* matching entry that decided the path's fate.\n\n    $ (echo '/no-such-*'; echo '!/no-such-*') >>.git/info/exclude\n    $ git check-ignore -v no-such-directory; echo $?\n    .git/info/exclude:14:!/no-such-*\tno-such-directory\n    0\n\nExit status section needs a bit more work.  It used to be OK to say\n\"success (0) is returned when we found a path that is ignored\", but\nthese days, it is not whether there are ignored paths in the input.\n\nIt signals if we found an entry in the list of exclude/ignore\npatterns that actively affects the path's fate.  In our project, if\nwe ask the fate of hello.c\n\n    $ git check-itnore -v hello.c; echo $?\n    1\n\nbecause we do not say explicitly that .c files are usually tracked\nsources.  If we did this:\n\n    $ echo >>.git/info/exclude '!*.c'\n\nto explicitly say that .c files are never ignored, it changes the\npicture:\n\n    $ git check-itnore -v hello.c; echo $?\n    .git/info/exclude:15:!*.c\thello.c\n    0\n\n\n"},{"id":"459339","messageId":"20220718232843.151392-1-britton.kerin@gmail.com","threadId":"58146","inReplyTo":"xmqqtu7lc587.fsf@gitster.g","subject":"Re: BUG: git-check-ignore documentation doesn't come close to describing what it really does","fromName":"Britton Leo Kerin","fromEmail":"britton.kerin@gmail.com","sentAt":"2022-07-18T23:28:43Z","receivedAt":"2022-07-18T23:28:51Z","isPatch":false,"sender":{"key":"britton.kerin@gmail.com","avatar":"https://avatars.githubusercontent.com/u/7434164?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Elijah Newren <newren@gmail.com> writes:\n>\n> > I suspect we're having an aliasing problem that you're not\n> > recognizing.  \"ignored\" and \"excluded\" are used interchangeably, note\n> > that patterns from the $GIT_DIR/info/exclude files and patterns from\n> > the file pointed to by core.excludesFile are also lumped together with\n> > the patterns from all the .gitignore files (see the gitignore manual\n> > page).  Further, the internal code refers to them all as \"excludes\"\n> > not as \"ignores\".\n>\n> All true.\n\nI wasn't surprised that 'ignoread' and 'excluded' are used interchangably,\nthat's not the problem.\n\n> > Yes, it outputs the paths that are excluded, as the documentation\n> > said.  Perhaps there's a way to reword it to make this clearer?  I\n> > don't think we can get rid of the alias given the fact that\n> > $GIT_DIR/info/exclude and core.excludesFile are hard-coded and must be\n> > kept for backward compatibility.  But suggestions to improve the\n> > wording would be great.\n> >\n> > Maybe it'd be as simple as replacing \"is excluded\" with \"matches an\n> > ignore/exclude rule\"?\n>\n> I smell a continuation of 7ec8125f (check-ignore: fix documentation\n> and implementation to match, 2020-02-18), which appears in 2.26 and\n> later (the way the negative entries in the ignore/exclude mechanism\n> gets handled has changed in Git 2.26, and the documentation has been\n> updated).\n>\n> \"Is excluded\" is perfectly fine, I think.  The first use of that\n> verb in the documentation should be a bit more careful, e.g. \"is\n> excluded (aka ignored)\" or something.\n\nI think replacing with \"matches an ignore/exclude rule\" is prefereable since\nthat's what's actually going on.  It's still a bit unfortunate since the\nignore/exclude terms are potentially confusing in the presence of dont-ignore\n(!) rules, but it seems likely that people running check-ignore are looking to\nsort out something complicated and are probably aware of negative rules, and\nanyway they get a ! to clue them in :)\n\nAdding some explanation to the first use of \"excluded\" would in principle solve\nthe problem by itself and give licence to use the term however you want, but to\nbe honest I'm not sure I would have read that paragraph carefully enough to get\nthe idea.  It still seems better to me to use different language each time it\ncomes up in the page.\n\n> >> IMO the behavior of git-check-ignore is the correct and useful\n> >> behavior\n> >\n> > I'm with you here.\n>\n> Yup, with the old \"huh?\" fixed in Git 2.26 (which was there simply\n> because check-ignore was not used to be a serious end-user facing\n> program but was more of a debugging aid), I think the behaviour of\n> the command we have today is what we want.\n>\n> >> and the documentation should simply be fixed\n> >\n> > Yes, I agree it's easy to misinterpret.  Would my suggested changes help?\n> >\n> >> to reflect the\n> >> fact that it just lists matching entries rather than wrongly claiming\n> >> that it returns the overall result of the ignore calculation.\n> >\n> > I think I understood where the problems were in the documentation that\n> > could lead to misinterpretations in the other two cases you mentioned\n> > earlier in your email, but I don't understand this one.  Even the\n> > first sentence you quoted included the phrase that it could \"output\n> > the path\", so I'm not sure where you think it claims that it'd return\n> > the overall result of the ignore calculation.  Could you point out\n> > what in the document led you to believe it was claiming this?  Maybe I\n> > could suggest wording improvements for it as well.  Or maybe you have\n> > some.\n>\n> It does return *the* matching entry that decided the path's fate.\n>\n>     $ (echo '/no-such-*'; echo '!/no-such-*') >>.git/info/exclude\n>     $ git check-ignore -v no-such-directory; echo $?\n>     .git/info/exclude:14:!/no-such-*\tno-such-directory\n>     0\n\nGood point: it's not exactly a full query either.\n\nIf it would be welcome and hasn't already been done I could rewrite this page\nto be clearer without adding or changing much.\n\nBritton\n"},{"id":"459344","messageId":"xmqqa695ehx2.fsf@gitster.g","threadId":"58146","inReplyTo":"20220718232843.151392-1-britton.kerin@gmail.com","subject":"Re: BUG: git-check-ignore documentation doesn't come close to describing what it really does","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-07-19T06:27:21Z","receivedAt":"2022-07-19T06:27:29Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Britton Leo Kerin <britton.kerin@gmail.com> writes:\n\n>> \"Is excluded\" is perfectly fine, I think.  The first use of that\n>> verb in the documentation should be a bit more careful, e.g. \"is\n>> excluded (aka ignored)\" or something.\n>\n> I think replacing with \"matches an ignore/exclude rule\" is prefereable since\n> that's what's actually going on.\n\nUnfortunately, it is only half of what's actually going on, isn't\nit?  If the last match is with a positive entry, then it is excluded\n(aka ignored).  If the last match is with a negative entry, then it\nis not excluded (and not shown without \"-v\").  That is demonstrated\nby the example:\n\n>> It does return *the* matching entry that decided the path's fate.\n>>\n>>     $ (echo '/no-such-*'; echo '!/no-such-*') >>.git/info/exclude\n>>     $ git check-ignore -v no-such-directory; echo $?\n>>     .git/info/exclude:14:!/no-such-*\tno-such-directory\n>>     0\n\nand\n\n    $ git check-ignore no-such-directory; echo $?\n    1\n\ni.e. with \"-v\", the output can give enough clue to the user if the\nmatch was with positive or negative entry, but without \"-v\", the\nexit status reports if the given path is \"excluded (aka ignored)\".\nIn the above case, the last entry that matches the path\n\"no-such-directory\" is a negative entry, so the path is not\nexcluded, hence there is no output (as documented, excluded paths\nare output).\n\nIf we remove the last line from .git/info/exclude, then the\ntranscript would become:\n\n    $ git check-ignore no-such-directory; echo $?\n    no-such-directory\n    0\n    $ git check-ignore -v no-such-directory; echo $?\n    .git/info/exclude:13:/no-such-* no-such-directory\n    0\n\nAs the last entry that matches the path is a positive entry in this\ncase, the path is excluded and it is shown in the output without\n\"-v\" and the command exits with success (i.e. is excluded).\n\nHere is a rough attempt to clarify what I found was unclear in the\ncurrent documentation.\n\nThanks.\n\n Documentation/git-check-ignore.txt | 16 ++++++++++------\n 1 file changed, 10 insertions(+), 6 deletions(-)\n\ndiff --git c/Documentation/git-check-ignore.txt w/Documentation/git-check-ignore.txt\nindex 2892799e32..a5491386cf 100644\n--- c/Documentation/git-check-ignore.txt\n+++ w/Documentation/git-check-ignore.txt\n@@ -16,7 +16,8 @@ DESCRIPTION\n -----------\n \n For each pathname given via the command-line or from a file via\n-`--stdin`, check whether the file is excluded by .gitignore (or other\n+`--stdin`, check whether the file is excluded (aka \"ignored\"---these\n+words are used interchangeably) by .gitignore (or other\n input files to the exclude mechanism) and output the path if it is\n excluded.\n \n@@ -31,11 +32,12 @@ OPTIONS\n \n -v, --verbose::\n \tInstead of printing the paths that are excluded, for each path\n-\tthat matches an exclude pattern, print the exclude pattern\n-\ttogether with the path.  (Matching an exclude pattern usually\n+\tthat matches an exclude pattern (or more), print the exclude\n+\tpattern that decides if the path is excluded or not excluded,\n+\ttogether with the path.  Matching an exclude pattern usually\n \tmeans the path is excluded, but if the pattern begins with \"`!`\"\n \tthen it is a negated pattern and matching it means the path is\n-\tNOT excluded.)\n+\tNOT excluded.\n +\n For precedence rules within and between exclude sources, see\n linkgit:gitignore[5].\n@@ -65,10 +67,12 @@ linkgit:gitignore[5].\n OUTPUT\n ------\n \n-By default, any of the given pathnames which match an ignore pattern\n+By default, any of the given pathnames which are excluded (aka ignored)\n will be output, one per line.  If no pattern matches a given path,\n nothing will be output for that path; this means that path will not be\n-ignored.\n+ignored.  If the pattern that matched the path is a negative one (i.e.\n+prefixed with \"`!`\"), the path is not excluded and nothing is output\n+for the path.\n \n If `--verbose` is specified, the output is a series of lines of the form:\n \n"}]}