{"thread":{"id":"17983","subject":"How do I qualify paths in the .gitignore file w.r.t. the repo root directory?","startedAt":"2009-02-24T06:47:13Z","lastAt":"2009-02-26T17:04:41Z","messageCount":15,"participants":["Brent Goodrick","Junio C Hamano","Sitaram Chamarty","Björn Steinbrink"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"105986","messageId":"e38bce640902232247t63a37f63x9f403fbda0744cfd@mail.gmail.com","threadId":"17983","inReplyTo":null,"subject":"How do I qualify paths in the .gitignore file w.r.t. the repo root directory?","fromName":"Brent Goodrick","fromEmail":"bgoodr@gmail.com","sentAt":"2009-02-24T06:47:13Z","receivedAt":"2009-02-24T06:47:13Z","isPatch":false,"sender":{"key":"bgoodr@gmail.com","avatar":"https://gravatar.com/avatar/2399bf5a3468b3516a892183edfd43a7fa0300a2e9d5072189020186961150bc?d=mp&s=160"},"body":"Say I have these files and directories [2]:\n\n  /home/smart_tator/misc_files/.gitignore\n  /home/smart_tator/misc_files/foo/\n  /home/smart_tator/misc_files/bar/\n  /home/smart_tator/misc_files/bar/baz/foo/\n  /home/smart_tator/misc_files/bar/baz/real/\n\nthen I do:\n\n  cd /home/smart_tator/misc_files/; git init\n\nand say I have this line in that .gitignore file:\n\n  foo/\n\nAnd then I naively execute:\n\n  git add bar/\n\nthen the bar/baz/real/ is added, but these are dutifully ignored:\n\n  /home/smart_tator/misc_files/foo/\n  /home/smart_tator/misc_files/bar/baz/foo/\n\nBut consider in my real repo, I have thousands of files, versus the\nTinker Toy example shown above. And consider that I don't know about\nthat bar/baz/foo/ exists ahead of time, because I'm not the only\ndeveloper checking in content to the repo that might contain precious\n\"foo/\"'s to keep. I can't move my top level foo/, as I have tools that\nrely upon that foo/ being in its place.\n\nThat means that we can't solve this problem efficiently/effectively\nwith the negation operator in the .gitignore file:\n\n  foo/\n  !bar/baz/foo/\n\nbecause sooner or later someone is going to get surprised as to why\ntheir foo/ isn't being added in some other subdirectory, and they will\n\"fix it\" by committing a change where they have removed the foo/ from\nthe .gitignore file, thus causing the top level foo/ to show up as\ncandidates for addition in git status output.\n\nIs there some way to express that the foo/ that is to be ignored is\nalways the one in /home/smart_tator/misc_files/ directory, but all\nother foo/ subdirectories in any other directory under consideration\nshould still continue to participate in adds and merges, all without\nhaving to \"over-express\" the exceptions with negation operators?\n\nMaybe the imaginary .gitignore syntax I am thinking of would be one of\nthe following (most of these are just silly/fun):\n\n  </>foo/  # <-- Huh?\n  <top>foo/  # <-- What the ...?\n  //foo/  # <-- Smells like Perforce or Windows UNC paths\n  /foo/ # <-- No! Matches UNIX root filesystem directory paths!\n  >foo/  # <-- You can't have a > character in DOS or Unix paths, can you?\n  $root/foo/  # <-- I like this syntax the best [1]\n\nThanks,\nbg\n\n[1] Maybe there are other \"variables\" besides $root that might be\n    useful to be added in the future, like $HOME.\n[2] By \"repo root directory\", I mean whatever \"$GIT_DIR/..\" resolves to.\n"},{"id":"105991","messageId":"7v1vtomhz1.fsf@gitster.siamese.dyndns.org","threadId":"17983","inReplyTo":"e38bce640902232247t63a37f63x9f403fbda0744cfd@mail.gmail.com","subject":"Re: How do I qualify paths in the .gitignore file w.r.t. the repo root directory?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-02-24T07:06:42Z","receivedAt":"2009-02-24T07:06:42Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Brent Goodrick <bgoodr@gmail.com> writes:\n\n> Say I have these files and directories [2]:\n>\n>   /home/smart_tator/misc_files/.gitignore\n>   /home/smart_tator/misc_files/foo/\n>   /home/smart_tator/misc_files/bar/\n>   /home/smart_tator/misc_files/bar/baz/foo/\n>   /home/smart_tator/misc_files/bar/baz/real/\n>\n> then I do:\n>\n>   cd /home/smart_tator/misc_files/; git init\n>\n> and say I have this line in that .gitignore file:\n>\n>   foo/\n>\n> And then I naively execute:\n>\n>   git add bar/\n>\n> then the bar/baz/real/ is added, but these are dutifully ignored:\n>\n>   /home/smart_tator/misc_files/foo/\n>   /home/smart_tator/misc_files/bar/baz/foo/\n\nI think you are looking for \"/foo/\".  From Documentation/gitignore.txt:\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\nWith this rule, (1) the trailing slash in your \"foo/\" tells git to match\nonly with directories, but (2) it behaves as if you said \"foo\" for all the\nother rules.\n\nWith \"/foo/\", you tell git to match only with a directory, and it is as if\nyou said \"/foo\".\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 without leading directories.\n\nYour \"foo/\" now behaves the same way as \"foo\" behaves.  You are telling\ngit to match directory foo anywhere in the tree.  \"/foo/\" (now behaving\nthe same way as \"/foo\") does not satisfy this criteria so we would skip\nthis rule.\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   For example, \"Documentation/\\*.html\" matches\n   \"Documentation/git.html\" but not\n   \"Documentation/ppc/ppc.html\".  A leading slash matches the\n   beginning of the pathname; for example, \"/*.c\" matches\n   \"cat-file.c\" but not \"mozilla-sha1/sha1.c\".\n\nYour \"foo/\" does not survive to this rule, but \"/foo/\" does.  It now\nbehaves as \"/foo\" and its leading slash makes it match the beginning.\n"},{"id":"106005","messageId":"slrngq7e6c.iti.sitaramc@sitaramc.homelinux.net","threadId":"17983","inReplyTo":"7v1vtomhz1.fsf@gitster.siamese.dyndns.org","subject":"Re: How do I qualify paths in the .gitignore file w.r.t. the repo root directory?","fromName":"Sitaram Chamarty","fromEmail":"sitaramc@gmail.com","sentAt":"2009-02-24T09:07:24Z","receivedAt":"2009-02-24T09:07:24Z","isPatch":false,"sender":{"key":"sitaramc@gmail.com","avatar":"https://avatars.githubusercontent.com/u/43316?v=4"},"body":"On 2009-02-24, Junio C Hamano <gitster@pobox.com> wrote:\n> I think you are looking for \"/foo/\".  From Documentation/gitignore.txt:\n\n[lots of very clear and detailed explanation snipped for\nbrevity...]\n\nI'd been sort of struggling with the part of 'man gitignore'\nthat describes the rules for the exclusion patterns; it just\ndidn't seem as clear as it could have been.  It's very\naccurate, but I (and I noticed a few others on irc) had to\nread very carefully to do anything moderately complex.\n\nA few days ago, 'doener' (BjÃ¶rn Steinbrink) came up with\nsome much simpler rules that said the same thing, and --\nbuilding on the insight that his rules gave me -- I came up\nwith these:\n\n----->8-----\n\nNote that rule 1 merely *modifies* rules 2 and 3, it does not\nsupercede or preclude them.\n\n1.  If you pattern ends with a slash, it matches only\n    directories (and their contents)\n2.  If there is no slash otherwise, it matches that name, at\n    any depth in the tree\n3.  If there is a slash anywhere else, it matches that name,\n    relative to the .gitignore (or $GIT_WORK_TREE if the\n    pattern is from one of the other pattern sources like\n    `.git/info/exclude` etc)\n\nThe wildcards (`*` and `?`) do not match slashes, but otherwise\nthe patterns are normal shell globs as defined by fnmatch(3) with\nthe FNM_PATHNAME flag set.\n\n----->8-----\n\nThose rules are meant to clarify the following lines from\nthe gitignore man page:\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\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 without leading directories.\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"},{"id":"106081","messageId":"7vzlgbhh95.fsf@gitster.siamese.dyndns.org","threadId":"17983","inReplyTo":"slrngq7e6c.iti.sitaramc@sitaramc.homelinux.net","subject":"Re: How do I qualify paths in the .gitignore file w.r.t. the repo root directory?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-02-24T17:33:26Z","receivedAt":"2009-02-24T17:33:26Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sitaram Chamarty <sitaramc@gmail.com> writes:\n\n> On 2009-02-24, Junio C Hamano <gitster@pobox.com> wrote:\n>> I think you are looking for \"/foo/\".  From Documentation/gitignore.txt:\n>\n> [lots of very clear and detailed explanation snipped for\n> brevity...]\n>\n> I'd been sort of struggling with the part of 'man gitignore'\n> that describes the rules for the exclusion patterns; it just\n> didn't seem as clear as it could have been.  It's very\n> accurate, but I (and I noticed a few others on irc) had to\n> read very carefully to do anything moderately complex.\n\nThe existing documentation has an unfortunate history behind it and the\n\"if it ends with a slash it matches only directories\" was bolted on as an\nafterthought; see d6b8fc3 (gitignore(5): Allow \"foo/\" in ignore list to\nmatch directory \"foo\", 2008-01-31).\n\n> A few days ago, 'doener' (BjÃ¶rn Steinbrink) came up with\n> some much simpler rules that said the same thing, and --\n> building on the insight that his rules gave me -- I came up\n> with these:\n>\n> ----->8-----\n>\n> Note that rule 1 merely *modifies* rules 2 and 3, it does not\n> supercede or preclude them.\n>\n> 1.  If you pattern ends with a slash, it matches only\n>     directories (and their contents)\n> 2.  If there is no slash otherwise, it matches that name, at\n>     any depth in the tree\n> 3.  If there is a slash anywhere else, it matches that name,\n>     relative to the .gitignore (or $GIT_WORK_TREE if the\n>     pattern is from one of the other pattern sources like\n>     `.git/info/exclude` etc)\n>\n> The wildcards (`*` and `?`) do not match slashes, but otherwise\n> the patterns are normal shell globs as defined by fnmatch(3) with\n> the FNM_PATHNAME flag set.\n>\n> ----->8-----\n\nNicely written, except that as a non-native speaker I fear \"otherwise\" and\n\"anywhere else\" _might_ leave ambiguity for a pattern that has slash only\nat the end [*1*], but I dunno.  It certainly is much better than what I\nwrote in the current documentation.\n\nPlease send it in a patch form (possibly addressing my ambiguity concern\nif it is real for other people) with a one-liner log message that says\n\"The existing documentation is unreadable even though it may be precise\",\nand I'll apply.\n\nThanks.\n\n[Footnote]\n\n*1* That is why I wrote \"it is removed for the purpose of...\" in the\ndescription, even though I do agree that paragraph is hard to read.\nPerhaps I should have said \"it only matches directories.  The slash at the\nend is ignored for the purpose of the following rules.\" which probably\nwould have flowed a bit more naturally.\n"},{"id":"106089","messageId":"slrngq8f8r.t5k.sitaramc@sitaramc.homelinux.net","threadId":"17983","inReplyTo":"7vzlgbhh95.fsf@gitster.siamese.dyndns.org","subject":"Re: How do I qualify paths in the .gitignore file w.r.t. the repo root directory?","fromName":"Sitaram Chamarty","fromEmail":"sitaramc@gmail.com","sentAt":"2009-02-24T18:31:55Z","receivedAt":"2009-02-24T18:31:55Z","isPatch":false,"sender":{"key":"sitaramc@gmail.com","avatar":"https://avatars.githubusercontent.com/u/43316?v=4"},"body":"On 2009-02-24, Junio C Hamano <gitster@pobox.com> wrote:\n> Please send it in a patch form (possibly addressing my ambiguity concern\n> if it is real for other people) with a one-liner log message that says\n> \"The existing documentation is unreadable even though it may be precise\",\n> and I'll apply.\n\nThank you for the encouragement!  (And to doener as well of\ncourse for the inspiration)\n\nI will send in a suitably amended patch with in the next day\nor so -- I'm half asleep right now, :-(\n\nRegards,\n\nSitaram\n"},{"id":"106128","messageId":"e38bce640902241714s720a4e23v49e0a4ab22da9bde@mail.gmail.com","threadId":"17983","inReplyTo":"7v1vtomhz1.fsf@gitster.siamese.dyndns.org","subject":"Re: How do I qualify paths in the .gitignore file w.r.t. the repo root directory?","fromName":"Brent Goodrick","fromEmail":"bgoodr@gmail.com","sentAt":"2009-02-25T01:14:42Z","receivedAt":"2009-02-25T01:14:42Z","isPatch":false,"sender":{"key":"bgoodr@gmail.com","avatar":"https://gravatar.com/avatar/2399bf5a3468b3516a892183edfd43a7fa0300a2e9d5072189020186961150bc?d=mp&s=160"},"body":"Thanks James and Junio.  I'll try the leading slash. I assumed that\nthe beginning slash means what it means for other tools (meaning a\nfully-qualified path to some file somewhere on the file system), but\napparently such is not the case with git (and I conclude from this\nthat it is actually not possible to store fully qualified paths\n_unless_ the $GIT_DIR is right under the root filesystem).  This isn't\na problem for me, and probably not for most folks, but it was\nconfusing to me the way it was written in the man page.\n\nBrent\n\n\nOn Mon, Feb 23, 2009 at 11:06 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Brent Goodrick <bgoodr@gmail.com> writes:\n>\n> > Say I have these files and directories [2]:\n> >\n> >   /home/smart_tator/misc_files/.gitignore\n> >   /home/smart_tator/misc_files/foo/\n> >   /home/smart_tator/misc_files/bar/\n> >   /home/smart_tator/misc_files/bar/baz/foo/\n> >   /home/smart_tator/misc_files/bar/baz/real/\n> >\n> > then I do:\n> >\n> >   cd /home/smart_tator/misc_files/; git init\n> >\n> > and say I have this line in that .gitignore file:\n> >\n> >   foo/\n> >\n> > And then I naively execute:\n> >\n> >   git add bar/\n> >\n> > then the bar/baz/real/ is added, but these are dutifully ignored:\n> >\n> >   /home/smart_tator/misc_files/foo/\n> >   /home/smart_tator/misc_files/bar/baz/foo/\n>\n> I think you are looking for \"/foo/\".  From Documentation/gitignore.txt:\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>\n> With this rule, (1) the trailing slash in your \"foo/\" tells git to match\n> only with directories, but (2) it behaves as if you said \"foo\" for all the\n> other rules.\n>\n> With \"/foo/\", you tell git to match only with a directory, and it is as if\n> you said \"/foo\".\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 without leading directories.\n>\n> Your \"foo/\" now behaves the same way as \"foo\" behaves.  You are telling\n> git to match directory foo anywhere in the tree.  \"/foo/\" (now behaving\n> the same way as \"/foo\") does not satisfy this criteria so we would skip\n> this rule.\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>   For example, \"Documentation/\\*.html\" matches\n>   \"Documentation/git.html\" but not\n>   \"Documentation/ppc/ppc.html\".  A leading slash matches the\n>   beginning of the pathname; for example, \"/*.c\" matches\n>   \"cat-file.c\" but not \"mozilla-sha1/sha1.c\".\n>\n> Your \"foo/\" does not survive to this rule, but \"/foo/\" does.  It now\n> behaves as \"/foo\" and its leading slash makes it match the beginning.\n"},{"id":"106131","messageId":"slrngq9es5.ik0.sitaramc@sitaramc.homelinux.net","threadId":"17983","inReplyTo":"7vzlgbhh95.fsf@gitster.siamese.dyndns.org","subject":"Re: How do I qualify paths in the .gitignore file w.r.t. the repo root directory?","fromName":"Sitaram Chamarty","fromEmail":"sitaramc@gmail.com","sentAt":"2009-02-25T03:31:17Z","receivedAt":"2009-02-25T03:31:17Z","isPatch":false,"sender":{"key":"sitaramc@gmail.com","avatar":"https://avatars.githubusercontent.com/u/43316?v=4"},"body":"On 2009-02-24, Junio C Hamano <gitster@pobox.com> wrote:\n> Sitaram Chamarty <sitaramc@gmail.com> writes:\n\n>> A few days ago, 'doener' (BjÃ¶rn Steinbrink) came up with\n>> some much simpler rules that said the same thing, and --\n>> building on the insight that his rules gave me -- I came up\n>> with these:\n>>\n>> ----->8-----\n>>\n>> Note that rule 1 merely *modifies* rules 2 and 3, it does not\n>> supercede or preclude them.\n>>\n>> 1.  If you pattern ends with a slash, it matches only\n>>     directories (and their contents)\n>> 2.  If there is no slash otherwise, it matches that name, at\n>>     any depth in the tree\n>> 3.  If there is a slash anywhere else, it matches that name,\n>>     relative to the .gitignore (or $GIT_WORK_TREE if the\n>>     pattern is from one of the other pattern sources like\n>>     `.git/info/exclude` etc)\n>>\n>> The wildcards (`*` and `?`) do not match slashes, but otherwise\n>> the patterns are normal shell globs as defined by fnmatch(3) with\n>> the FNM_PATHNAME flag set.\n>>\n>> ----->8-----\n>\n> Nicely written, except that as a non-native speaker I fear \"otherwise\" and\n> \"anywhere else\" _might_ leave ambiguity for a pattern that has slash only\n> at the end [*1*], but I dunno.  It certainly is much better than what I\n> wrote in the current documentation.\n>\n> Please send it in a patch form (possibly addressing my ambiguity concern\n> if it is real for other people) with a one-liner log message that says\n> \"The existing documentation is unreadable even though it may be precise\",\n> and I'll apply.\n\nI couldn't think of an easy way to clear that up without\nmaking it far more verbose.\n\nThe ambiguity is partly because we're overloading the slash\nto control both \"what matches\" (only a directory, versus\ndirectory / file / symlink) and \"where it matches\" (anchored\nat the directory in which the current .gitignore is found or\nwork tree, versus at any depth underneath).\n\nSo I came up with this (see below).  It keeps the \"what\" and\nthe \"where\" clearly separate, so now the \"otherwise\" applies\nto only one preceding clause, and there is no \"anywhere\nelse\".\n\nIt's a somewhat larger change, replacing all 6 bullets and\nthe line preceding them.  I think it looks nicer but since I\nwrote it, I can't vote ;-)\n\nPlease tell me what you think.  If you like it, I'll send in\nthis patch.  If you prefer the previous one, I'll send that\nin.\n\n[I've also changed $GIT_WORK_TREE in my previous attempt to\n'root of the working tree' because that variable is not\nnormally set, and I don't want to imply that it does]\n\n----->8-----\n\nThe files containing the patterns have the following format:\n\n - A blank line matches no files, so it can serve as a\n   separator for readability.\n\n - A line starting with # serves as a comment.\n\nThis is _how_ the patterns match:\n\n - The wildcards (`*` and `?`) do not match slashes, but\n   otherwise the patterns are normal shell globs as defined\n   by fnmatch(3) with the FNM_PATHNAME flag set.\n\n - An optional prefix '!' negates the pattern; any matching\n   file excluded by a previous pattern will become included\n   again.  If a negated pattern matches, this will override\n   lower precedence patterns sources.\n\nThis is _what_ the patterns match:\n\n - If the pattern ends with a slash, it matches only\n   directories (and their contents), otherwise it matches\n   regular files and symlinks also.\n\nThis is _where_ the patterns match (a trailing slash is\nignored for these rules):\n\n - If there is a slash at the start or within the pattern,\n   it matches paths relative to the .gitignore file in which\n   the pattern is found, or to the root of the working tree\n   if the pattern is from one of the other pattern sources\n   (i.e., `.git/info/exclude`, `core.excludesfile`)\n\n - Otherwise, it matches a path at any depth in the tree\n\n----->8-----\n\nRegards,\n\nSitaram\n"},{"id":"106133","messageId":"slrngq9glm.l8b.sitaramc@sitaramc.homelinux.net","threadId":"17983","inReplyTo":"e38bce640902241714s720a4e23v49e0a4ab22da9bde@mail.gmail.com","subject":"Re: How do I qualify paths in the .gitignore file w.r.t. the repo root directory?","fromName":"Sitaram Chamarty","fromEmail":"sitaramc@gmail.com","sentAt":"2009-02-25T04:01:58Z","receivedAt":"2009-02-25T04:01:58Z","isPatch":false,"sender":{"key":"sitaramc@gmail.com","avatar":"https://avatars.githubusercontent.com/u/43316?v=4"},"body":"On 2009-02-25, Brent Goodrick <bgoodr@gmail.com> wrote:\n> apparently such is not the case with git (and I conclude from this\n> that it is actually not possible to store fully qualified paths\n> _unless_ the $GIT_DIR is right under the root filesystem).  This isn't\n> a problem for me, and probably not for most folks, but it was\n\nI suspect it's not _useful_ also, because it would prevent\nyou from relocating your git work tree to some other path\nwhile getting predictable results.  I'm unable to think of a\nuse-case where that would be desirable, but I admit I\nhaven't thought about it too much.\n\n> confusing to me the way it was written in the man page.\n\nIf you could look at either of my two submissions in this\nthread, and comment on whether they would have helped you in\nthis regard, I'd appreciate it very much.\n\nI prefer the second one that I sent, but don't let that\nprejudice you ;-)\n"},{"id":"106177","messageId":"7vab8aap6t.fsf@gitster.siamese.dyndns.org","threadId":"17983","inReplyTo":"slrngq9es5.ik0.sitaramc@sitaramc.homelinux.net","subject":"Re: How do I qualify paths in the .gitignore file w.r.t. the repo root directory?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-02-25T08:36:10Z","receivedAt":"2009-02-25T08:36:10Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sitaram Chamarty <sitaramc@gmail.com> writes:\n\n> Please tell me what you think.  If you like it, I'll send in\n> this patch.  If you prefer the previous one, I'll send that\n> in.\n> ...\n> The files containing the patterns have the following format:\n>\n>  - A blank line matches no files, so it can serve as a\n>    separator for readability.\n>\n>  - A line starting with # serves as a comment.\n>\n> This is _how_ the patterns match:\n>\n>  - The wildcards (`*` and `?`) do not match slashes, but\n>    otherwise the patterns are normal shell globs as defined\n>    by fnmatch(3) with the FNM_PATHNAME flag set.\n\nI had to read this twice and run \"man 3 fnmatch\" to clear my head.\n\n - In normal shell globs, wildcards '*' and '?' do not match slashes;\n\n - fnmatch(3) with FNM_PATHNAME implements the normal shell globs;\n\n - wildcards do not match slashes in gitignore either.\n\nGiven these three, I am very confused why you say \"but otherwise\".  I\nwould understand it if it were:\n\n    The patterns are treated as normal shell globs defined by fnmatch(3) with\n    FNM_PATHNAME; in other words, the wildcards (`*` and `?`) do not match\n    slashes.\n\n>  - An optional prefix '!' negates the pattern; any matching\n>    file excluded by a previous pattern will become included\n>    again.  If a negated pattern matches, this will override\n>    lower precedence patterns sources.\n\n'!' is not part of _how_ the patterns match.  It is _what happens_ when a\npattern marked as such matches (meaning, the syntax for a line in\ngitignore file is \"an optional '!' followed by a pattern\").\n\n    An optional prefix '!' is not a part of the pattern and it does not\n    affect the match.  When a path matches such a pattern, instead of\n    being ignored, it is unignored.\n\nIt would be good to clarify that '!' is not part of the pattern, as I'd\nlike to take J6t's patch that says gitattributes uses the same pattern as\ngitignore uses.\n\n> This is _what_ the patterns match:\n>\n>  - If the pattern ends with a slash, it matches only\n>    directories (and their contents), otherwise it matches\n>    regular files and symlinks also.\n\nDo we want \"(and their contents)\" here?  Once a directory is ignored like\nthis, none of its contents, including .gitignore file in it, is examined\nbecause we do not even descend into it.\n\n> This is _where_ the patterns match (a trailing slash is\n> ignored for these rules):\n>\n>  - If there is a slash at the start or within the pattern,\n>    it matches paths relative to the .gitignore file in which\n>    the pattern is found, or to the root of the working tree\n>    if the pattern is from one of the other pattern sources\n>    (i.e., `.git/info/exclude`, `core.excludesfile`)\n\n\"at the start or within but not at the end of the pattern\"?\n\n>  - Otherwise, it matches a path at any depth in the tree\n"},{"id":"106210","messageId":"slrngqaa5n.mp1.sitaramc@sitaramc.homelinux.net","threadId":"17983","inReplyTo":"7vab8aap6t.fsf@gitster.siamese.dyndns.org","subject":"Re: How do I qualify paths in the .gitignore file w.r.t. the repo root directory?","fromName":"Sitaram Chamarty","fromEmail":"sitaramc@gmail.com","sentAt":"2009-02-25T11:17:11Z","receivedAt":"2009-02-25T11:17:11Z","isPatch":false,"sender":{"key":"sitaramc@gmail.com","avatar":"https://avatars.githubusercontent.com/u/43316?v=4"},"body":"On 2009-02-25, Junio C Hamano <gitster@pobox.com> wrote:\n> Sitaram Chamarty <sitaramc@gmail.com> writes:\n\n>> This is _how_ the patterns match:\n>>\n>>  - The wildcards (`*` and `?`) do not match slashes, but\n>>    otherwise the patterns are normal shell globs as defined\n>>    by fnmatch(3) with the FNM_PATHNAME flag set.\n>\n> I had to read this twice and run \"man 3 fnmatch\" to clear my head.\n>\n>  - In normal shell globs, wildcards '*' and '?' do not match slashes;\n>\n>  - fnmatch(3) with FNM_PATHNAME implements the normal shell globs;\n>\n>  - wildcards do not match slashes in gitignore either.\n>\n> Given these three, I am very confused why you say \"but otherwise\".  I\n> would understand it if it were:\n>\n>     The patterns are treated as normal shell globs defined by fnmatch(3) with\n>     FNM_PATHNAME; in other words, the wildcards (`*` and `?`) do not match\n>     slashes.\n\nI'll use that.\n\nThis confusing statement existed in the previous (shorter)\nversion also.  My fault; I use [[ path == patt ]] far more\noften than plain globs so I had a thinko.  (Perversely, that\none does *not* use FNM_PATHNAME... go figure!)\n\n>>  - An optional prefix '!' negates the pattern; any matching\n>>    file excluded by a previous pattern will become included\n>>    again.  If a negated pattern matches, this will override\n>>    lower precedence patterns sources.\n>\n> '!' is not part of _how_ the patterns match.  It is _what happens_ when a\n> pattern marked as such matches (meaning, the syntax for a line in\n> gitignore file is \"an optional '!' followed by a pattern\").\n>\n>     An optional prefix '!' is not a part of the pattern and it does not\n>     affect the match.  When a path matches such a pattern, instead of\n>     being ignored, it is unignored.\n\nI can use this.  Can we keep it in the same section, despite\nbeing technically not a '_how_'?  It fits the other sections\neven less, and the sectioning is the main thing in all this.\n\n> It would be good to clarify that '!' is not part of the pattern, as I'd\n> like to take J6t's patch that says gitattributes uses the same pattern as\n> gitignore uses.\n>\n>> This is _what_ the patterns match:\n>>\n>>  - If the pattern ends with a slash, it matches only\n>>    directories (and their contents), otherwise it matches\n>>    regular files and symlinks also.\n>\n> Do we want \"(and their contents)\" here?  Once a directory is ignored like\n> this, none of its contents, including .gitignore file in it, is examined\n> because we do not even descend into it.\n\nDo we not want to specify that we don't descend?  The\noriginal text does say '...will match a directory foo and\npaths underneath it'.\n\n>> This is _where_ the patterns match (a trailing slash is\n>> ignored for these rules):\n>>\n>>  - If there is a slash at the start or within the pattern,\n>>    it matches paths relative to the .gitignore file in which\n>>    the pattern is found, or to the root of the working tree\n>>    if the pattern is from one of the other pattern sources\n>>    (i.e., `.git/info/exclude`, `core.excludesfile`)\n>\n> \"at the start or within but not at the end of the pattern\"?\n\nIsn't that confusing?  'if there is a slash ... not at the\nend of the pattern' can easily sound like \"there *should\nnot* be a trailing slash\", which is quite different from \"we\ndon't care if there *is* a trailing slash; it's the *other*\nslashes that matter here\".\n\nAnd it'll _seem to_ contradict what we say, just above, that\na trailing slash is ignored for these rules.\n\n>\n>>  - Otherwise, it matches a path at any depth in the tree\n"},{"id":"106262","messageId":"7vvdqyyzsr.fsf@gitster.siamese.dyndns.org","threadId":"17983","inReplyTo":"slrngqaa5n.mp1.sitaramc@sitaramc.homelinux.net","subject":"Re: How do I qualify paths in the .gitignore file w.r.t. the repo root directory?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-02-25T21:25:24Z","receivedAt":"2009-02-25T21:25:24Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sitaram Chamarty <sitaramc@gmail.com> writes:\n\n> On 2009-02-25, Junio C Hamano <gitster@pobox.com> wrote:\n> ...\n>> '!' is not part of _how_ the patterns match.  It is _what happens_ when a\n>> pattern marked as such matches (meaning, the syntax for a line in\n>> gitignore file is \"an optional '!' followed by a pattern\").\n>>\n>>     An optional prefix '!' is not a part of the pattern and it does not\n>>     affect the match.  When a path matches such a pattern, instead of\n>>     being ignored, it is unignored.\n>\n> I can use this.  Can we keep it in the same section, despite\n> being technically not a '_how_'?  It fits the other sections\n> even less, and the sectioning is the main thing in all this.\n\nI thought making the text easier to follow was the main thing.\n\nSectioning could be part of the solution, but if we find that the boundary\nbetween sections are blurry, or if there are too many sections compared to\nthe number of rules, perhaps dividing them into sections and giving each a\nseparate section header may make them even harder to follow.\n\nI am actually very tempted to say that the correct description of the\ngitignore language is:\n\n    - an optional ! sign whose meaning is \"unignore paths that matches\n      this pattern, instead of ignoring them\"; followed by\n\n    - an optional / sign whose meaning is \"a match with this pattern must\n      be made at this directory and not in its subdirectories\"; followed\n      by\n\n    - a pattern that never begins nor ends with a slash whose meaning is\n      \"this is a shell glob pattern to test paths against\"; followed by\n\n    - an optional / sign whose meaning is \"this pattern matches only with\n      a directory\".\n\nWe'll need to tweak the language a bit in J6t's patch that talks about the\ngitattributes pattern if we go this route, though.  The attribute system\nuses the latter three that specify how a match is made, but does not use\nthe first one that specifies what happens once a match is found, because\nthe latter is done by the attributes part that follows the pattern in the\ngitattributes file.\n\n> Do we not want to specify that we don't descend?  The\n> original text does say '...will match a directory foo and\n> paths underneath it'.\n\nOk.  If we unignore a directory that does not mean all paths inside it are\nnow unignored --- they are still subject to .gitignore rules read from it\nand its subdirectories.  So \"will match it and paths inside it\" is correct\nbut \"will ignore it and paths inside it\" is not.\n\n>>> This is _where_ the patterns match (a trailing slash is\n>>> ignored for these rules):\n>>> ...\n> And it'll _seem to_ contradict what we say, just above, that\n> a trailing slash is ignored for these rules.\n\nYou are absolutely right.  Please scratch my comment on this item.\n"},{"id":"106278","messageId":"20090226004530.GA11730@atjola.homenet","threadId":"17983","inReplyTo":"7vvdqyyzsr.fsf@gitster.siamese.dyndns.org","subject":"Re: How do I qualify paths in the .gitignore file w.r.t. the repo root directory?","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2009-02-26T00:45:30Z","receivedAt":"2009-02-26T00:45:30Z","isPatch":false,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2009.02.25 13:25:24 -0800, Junio C Hamano wrote:\n> Sitaram Chamarty <sitaramc@gmail.com> writes:\n> > Do we not want to specify that we don't descend?  The\n> > original text does say '...will match a directory foo and\n> > paths underneath it'.\n> \n> Ok.  If we unignore a directory that does not mean all paths inside it are\n> now unignored --- they are still subject to .gitignore rules read from it\n> and its subdirectories.  So \"will match it and paths inside it\" is correct\n> but \"will ignore it and paths inside it\" is not.\n\nI don't think that's good enough. The case in which we ignore\ndirectories is impressively hard to describe correctly. Consider this:\n\n.gitignore     # Contains foo\nfoo/.gitignore # Contains !bar\nfoo/bar\n\nThe current man page says that for \"foo/bar\" foo/.gitignore has the\nhighest precedence, overriding the patterns from .gitignore. So without\nfurther information, one could think that while foo/bar is matched by\nthe \"foo\" pattern, this is invalidated by the \"!bar\" rule and thus\nfoo/bar would not be ignored. But of course we don't bother looking into\nfoo at all, so the foo/.gitignore has no effect.\n\nAnd it gets more interesting:\n\n.gitignore # Contains \"foo\" and \"!foo/bar\"\nfoo/bar\n\nEven in this case, foo/bar is ignored. Because again, we don't look into\nfoo at all, so we never even see foo/bar and thus we won't notice that\nit is to be unignored. So saying \"match it and paths inside it\" is\nmisleading, because we'll never even see any path inside it that could\nmatch, and it might lead to failing gitignore setups like the above.\n\nSo maybe instead of \"... and paths inside it\", we could have something\nlike this:\n\n    If a directory is ignored, git won't look into it at all when\n    searching for untracked files. This means that all paths inside it\n    are implicitly ignored and that you cannot unignore these paths.\n\nBjörn\n"},{"id":"106280","messageId":"slrngqbrpd.t1k.sitaramc@sitaramc.homelinux.net","threadId":"17983","inReplyTo":"7vvdqyyzsr.fsf@gitster.siamese.dyndns.org","subject":"Re: How do I qualify paths in the .gitignore file w.r.t. the repo root directory?","fromName":"Sitaram Chamarty","fromEmail":"sitaramc@gmail.com","sentAt":"2009-02-26T01:23:58Z","receivedAt":"2009-02-26T01:23:58Z","isPatch":false,"sender":{"key":"sitaramc@gmail.com","avatar":"https://avatars.githubusercontent.com/u/43316?v=4"},"body":"On 2009-02-25, Junio C Hamano <gitster@pobox.com> wrote:\n> Sitaram Chamarty <sitaramc@gmail.com> writes:\n\n>> I can use this.  Can we keep it in the same section, despite\n>> being technically not a '_how_'?  It fits the other sections\n>> even less, and the sectioning is the main thing in all this.\n>\n> I thought making the text easier to follow was the main thing.\n\nI meant the sectioning was the main change to make the text\neasier to follow, since the words are mostly the same\notherwise.\n\n> Sectioning could be part of the solution, but if we find that the boundary\n> between sections are blurry, or if there are too many sections compared to\n> the number of rules, perhaps dividing them into sections and giving each a\n> separate section header may make them even harder to follow.\n\nI'm ambivalent on this, so I appreciate the tie-breaker.\n\n> I am actually very tempted to say that the correct description of the\n> gitignore language is:\n\nI see you've used 'pattern' and 'sign' to break the\noverloading of '/'.\n\n>     - an optional ! sign whose meaning is \"unignore paths that matches\n>       this pattern, instead of ignoring them\"; followed by\n>\n>     - an optional / sign whose meaning is \"a match with this pattern must\n>       be made at this directory and not in its subdirectories\"; followed\n>       by\n>\n>     - a pattern that never begins nor ends with a slash whose meaning is\n>       \"this is a shell glob pattern to test paths against\"; followed by\n\nI wish[1].  But in reality, a slash 'inside' anchors the\nmatch the same as a leading slash does.\n\nBoy this is tough :-) and I'm almost tempted to relook at my\nfirst attempt, where your only concerns were the words\n'otherwise' and 'anywhere else' for non-native speakers.\n\nI'll think about this some more and get back to you.\n\nRegards,\n\nSitaram\n\n[1] Would have been much simpler, plus you'd be able to\nspecify a non-anchored pattern that contains a slash, which\nyou currently cannot.\n"},{"id":"106283","messageId":"slrngqc47n.t1k.sitaramc@sitaramc.homelinux.net","threadId":"17983","inReplyTo":"slrngqbrpd.t1k.sitaramc@sitaramc.homelinux.net","subject":"Re: How do I qualify paths in the .gitignore file w.r.t. the repo root directory?","fromName":"Sitaram Chamarty","fromEmail":"sitaramc@gmail.com","sentAt":"2009-02-26T03:48:07Z","receivedAt":"2009-02-26T03:48:07Z","isPatch":false,"sender":{"key":"sitaramc@gmail.com","avatar":"https://avatars.githubusercontent.com/u/43316?v=4"},"body":"On 2009-02-26, Sitaram Chamarty <sitaramc@gmail.com> wrote:\n\n> On 2009-02-25, Junio C Hamano <gitster@pobox.com> wrote:\n\n> I see you've used 'pattern' and 'sign' to break the\n> overloading of '/'.\n>\n>>     - an optional ! sign whose meaning is \"unignore paths that matches\n>>       this pattern, instead of ignoring them\"; followed by\n>>\n>>     - an optional / sign whose meaning is \"a match with this pattern must\n>>       be made at this directory and not in its subdirectories\"; followed\n>>       by\n>>\n>>     - a pattern that never begins nor ends with a slash whose meaning is\n>>       \"this is a shell glob pattern to test paths against\"; followed by\n>\n> I wish[1].  But in reality, a slash 'inside' anchors the\n> match the same as a leading slash does.\n>\n> Boy this is tough :-) and I'm almost tempted to relook at my\n> first attempt, where your only concerns were the words\n> 'otherwise' and 'anywhere else' for non-native speakers.\n>\n> I'll think about this some more and get back to you.\n\nHow about this:\n\n----8<----\n\n    - an optional leading ! symbol meaning \"unignore paths\n      that match this pattern, instead of ignoring them\"\n\n    - an optional trailing / symbol meaning \"this pattern\n      matches only with a directory (i.e., files and\n      symlinks won't match)\"\n\n    - the above two symbols (if present) are then removed.\n      What remains is treated as a normal shell glob\n      pattern, with the additional restriction that if the\n      pattern still contains a slash, it matches only at the\n      current directory and not in its subdirectories\n\n----8<----\n\nI'm not going into the 'descend' thing; based on how the\nemail from BjÃ¶rn Steinbrink plays out, we can describe that\nlater.  Same for 'current directory', which stands for the\nroot of the work-tree if the pattern came from\n.git/info/exclude or a core.excludesfile; this also can be\nadded as a footnote.\n"},{"id":"106343","messageId":"7v1vtluo2e.fsf@gitster.siamese.dyndns.org","threadId":"17983","inReplyTo":"slrngqc47n.t1k.sitaramc@sitaramc.homelinux.net","subject":"Re: How do I qualify paths in the .gitignore file w.r.t. the repo root directory?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-02-26T17:04:41Z","receivedAt":"2009-02-26T17:04:41Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sitaram Chamarty <sitaramc@gmail.com> writes:\n\n> How about this:\n>\n> ----8<----\n>\n>     - an optional leading ! symbol meaning \"unignore paths\n>       that match this pattern, instead of ignoring them\"\n>\n>     - an optional trailing / symbol meaning \"this pattern\n>       matches only with a directory (i.e., files and\n>       symlinks won't match)\"\n>\n>     - the above two symbols (if present) are then removed.\n>       What remains is treated as a normal shell glob\n>       pattern, with the additional restriction that if the\n>       pattern still contains a slash, it matches only at the\n>       current directory and not in its subdirectories\n\nSure, but then you are not stripping the leading / from the pattern but\nyou do not use it for the purpose of matching, right?\n\nI think your original before I wondered about the ambiguity is the best\nrewrite so far.\n"}]}