{"thread":{"id":"13599","subject":"gitignore: negating path patterns","startedAt":"2008-05-21T14:52:36Z","lastAt":"2008-05-26T08:54:19Z","messageCount":5,"participants":["Michael J Gruber","Kevin Ballard"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"77390","messageId":"g11cvn$ndr$1@ger.gmane.org","threadId":"13599","inReplyTo":null,"subject":"gitignore: negating path patterns","fromName":"Michael J Gruber","fromEmail":"michaeljgruber+gmane@fastmail.fm","sentAt":"2008-05-21T14:52:36Z","receivedAt":"2008-05-21T14:52:36Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Hi there\n\nIt seems that negating path patterns in gitignore doesn't work, or I\ndon't understand it (or both). With the attached script, git status\n(1.5.5.1) reports \"dir/a\" as new and \"dir/b\" as untracked. I would\nrather expect it to report \"dir/c\" as untracked also.\n\nIt seems that \"!b\" matches to include \"dir/b\" (reverting the exclusion\n\"*\" as expected), whereas \"!dir/\" does not match to include \"dir/c\".\n\nWhat's going on here?\n\nMichael\n\nP.S.: \"*\" in dir/.gitignore would do what I want, but I want all\npatterns in one place.\n\nP.P.S.: My first attempt at sending this was blocked (by an MS CDO for \nExchange 2000?! Is this gmane playing pranks on me?). So I'll resend \nwith the script inline rather than attached.\n\n---etest.sh---\n\n\n#!/bin/sh\nrm -Rf test\nmkdir test\ncd test\ngit init\nmkdir dir\necho test > a\necho test > dir/a\necho test > dir/b\necho test > dir/c\ngit add dir/a\ncat > .git/info/exclude <<EOF\n*\n!dir/\n!b\nEOF\ngit status\n"},{"id":"77515","messageId":"5BBB5607-DF95-4C06-BE6C-C3D7AF475FBF@sb.org","threadId":"13599","inReplyTo":"g11cvn$ndr$1@ger.gmane.org","subject":"Re: gitignore: negating path patterns","fromName":"Kevin Ballard","fromEmail":"kevin@sb.org","sentAt":"2008-05-23T00:23:54Z","receivedAt":"2008-05-23T00:23:54Z","isPatch":false,"sender":{"key":"kevin@sb.org","avatar":"https://avatars.githubusercontent.com/u/714?v=4"},"body":"On May 21, 2008, at 7:52 AM, Michael J Gruber wrote:\n\n> Hi there\n>\n> It seems that negating path patterns in gitignore doesn't work, or I\n> don't understand it (or both). With the attached script, git status\n> (1.5.5.1) reports \"dir/a\" as new and \"dir/b\" as untracked. I would\n> rather expect it to report \"dir/c\" as untracked also.\n>\n> It seems that \"!b\" matches to include \"dir/b\" (reverting the exclusion\n> \"*\" as expected), whereas \"!dir/\" does not match to include \"dir/c\".\n>\n> What's going on here?\n\n\"dir/\" will not match anything, because paths are compared without  \ntrailing slashes. Try \"!dir\".\n\n-- \nKevin Ballard\nhttp://kevin.sb.org\nkevin@sb.org\nhttp://www.tildesoft.com\n"},{"id":"77531","messageId":"g15t3j$eoa$1@ger.gmane.org","threadId":"13599","inReplyTo":"5BBB5607-DF95-4C06-BE6C-C3D7AF475FBF@sb.org","subject":"Re: gitignore: negating path patterns","fromName":"Michael J Gruber","fromEmail":"michaeljgruber+gmane@fastmail.fm","sentAt":"2008-05-23T07:52:19Z","receivedAt":"2008-05-23T07:52:19Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Kevin Ballard venit, vidit, dixit 23.05.2008 02:23:\n> On May 21, 2008, at 7:52 AM, Michael J Gruber wrote:\n> \n>> Hi there\n>>\n>> It seems that negating path patterns in gitignore doesn't work, or I\n>> don't understand it (or both). With the attached script, git status\n>> (1.5.5.1) reports \"dir/a\" as new and \"dir/b\" as untracked. I would\n>> rather expect it to report \"dir/c\" as untracked also.\n>>\n>> It seems that \"!b\" matches to include \"dir/b\" (reverting the exclusion\n>> \"*\" as expected), whereas \"!dir/\" does not match to include \"dir/c\".\n>>\n>> What's going on here?\n> \n> \"dir/\" will not match anything, because paths are compared without  \n> trailing slashes. Try \"!dir\".\n> \n\nI am sorry, but this is plain wrong, at least if \"man gitignore\" is \nright (see below). \"!dir\" would match files whose name (pathname without \nleading directory name) matches \"dir\" (i.e.: is dir) and exclude those \nfrom exclusion (include them).\n\nAlso, replacing \"!dir/\" by \"!dir\" in my test script does not change the \nresult. In fact, for \"!dir\" the result is as expected and documented, \njust for \"!dir/\" I would expect something else.\n\nSo, thanks for trying to help, although reading the manual or testing \nyour advice before would be appreciated even more. ;)\n\nMichael\n\n From man gitignore:\n\nIf the pattern ends with a slash, it is removed for the purpose of the \nfollowing description, but it would only find a match with a directory. \nIn other words, foo/ will match a directory foo and paths underneath it, \nbut will not match a regular file or a symbolic link foo (this is \nconsistent with the way how pathspec works in general in git).\n"},{"id":"77608","messageId":"ADCBC87D-27A7-4C3F-B11E-8AE217F8AF91@sb.org","threadId":"13599","inReplyTo":"g15t3j$eoa$1@ger.gmane.org","subject":"Re: gitignore: negating path patterns","fromName":"Kevin Ballard","fromEmail":"kevin@sb.org","sentAt":"2008-05-23T22:44:02Z","receivedAt":"2008-05-23T22:44:02Z","isPatch":false,"sender":{"key":"kevin@sb.org","avatar":"https://avatars.githubusercontent.com/u/714?v=4"},"body":"On May 23, 2008, at 12:52 AM, Michael J Gruber wrote:\n\n> Kevin Ballard venit, vidit, dixit 23.05.2008 02:23:\n>> On May 21, 2008, at 7:52 AM, Michael J Gruber wrote:\n>>> Hi there\n>>>\n>>> It seems that negating path patterns in gitignore doesn't work, or I\n>>> don't understand it (or both). With the attached script, git status\n>>> (1.5.5.1) reports \"dir/a\" as new and \"dir/b\" as untracked. I would\n>>> rather expect it to report \"dir/c\" as untracked also.\n>>>\n>>> It seems that \"!b\" matches to include \"dir/b\" (reverting the  \n>>> exclusion\n>>> \"*\" as expected), whereas \"!dir/\" does not match to include \"dir/c\".\n>>>\n>>> What's going on here?\n>> \"dir/\" will not match anything, because paths are compared without   \n>> trailing slashes. Try \"!dir\".\n>\n> I am sorry, but this is plain wrong, at least if \"man gitignore\" is  \n> right (see below). \"!dir\" would match files whose name (pathname  \n> without leading directory name) matches \"dir\" (i.e.: is dir) and  \n> exclude those from exclusion (include them).\n>\n> Also, replacing \"!dir/\" by \"!dir\" in my test script does not change  \n> the result. In fact, for \"!dir\" the result is as expected and  \n> documented, just for \"!dir/\" I would expect something else.\n>\n> So, thanks for trying to help, although reading the manual or  \n> testing your advice before would be appreciated even more. ;)\n>\n> Michael\n>\n> From man gitignore:\n>\n> If the pattern ends with a slash, it is removed for the purpose of  \n> the following description, but it would only find a match with a  \n> directory. In other words, foo/ will match a directory foo and paths  \n> underneath it, but will not match a regular file or a symbolic link  \n> foo (this is consistent with the way how pathspec works in general  \n> in git).\n\nAhh, the behavior changed in 1.5.5. Pre-1.5.5, if a path ended in a  \nslash, it would never match anything.\n\nIn any case, the problem is the * pattern. Here's what happens:\n\nAt /, the * is evaluated and ignores everything. The !dir/ is  \nevaluated and unignores dir. The !b is evaluated and matches nothing.\nAT /dir, the * is evaluated and ignores everything. The !dir/ is  \nevaluated and matches nothing. The !b is evaluated and unignores b.\n\nSo the problem is the * is recursively applying to the subdirectories.  \nTo fix this, use /* as the pattern.\n\n-Kevin Ballard\n\n-- \nKevin Ballard\nhttp://kevin.sb.org\nkevin@sb.org\nhttp://www.tildesoft.com\n"},{"id":"77750","messageId":"g1dts5$bmh$1@ger.gmane.org","threadId":"13599","inReplyTo":"ADCBC87D-27A7-4C3F-B11E-8AE217F8AF91@sb.org","subject":"Re: gitignore: negating path patterns","fromName":"Michael J Gruber","fromEmail":"michaeljgruber+gmane@fastmail.fm","sentAt":"2008-05-26T08:54:19Z","receivedAt":"2008-05-26T08:54:19Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Kevin Ballard venit, vidit, dixit 24.05.2008 00:44:\n> On May 23, 2008, at 12:52 AM, Michael J Gruber wrote:\n> \n>> Kevin Ballard venit, vidit, dixit 23.05.2008 02:23:\n>>> On May 21, 2008, at 7:52 AM, Michael J Gruber wrote:\n>>>> Hi there\n>>>>\n>>>> It seems that negating path patterns in gitignore doesn't work, or I\n>>>> don't understand it (or both). With the attached script, git status\n>>>> (1.5.5.1) reports \"dir/a\" as new and \"dir/b\" as untracked. I would\n>>>> rather expect it to report \"dir/c\" as untracked also.\n>>>>\n>>>> It seems that \"!b\" matches to include \"dir/b\" (reverting the  \n>>>> exclusion\n>>>> \"*\" as expected), whereas \"!dir/\" does not match to include \"dir/c\".\n>>>>\n>>>> What's going on here?\n>>> \"dir/\" will not match anything, because paths are compared without   \n>>> trailing slashes. Try \"!dir\".\n>> I am sorry, but this is plain wrong, at least if \"man gitignore\" is  \n>> right (see below). \"!dir\" would match files whose name (pathname  \n>> without leading directory name) matches \"dir\" (i.e.: is dir) and  \n>> exclude those from exclusion (include them).\n>>\n>> Also, replacing \"!dir/\" by \"!dir\" in my test script does not change  \n>> the result. In fact, for \"!dir\" the result is as expected and  \n>> documented, just for \"!dir/\" I would expect something else.\n>>\n>> So, thanks for trying to help, although reading the manual or  \n>> testing your advice before would be appreciated even more. ;)\n>>\n>> Michael\n>>\n>> From man gitignore:\n>>\n>> If the pattern ends with a slash, it is removed for the purpose of  \n>> the following description, but it would only find a match with a  \n>> directory. In other words, foo/ will match a directory foo and paths  \n>> underneath it, but will not match a regular file or a symbolic link  \n>> foo (this is consistent with the way how pathspec works in general  \n>> in git).\n> \n> Ahh, the behavior changed in 1.5.5. Pre-1.5.5, if a path ended in a  \n> slash, it would never match anything.\n> \n> In any case, the problem is the * pattern. Here's what happens:\n> \n> At /, the * is evaluated and ignores everything. The !dir/ is  \n> evaluated and unignores dir. The !b is evaluated and matches nothing.\n> AT /dir, the * is evaluated and ignores everything. The !dir/ is  \n> evaluated and matches nothing. The !b is evaluated and unignores b.\n> \n> So the problem is the * is recursively applying to the subdirectories.  \n> To fix this, use /* as the pattern.\n\nYou're right, that's how it works now. Thanks a bunch! Nothings beats \n\"using the s/force/source/\".\n\nI find this behaviour highly confusing for someone going by \n\"gitgnore(5)\". I'll try and submit a documentation fix as a first \nattempt at contributing back.\n\nMichael\n"}]}