{"thread":{"id":"28867","subject":"[RFC/PATCH 0/5] gitignore.5 clarifications","startedAt":"2011-11-07T08:04:55Z","lastAt":"2011-11-07T16:53:28Z","messageCount":10,"participants":["Jonathan Nieder","Nguyen Thai Ngoc Duy","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":5},"messages":[{"id":"179008","messageId":"20111107080449.GA30448@elie.hsd1.il.comcast.net","threadId":"28867","inReplyTo":null,"subject":"[RFC/PATCH 0/5] gitignore.5 clarifications","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-11-07T08:04:55Z","receivedAt":"2011-11-07T08:04:55Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nY.G. noticed that the explanation of '/' handling in the gitignore\ndocs are hard to follow.  Worse, it's completely wrong in a number\nof ways.\n\nHere's a series to fix a few of those.  Impact:\n\n - remove some complete nonsense (how did I mislead myself into\n   thinking patterns without a '/' were anchored?)\n\n - address the frequently asked question \"how do I un-ignore part of a\n   directory I have ignored?\"\n\n - relive what seems to be a bug (even when the \"foo/\" directory is\n   ignored, a \"git add foo/bar\" should add new changes to the index\n   when that file is already tracked)\n\n - some minor clarity improvements\n\nAt this point, I can hardly trust myself, so careful review for\ncorrectness and clarity would be very welcome.\n\nIncorporates material from\nhttp://thread.gmane.org/gmane.comp.version-control.git/170907/focus=170916\n\nJohannes Sixt (1):\n  Documentation/gitignore: explain how to un-ignore part of a directory\n\nJonathan Nieder (3):\n  Documentation/gitignore: \"foo/\" patterns match directories, not files\n    under them\n  Documentation: clarify effect of '/' in gitignore(5) patterns\n  Documentation: unanchored gitignore patterns match basename\n\n Documentation/gitignore.txt |   48 ++++++++++++++++++++++++++++++------------\n 1 files changed, 34 insertions(+), 14 deletions(-)\n"},{"id":"179009","messageId":"20111107080711.GA30486@elie.hsd1.il.comcast.net","threadId":"28867","inReplyTo":"20111107080449.GA30448@elie.hsd1.il.comcast.net","subject":"[PATCH 1/4] Documentation/gitignore: \"foo/\" patterns match directories, not files under them","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-11-07T08:07:11Z","receivedAt":"2011-11-07T08:07:11Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"The gitignore(5) manpage says that \"foo/\" will match a directory foo\nand paths underneath it.  But that is completely false: as Johannes\nSixt likes to remind us, patterns with a trailing '/' match the named\ndirectory, not files under that directory.  For example, the following\n.gitignore file\n\n\t/build/\n\t!/build/tests/results\n\ndoes not un-ignore build/tests/results since it was never ignored in\nthe first place; and commands like \"git status\" will not notice\nchanges to build/tests/results because git doesn't enter the (ignored)\nbuild/ directory.\n\nCorrect the manual to just say that \"foo/\" matches the directory\n\"foo\", and make the wording a little clearer in other ways while at\nit.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n Documentation/gitignore.txt |   14 ++++++++------\n 1 files changed, 8 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt\nindex 2e7328b8..5b070bf0 100644\n--- a/Documentation/gitignore.txt\n+++ b/Documentation/gitignore.txt\n@@ -72,12 +72,14 @@ PATTERN FORMAT\n    included again.  If a negated pattern matches, this will\n    override lower precedence patterns sources.\n \n- - If the pattern ends with a slash, it is removed for the\n-   purpose of the following description, but it would only find\n-   a match with a directory.  In other words, `foo/` will match a\n-   directory `foo` and paths underneath it, but will not match a\n-   regular file or a symbolic link `foo` (this is consistent\n-   with the way how pathspec works in general in git).\n+ - If the pattern ends with a slash, it will only match\n+   directories.  In other words, `foo/` will match a\n+   directory `foo` but will not match a regular file or a\n+   symbolic link `foo` (this is consistent with the way\n+   pathspecs work in general in git).\n++\n+The trailing slash is removed before applying the remaining\n+rules.\n \n  - If the pattern does not contain a slash '/', git treats it as\n    a shell glob pattern and checks for a match against the\n-- \n1.7.8.rc0\n"},{"id":"179010","messageId":"20111107080842.GB30486@elie.hsd1.il.comcast.net","threadId":"28867","inReplyTo":"20111107080449.GA30448@elie.hsd1.il.comcast.net","subject":"[PATCH 2/4] Documentation: clarify effect of '/' in gitignore(5) patterns","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-11-07T08:08:42Z","receivedAt":"2011-11-07T08:08:42Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"The introduction of directory-only matches in v1.5.5-rc0~208^2~1\n(gitignore(5): Allow \"foo/\" in ignore list to match directory \"foo\",\n2008-01-31) was a small, incremental change to gitignore syntax that\ndid not affect the rest of the rules in any major way.  A '/' at the\nend of a pattern means \"match directories only\" and does not otherwise\naffect the pattern.  And that is how the gitignore(5) manpage explains\nthe syntax.\n\nHowever, to a person parsing an unfamiliar gitignore entry like foo/,\nit is too easy to notice the later (old) rule that describes how\npatterns containing a slash are anchored and miss that the slash\nshould have been stripped off before considering whether the rule\napplies.\n\nLet's just explicitly say that patterns are only anchored if they\ncontain a slash that is not at the end of the pattern, avoiding this\nconfusion.  A more graceful presentation of this material may be\npossible, but for now the goal is to get the facts clear --- we can\nrefactor the text to scan well without losing its meaning later.\n\n(While at it, tweak the wording for clarity and add an example.)\n\nReported-by: Y.G. <yamomo1@hotmail.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n Documentation/gitignore.txt |   24 +++++++++++++-----------\n 1 files changed, 13 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt\nindex 5b070bf0..c7c948dd 100644\n--- a/Documentation/gitignore.txt\n+++ b/Documentation/gitignore.txt\n@@ -77,19 +77,21 @@ PATTERN FORMAT\n    directory `foo` but will not match a regular file or a\n    symbolic link `foo` (this is consistent with the way\n    pathspecs work in general in git).\n-+\n-The trailing slash is removed before applying the remaining\n-rules.\n \n- - If the pattern does not contain a slash '/', git treats it as\n-   a shell glob pattern and checks for a match against the\n-   pathname relative to the location of the `.gitignore` file\n-   (relative to the toplevel of the work tree if not from a\n-   `.gitignore` file).\n+ - If the pattern does not contain a slash '/' at the beginning\n+   or in the middle, git treats it as a shell glob pattern and\n+   matches the entire pathname including slashes, relative to the\n+   location of the `.gitignore` file (or relative to the toplevel\n+   of the work tree if the pattern is not from a `.gitignore`\n+   file), against it.\n+   For example, \"{asterisk}.html\" matches HTML files in the\n+   directory containing the `.gitignore` file and in its\n+   subdirectories.\n \n- - Otherwise, git treats the pattern as a shell glob suitable\n-   for consumption by fnmatch(3) with the FNM_PATHNAME flag:\n-   wildcards in the pattern will not match a / in the pathname.\n+ - If the pattern contains a slash '/' at the beginning or in the\n+   middle, git imitates the behavior of fnmatch(3) with the\n+   FNM_PATHNAME flag: wildcards in the pattern will not match a /\n+   in the pathname.\n    For example, \"Documentation/{asterisk}.html\" matches\n    \"Documentation/git.html\" but not \"Documentation/ppc/ppc.html\"\n    or \"tools/perf/Documentation/perf.html\".\n-- \n1.7.8.rc0\n"},{"id":"179011","messageId":"20111107080926.GC30486@elie.hsd1.il.comcast.net","threadId":"28867","inReplyTo":"20111107080449.GA30448@elie.hsd1.il.comcast.net","subject":"[PATCH 3/4] Documentation: unanchored gitignore patterns match basename","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-11-07T08:09:26Z","receivedAt":"2011-11-07T08:09:26Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"The rule described by v1.7.1.1~31^2 (gitignore.5: Clarify matching\nrules, 2010-03-05) is just false: simple gitignore patterns without a\nslash like \"foo\" and \"cscope*\" have always matched files in all\ndirectories, not just the toplevel, and a question mark cannot be used\nto match the slash separating path components.\n\nFor example:\n\n\tfoo/ - matches directories named \"foo\" throughout the tree\n\tDocumentation?foo - does not match Documentation/foo\n\nReported-by: Y.G. <yamomo1@hotmail.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n Documentation/gitignore.txt |   19 ++++++++++---------\n 1 files changed, 10 insertions(+), 9 deletions(-)\n\ndiff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt\nindex c7c948dd..e5715a27 100644\n--- a/Documentation/gitignore.txt\n+++ b/Documentation/gitignore.txt\n@@ -80,18 +80,19 @@ PATTERN FORMAT\n \n  - If the pattern does not contain a slash '/' at the beginning\n    or in the middle, git treats it as a shell glob pattern and\n-   matches the entire pathname including slashes, relative to the\n-   location of the `.gitignore` file (or relative to the toplevel\n-   of the work tree if the pattern is not from a `.gitignore`\n-   file), against it.\n-   For example, \"{asterisk}.html\" matches HTML files in the\n-   directory containing the `.gitignore` file and in its\n-   subdirectories.\n+   checks if the pathname with leading path components\n+   removed matches it.\n+   For example, \"x{asterisk}.html\" matches HTML files whose\n+   filename begins with an \"x\" in the directory containing\n+   the `.gitignore` file and in its subdirectories.\n \n  - If the pattern contains a slash '/' at the beginning or in the\n    middle, git imitates the behavior of fnmatch(3) with the\n-   FNM_PATHNAME flag: wildcards in the pattern will not match a /\n-   in the pathname.\n+   FNM_PATHNAME flag.  The pattern is used to match the entire\n+   pathname, relative to the location of the `.gitignore` file\n+   (or relative to the toplevel of the work tree if the pattern\n+   is not from a `.gitignore` file).  Wildcards in the pattern\n+   do not match a / in the pathname.\n    For example, \"Documentation/{asterisk}.html\" matches\n    \"Documentation/git.html\" but not \"Documentation/ppc/ppc.html\"\n    or \"tools/perf/Documentation/perf.html\".\n-- \n1.7.8.rc0\n"},{"id":"179012","messageId":"20111107081132.GD30486@elie.hsd1.il.comcast.net","threadId":"28867","inReplyTo":"20111107080449.GA30448@elie.hsd1.il.comcast.net","subject":"[PATCH 4/4] Documentation/gitignore: explain how to un-ignore part of a directory","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-11-07T08:11:32Z","receivedAt":"2011-11-07T08:11:32Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"From: Johannes Sixt <j6t@kdbg.org>\nDate: Tue, 5 Apr 2011 23:15:54 +0200\n\nTrying to whitelist a single file pattern in a directory that I was\notherwise content to ignore, if I try\n\n\t/m4/\n\t!/m4/virt-*.m4\n\nthen 'git add' will keep warning me that I have to use -f.  That is\nbecause ignoring a directory is much different than ignoring all files\nin a directory, when it comes to later negation patterns:\n\n\t/m4/*\n\t!/m4/virt-*.m4\n\nHowever, this example is misleading because it gives the false\nimpression that you could do\n\n\t/foo/*\n\t!/foo/bar/baz\n\nand have foo/bar/baz not ignored, and it is still ignored.  Add a\nparagraph in the NOTES section explaining the general rule and\nsuggesting ignoring the directory and using \"git add -f\" to track\nexceptions to cope with it.\n\n[jn: change description distilled from messages by Eric and Hannes\nto the mailing list.\n\nAs Eric noticed, while the \"git add -f\" trick works well with\ncommands like \"git status\" and \"git add -u\", plain \"git add\nsubdir/<path>\" refuses to update the index with changes from an\nignored subdirectory.  When describing the trick, explicitly list a\nfew commands that already behave appropriately to avoid confusion.]\n\nReported-by: Eric Blake <eblake@redhat.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\nThat's the end of the series.  Thoughts?\n\n Documentation/gitignore.txt |   15 +++++++++++++++\n 1 files changed, 15 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt\nindex e5715a27..8b6f601e 100644\n--- a/Documentation/gitignore.txt\n+++ b/Documentation/gitignore.txt\n@@ -113,6 +113,21 @@ use 'git update-index {litdd}assume-unchanged'.\n To stop tracking a file that is currently tracked, use\n 'git rm --cached'.\n \n+When a directory is ignored, it is not possible to un-ignore a single file\n+somewhere in the directory using another pattern. E.g., with the patterns\n+\n+--------------\n+/build/\n+!/build/tests/results\n+--------------\n+\n+the file \"build/tests/results\" is still ignored because when a directory is\n+ignored, its contents are never investigated. In a situation where a few\n+exceptions in an otherwise ignored hierarchy are needed, the recommended\n+procedure is to specify to ignore the root of the hierarchy and then to 'git\n+add -f' the exceptional files. Subsequent changes to the files will not be\n+ignored by 'git status', 'git add .', 'git add -u', or 'git commit -a'.\n+\n EXAMPLES\n --------\n \n-- \n1.7.8.rc0\n"},{"id":"179019","messageId":"CACsJy8CZFihbS8MrG=0gWdRPu6F0BqG2FLp48KDxOXWc+4amuQ@mail.gmail.com","threadId":"28867","inReplyTo":"20111107080711.GA30486@elie.hsd1.il.comcast.net","subject":"Re: [PATCH 1/4] Documentation/gitignore: \"foo/\" patterns match directories, not files under them","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-11-07T09:57:01Z","receivedAt":"2011-11-07T09:57:01Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"2011/11/7 Jonathan Nieder <jrnieder@gmail.com>:\n> The gitignore(5) manpage says that \"foo/\" will match a directory foo\n> and paths underneath it.\n\nIf git ignores a directory, then it essentially ignores all paths\nunderneath it, doesn't it?\n\n> But that is completely false: as Johannes\n> Sixt likes to remind us, patterns with a trailing '/' match the named\n> directory, not files under that directory.  For example, the following\n> .gitignore file\n>\n>        /build/\n>        !/build/tests/results\n>\n> does not un-ignore build/tests/results since it was never ignored in\n> the first place; and commands like \"git status\" will not notice\n> changes to build/tests/results because git doesn't enter the (ignored)\n> build/ directory.\n\nI haven't checked but I think it's because when a directory is\nignored, git just stops checking further ignore rules. So \"build\" _is_\nignored, too strongly that it does not care if some files may need to\nbe un-ignored later on.\n\nI remember the argument was, because ignore rules are distributed\nacross .gitignore files, we would need to go into ignored directories\nfor collecting potential un-ignore rules (for example \"!results\" on\nbuild/tests/.gitignore) and that just does not make much sense because\nwe always have to go into ignored directories.\n\nBut in your example, where we know we have negated rules, we should\nfollow the rules and ignore all but build/tests/results.\n\n> Correct the manual to just say that \"foo/\" matches the directory\n> \"foo\", and make the wording a little clearer in other ways while at\n> it.\n\nI haven't not read the next patches, maybe you have mentioned this\nalready. We should make clear that git does not look for negated rules\nonce a directory is ignored.\n\nYour example however demonstrates a bug that should be fixed in my\nopinion. So maybe one or two lines under BUGS section.\n\n> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n> ---\n>  Documentation/gitignore.txt |   14 ++++++++------\n>  1 files changed, 8 insertions(+), 6 deletions(-)\n>\n> diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt\n> index 2e7328b8..5b070bf0 100644\n> --- a/Documentation/gitignore.txt\n> +++ b/Documentation/gitignore.txt\n> @@ -72,12 +72,14 @@ PATTERN FORMAT\n>    included again.  If a negated pattern matches, this will\n>    override lower precedence patterns sources.\n>\n> - - If the pattern ends with a slash, it is removed for the\n> -   purpose of the following description, but it would only find\n> -   a match with a directory.  In other words, `foo/` will match a\n> -   directory `foo` and paths underneath it, but will not match a\n> -   regular file or a symbolic link `foo` (this is consistent\n> -   with the way how pathspec works in general in git).\n> + - If the pattern ends with a slash, it will only match\n> +   directories.  In other words, `foo/` will match a\n> +   directory `foo` but will not match a regular file or a\n> +   symbolic link `foo` (this is consistent with the way\n> +   pathspecs work in general in git).\n\nLooks good.\n\n> ++\n> +The trailing slash is removed before applying the remaining\n> +rules.\n\nWhy does the trailing slash of a rule affect the remaining rules?\n-- \nDuy\n"},{"id":"179020","messageId":"CACsJy8AnPD7NFeCbMG+vy5YvWWfb5CwaRX=qRkOE8_Hk_9zUNw@mail.gmail.com","threadId":"28867","inReplyTo":"20111107080842.GB30486@elie.hsd1.il.comcast.net","subject":"Re: [PATCH 2/4] Documentation: clarify effect of '/' in gitignore(5) patterns","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-11-07T10:05:15Z","receivedAt":"2011-11-07T10:05:15Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"2011/11/7 Jonathan Nieder <jrnieder@gmail.com>:\n> The introduction of directory-only matches in v1.5.5-rc0~208^2~1\n> (gitignore(5): Allow \"foo/\" in ignore list to match directory \"foo\",\n> 2008-01-31) was a small, incremental change to gitignore syntax that\n> did not affect the rest of the rules in any major way.  A '/' at the\n> end of a pattern means \"match directories only\" and does not otherwise\n> affect the pattern.  And that is how the gitignore(5) manpage explains\n> the syntax.\n>\n> However, to a person parsing an unfamiliar gitignore entry like foo/,\n> it is too easy to notice the later (old) rule that describes how\n> patterns containing a slash are anchored and miss that the slash\n> should have been stripped off before considering whether the rule\n> applies.\n\nI think I make this mistake too. Documenting it is one way. Another way is t\n\n>\n> Let's just explicitly say that patterns are only anchored if they\n> contain a slash that is not at the end of the pattern, avoiding this\n> confusion.  A more graceful presentation of this material may be\n> possible, but for now the goal is to get the facts clear --- we can\n> refactor the text to scan well without losing its meaning later.\n\nI think the first slash in 'foo//' may function as the anchor and it's\nnot very clear to me if it's in the middle of pattern of at the end.\nOf course we could just change the code to strip all trailing slashes.\n-- \nDuy\n"},{"id":"179021","messageId":"CACsJy8BLmanoWmUwT4uD+qosxbQYRCaACDFriLA6J7-jUztG6Q@mail.gmail.com","threadId":"28867","inReplyTo":"20111107080926.GC30486@elie.hsd1.il.comcast.net","subject":"Re: [PATCH 3/4] Documentation: unanchored gitignore patterns match basename","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-11-07T10:18:15Z","receivedAt":"2011-11-07T10:18:15Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"2011/11/7 Jonathan Nieder <jrnieder@gmail.com>:\n> The rule described by v1.7.1.1~31^2 (gitignore.5: Clarify matching\n> rules, 2010-03-05) is just false: simple gitignore patterns without a\n> slash like \"foo\" and \"cscope*\" have always matched files in all\n> directories, not just the toplevel, and a question mark cannot be used\n> to match the slash separating path components.\n>\n> For example:\n>\n>        foo/ - matches directories named \"foo\" throughout the tree\n>        Documentation?foo - does not match Documentation/foo\n>\n> Reported-by: Y.G. <yamomo1@hotmail.com>\n> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n\nAcked-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n-- \nDuy\n"},{"id":"179022","messageId":"CACsJy8BND-fg0YoUiSpYo1KiNjt604uQ395+KMTK-E6QP7oSdw@mail.gmail.com","threadId":"28867","inReplyTo":"20111107081132.GD30486@elie.hsd1.il.comcast.net","subject":"Re: [PATCH 4/4] Documentation/gitignore: explain how to un-ignore part of a directory","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-11-07T10:23:27Z","receivedAt":"2011-11-07T10:23:27Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"2011/11/7 Jonathan Nieder <jrnieder@gmail.com>:\n> From: Johannes Sixt <j6t@kdbg.org>\n> Date: Tue, 5 Apr 2011 23:15:54 +0200\n>\n> Trying to whitelist a single file pattern in a directory that I was\n> otherwise content to ignore, if I try\n>\n>        /m4/\n>        !/m4/virt-*.m4\n>\n> then 'git add' will keep warning me that I have to use -f.  That is\n> because ignoring a directory is much different than ignoring all files\n> in a directory, when it comes to later negation patterns:\n>\n>        /m4/*\n>        !/m4/virt-*.m4\n>\n\ngitignore.txt is also referred in sparse checkout. And (un)fortunately\nthe former also works in sparse checkout. I don't know, may be you\ncould put this in a subsection or something reference-able so we could\nmention in sparse checkout document that this part of gitignore.txt\ndoes not apply to sparse checkout?\n-- \nDuy\n"},{"id":"179049","messageId":"7vty6f27sn.fsf@alter.siamese.dyndns.org","threadId":"28867","inReplyTo":"CACsJy8CZFihbS8MrG=0gWdRPu6F0BqG2FLp48KDxOXWc+4amuQ@mail.gmail.com","subject":"Re: [PATCH 1/4] Documentation/gitignore: \"foo/\" patterns match directories, not files under them","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-11-07T16:53:28Z","receivedAt":"2011-11-07T16:53:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:\n\n> 2011/11/7 Jonathan Nieder <jrnieder@gmail.com>:\n>> The gitignore(5) manpage says that \"foo/\" will match a directory foo\n>> and paths underneath it.\n>\n> If git ignores a directory, then it essentially ignores all paths\n> underneath it, doesn't it?\n>\n>> But that is completely false: as Johannes\n>> Sixt likes to remind us, patterns with a trailing '/' match the named\n>> directory, not files under that directory.  For example, the following\n>> .gitignore file\n>>\n>>        /build/\n>>        !/build/tests/results\n>>\n>> does not un-ignore build/tests/results since it was never ignored in\n>> the first place; and commands like \"git status\" will not notice\n>> changes to build/tests/results because git doesn't enter the (ignored)\n>> build/ directory.\n>\n> I haven't checked but I think it's because when a directory is\n> ignored, git just stops checking further ignore rules. So \"build\" _is_\n> ignored, too strongly that it does not care if some files may need to\n> be un-ignored later on.\n>\n> I remember the argument was, because ignore rules are distributed\n> across .gitignore files, we would need to go into ignored directories\n> for collecting potential un-ignore rules (for example \"!results\" on\n> build/tests/.gitignore) and that just does not make much sense because\n> we always have to go into ignored directories.\n>\n> But in your example, where we know we have negated rules, we should\n> follow the rules and ignore all but build/tests/results.\n>\n>> Correct the manual to just say that \"foo/\" matches the directory\n>> \"foo\", and make the wording a little clearer in other ways while at\n>> it.\n>\n> I haven't not read the next patches, maybe you have mentioned this\n> already. We should make clear that git does not look for negated rules\n> once a directory is ignored.\n>\n> Your example however demonstrates a bug that should be fixed in my\n> opinion. So maybe one or two lines under BUGS section.\n>\n>> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n>> ---\n>>  Documentation/gitignore.txt |   14 ++++++++------\n>>  1 files changed, 8 insertions(+), 6 deletions(-)\n>>\n>> diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt\n>> index 2e7328b8..5b070bf0 100644\n>> --- a/Documentation/gitignore.txt\n>> +++ b/Documentation/gitignore.txt\n>> @@ -72,12 +72,14 @@ PATTERN FORMAT\n>>    included again.  If a negated pattern matches, this will\n>>    override lower precedence patterns sources.\n>>\n>> - - If the pattern ends with a slash, it is removed for the\n>> -   purpose of the following description, but it would only find\n>> -   a match with a directory.  In other words, `foo/` will match a\n>> -   directory `foo` and paths underneath it, but will not match a\n>> -   regular file or a symbolic link `foo` (this is consistent\n>> -   with the way how pathspec works in general in git).\n>> + - If the pattern ends with a slash, it will only match\n>> +   directories.  In other words, `foo/` will match a\n>> +   directory `foo` but will not match a regular file or a\n>> +   symbolic link `foo` (this is consistent with the way\n>> +   pathspecs work in general in git).\n>\n> Looks good.\n\nOr just remove \"In other words, ...\" that is bogus. Everything before that\nis correct.\n\n>> ++\n>> +The trailing slash is removed before applying the remaining\n>> +rules.\n>\n> Why does the trailing slash of a rule affect the remaining rules?\n\nLater rule makes a path with and without a slash in it work differently.\nA single token \"foo/\" acts as if there is no trailing slash to match\nany directory in the hierarchy, e.g. it matches a directory \"frotz/foo\".\n"}]}