{"thread":{"id":"41130","subject":"Git 2.7.0 gitignore behaviour regression","startedAt":"2016-01-05T14:40:16Z","lastAt":"2016-01-08T09:02:31Z","messageCount":13,"participants":["Mike McQuaid","Jeff King","Duy Nguyen","Junio C Hamano","brian m. carlson","Carlos Martín Nieto"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"275377","messageId":"4B0F686D-3DF9-4E5D-971D-DB106C6573FD@mikemcquaid.com","threadId":"41130","inReplyTo":null,"subject":"Git 2.7.0 gitignore behaviour regression","fromName":"Mike McQuaid","fromEmail":"mike@mikemcquaid.com","sentAt":"2016-01-05T14:40:16Z","receivedAt":"2016-01-05T14:40:16Z","isPatch":false,"sender":{"key":"mike@mikemcquaid.com","avatar":null},"body":"Hi folks,\n\nFirstly, thanks for all your hard work on Git. It makes my life much easier.\n\nHomebrew has a series of convoluted .gitignore rules due to our special/weird use-case of wanting to ignore everything in a working directory except a select few files/directories. We experienced a bug with our .gitignore file for users using Git 2.7.0. This may well be a valid WONTFIX or intentional behaviour change but I wanted to flag it in case it wasn’t.\n\nHere’s a minimal test case:\n\n- Create an empty git repository in a directory with `git init`\n- Create a directory named ‘a' containing a file named ‘b' with `mkdir a && touch a/b`\n- Create a ‘gitignore’ file with the following contents:\n```\n*/\n/a\n!/a/*\n```\n- Run `git status --short`.\n\nThe output with Git 2.6.4 is:\n```\n?? .gitignore\n```\n\nThe output with Git 2.7.0 is:\n```\n?? .gitignore\n?? a/\n```\n\nAnother minimal test case:\n\n- Create an empty git repository in a directory with `git init`\n- Create a directory named ‘a' containing a file named ‘b' with `mkdir a && touch a/b`\n- Create a ‘gitignore’ file with the following contents:\n```\n*/\n/a\n!/a/\n```\n- Run `git status —short`.\n\nThe output with Git 2.6.4 is:\n```\n?? .gitignore\n?? a/\n```\n\nThe output with Git 2.7.0 is:\n```\n?? .gitignore\n```\n\nLet me know if you need any more information, thanks!\n\nMike McQuaid\nhttp://mikemcquaid.com"},{"id":"275378","messageId":"20160105150602.GA4130@sigill.intra.peff.net","threadId":"41130","inReplyTo":"4B0F686D-3DF9-4E5D-971D-DB106C6573FD@mikemcquaid.com","subject":"Re: Git 2.7.0 gitignore behaviour regression","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-01-05T15:06:02Z","receivedAt":"2016-01-05T15:06:02Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Jan 05, 2016 at 02:40:16PM +0000, Mike McQuaid wrote:\n\n> Homebrew has a series of convoluted .gitignore rules due to our\n> special/weird use-case of wanting to ignore everything in a working\n> directory except a select few files/directories. We experienced a bug\n> with our .gitignore file for users using Git 2.7.0. This may well be a\n> valid WONTFIX or intentional behaviour change but I wanted to flag it\n> in case it wasn’t.\n> \n> Here’s a minimal test case:\n> \n> - Create an empty git repository in a directory with `git init`\n> - Create a directory named ‘a' containing a file named ‘b' with `mkdir a && touch a/b`\n> - Create a ‘gitignore’ file with the following contents:\n> ```\n> */\n> /a\n> !/a/*\n> ```\n> - Run `git status --short`.\n> \n> The output with Git 2.6.4 is:\n> ```\n> ?? .gitignore\n> ```\n> \n> The output with Git 2.7.0 is:\n> ```\n> ?? .gitignore\n> ?? a/\n> ```\n\nThanks for giving a clear example. This bisects to Duy's 57534ee (dir.c:\ndon't exclude whole dir prematurely if neg pattern may match,\n2015-09-21). AFAICT (and I don't recall looking over this patch\npreviously), what you are seeing is the intended effect of the patch.\n\nYour final line unignores stuff inside of \"a\", so we're reporting it (if you gave\n\"-uall\", you'd see the actual file \"a/b\"). Older versions of git\ngenerally optimized out looking inside \"a/\" at all. This created a\nhassle when people wanted to do things like:\n\n    a/\n    !a/precious-file\n\nin their .gitignore.\n\nI'm sympathetic that in making that use-case work, we might have\nregressed another one, but it's hard to tell from the small example. Can\nyou elaborate on your use case? Why are you both ignoring and unignoring\neverything in the directory?\n\n-Peff\n"},{"id":"275424","messageId":"CACsJy8AQ9s4VkFn+TNJLD55xJc40+-54BTYbC4Os71uSkL1QSA@mail.gmail.com","threadId":"41130","inReplyTo":"20160105150602.GA4130@sigill.intra.peff.net","subject":"Re: Git 2.7.0 gitignore behaviour regression","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2016-01-06T09:42:32Z","receivedAt":"2016-01-06T09:42:32Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Tue, Jan 5, 2016 at 10:06 PM, Jeff King <peff@peff.net> wrote:\n> On Tue, Jan 05, 2016 at 02:40:16PM +0000, Mike McQuaid wrote:\n>\n>> Homebrew has a series of convoluted .gitignore rules due to our\n>> special/weird use-case of wanting to ignore everything in a working\n>> directory except a select few files/directories. We experienced a bug\n>> with our .gitignore file for users using Git 2.7.0. This may well be a\n>> valid WONTFIX or intentional behaviour change but I wanted to flag it\n>> in case it wasn’t.\n>>\n>> Here’s a minimal test case:\n>>\n>> - Create an empty git repository in a directory with `git init`\n>> - Create a directory named ‘a' containing a file named ‘b' with `mkdir a && touch a/b`\n>> - Create a ‘gitignore’ file with the following contents:\n>> ```\n>> */\n>> /a\n>> !/a/*\n>> ```\n>> - Run `git status --short`.\n>>\n>> The output with Git 2.6.4 is:\n>> ```\n>> ?? .gitignore\n>> ```\n>>\n>> The output with Git 2.7.0 is:\n>> ```\n>> ?? .gitignore\n>> ?? a/\n>> ```\n>\n> Thanks for giving a clear example. This bisects to Duy's 57534ee (dir.c:\n> don't exclude whole dir prematurely if neg pattern may match,\n> 2015-09-21). AFAICT (and I don't recall looking over this patch\n> previously), what you are seeing is the intended effect of the patch.\n\nYeah.. I think it's the only relevant commit in 2.7.0 cycle anyway.\nThese patterns \"/a\" followed by \"!/a/*\" were wrecking my head. But I\nfinally decided 2.7 output makes more sense. You asked to un-ignore\neverything inside 'a' so we can't treat 'a' as (entirely) ignored and\nhide it away.\n\n> I'm sympathetic that in making that use-case work, we might have\n> regressed another one, but it's hard to tell from the small example. Can\n> you elaborate on your use case? Why are you both ignoring and unignoring\n> everything in the directory?\n\nAlso how bad this affects you (widely-used 'wrong' behavior can become\n'right', and my change a regression as a result)\n-- \nDuy\n"},{"id":"275426","messageId":"5E517AD0-CD4E-4F85-8FEB-89B7A0183967@mikemcquaid.com","threadId":"41130","inReplyTo":"CACsJy8AQ9s4VkFn+TNJLD55xJc40+-54BTYbC4Os71uSkL1QSA@mail.gmail.com","subject":"Re: Git 2.7.0 gitignore behaviour regression","fromName":"Mike McQuaid","fromEmail":"mike@mikemcquaid.com","sentAt":"2016-01-06T09:50:39Z","receivedAt":"2016-01-06T09:50:39Z","isPatch":false,"sender":{"key":"mike@mikemcquaid.com","avatar":null},"body":"\n> On 6 Jan 2016, at 09:42, Duy Nguyen <pclouds@gmail.com> wrote:\n> \n> Yeah.. I think it's the only relevant commit in 2.7.0 cycle anyway.\n> These patterns \"/a\" followed by \"!/a/*\" were wrecking my head. But I\n> finally decided 2.7 output makes more sense. You asked to un-ignore\n> everything inside 'a' so we can't treat 'a' as (entirely) ignored and\n> hide it away.\n> \n>> I'm sympathetic that in making that use-case work, we might have\n>> regressed another one, but it's hard to tell from the small example. Can\n>> you elaborate on your use case? Why are you both ignoring and unignoring\n>> everything in the directory?\n> \n> Also how bad this affects you (widely-used 'wrong' behavior can become\n> 'right', and my change a regression as a result)\n\nThis doesn’t affect me badly; I was able to work around the original issue before the bug report in a way that was consistent between Git 2.6 and Git 2.7 but wanted to ensure that I filed something upstream just so it was a known issue as it was relatively easy to reproduce.\n\nI agree that all the pattern handling stuff like in my example is pretty awful; it’s also a big area where libgit2 was inconsistent with Git’s behaviour on either of those versions too. I’ve played around and now got a .gitignore file that behaves consistently across Git 2.6, Git 2.7 and libgit2 0.23.4 (https://github.com/Homebrew/homebrew/blob/master/.gitignore) so there’s no outstanding issue on my side.\n\nThanks!\n\nMike McQuaid\nhttp://mikemcquaid.com\n"},{"id":"275427","messageId":"CACsJy8CvPqYGRXB845+4fHjkXH_kSAWG684CoxtWAnXE-gM6ag@mail.gmail.com","threadId":"41130","inReplyTo":"5E517AD0-CD4E-4F85-8FEB-89B7A0183967@mikemcquaid.com","subject":"Re: Git 2.7.0 gitignore behaviour regression","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2016-01-06T10:03:10Z","receivedAt":"2016-01-06T10:03:10Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Wed, Jan 6, 2016 at 4:50 PM, Mike McQuaid <mike@mikemcquaid.com> wrote:\n> it’s also a big area where libgit2 was inconsistent with Git’s behaviour on either of those versions too.\n\nYeah.. it looks like libgit2's gitignore support was written new, not\nimported from C Git, so behavior differences (especially in corner\ncases) and even lack of some feature (\"**\" support comes to mind). For\nisolated features like gitignore, perhaps we can have an option to\nreplace C Git code with libgit2 and therefore can test libgit2 against\nC Git test suite. It could be a good start for libgit2 to invade C\nGit. Not sure if anybody's interested in doing it though.\n-- \nDuy\n"},{"id":"275447","messageId":"CAPc5daX+uGQfKEteT2dqax-m9dR76Gkg1YeiFjVU9dsTqnHDmw@mail.gmail.com","threadId":"41130","inReplyTo":"CACsJy8CvPqYGRXB845+4fHjkXH_kSAWG684CoxtWAnXE-gM6ag@mail.gmail.com","subject":"Re: Git 2.7.0 gitignore behaviour regression","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-01-06T18:58:37Z","receivedAt":"2016-01-06T18:58:37Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"On Wed, Jan 6, 2016 at 2:03 AM, Duy Nguyen <pclouds@gmail.com> wrote:\n>\n> On Wed, Jan 6, 2016 at 4:50 PM, Mike McQuaid <mike@mikemcquaid.com> wrote:\n> > it’s also a big area where libgit2 was inconsistent with Git’s behaviour on either of those versions too.\n>\n> Yeah.. it looks like libgit2's gitignore support was written new, not\n> imported from C Git, so behavior differences (especially in corner\n> cases) and even lack of some feature (\"**\" support comes to mind). For\n> isolated features like gitignore, perhaps we can have an option to\n> replace C Git code with libgit2 and therefore can test libgit2 against\n> C Git test suite. It could be a good start for libgit2 to invade C\n> Git. Not sure if anybody's interested in doing it though.\n\nYup, an area that is reasonably isolated from the remainder of the system like\nthis might be a good starting point. But I suspect that the invasion needs to\nhappen in the opposite direction in this particular case before it happens.\nThat is, if libgit2's implementation does not behave like how we do, it needs to\nbe fixed, possibly by discarding what they did and instead importing code from\nus. After the behaviour of libgit2 is fixed, we can talk about the\ninvasion in the\nopposite direction.\n\nThanks.\n"},{"id":"275460","messageId":"20160107020406.GA9358@sigill.intra.peff.net","threadId":"41130","inReplyTo":"CAPc5daX+uGQfKEteT2dqax-m9dR76Gkg1YeiFjVU9dsTqnHDmw@mail.gmail.com","subject":"Re: Git 2.7.0 gitignore behaviour regression","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2016-01-07T02:04:06Z","receivedAt":"2016-01-07T02:04:06Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"[+cc Carlos and Shawn for libgit2/JGit talk]\n\nOn Wed, Jan 06, 2016 at 10:58:37AM -0800, Junio C Hamano wrote:\n\n> On Wed, Jan 6, 2016 at 2:03 AM, Duy Nguyen <pclouds@gmail.com> wrote:\n> >\n> > Yeah.. it looks like libgit2's gitignore support was written new, not\n> > imported from C Git, so behavior differences (especially in corner\n> > cases) and even lack of some feature (\"**\" support comes to mind). For\n> > isolated features like gitignore, perhaps we can have an option to\n> > replace C Git code with libgit2 and therefore can test libgit2 against\n> > C Git test suite. It could be a good start for libgit2 to invade C\n> > Git. Not sure if anybody's interested in doing it though.\n\nYeah, libgit2 is in the difficult position of trying to hit a moving\ntarget. There's a good chance that it _was_ the same as git's behavior\nwhen it was written. :)\n\nJGit is in the same boat, and I wouldn't be surprised if they don't\nhandle \"**\" either (I didn't check). Note that git inherited that\nfeature (and probably some others) by importing a GPLv2 version of\nwildmatch. That certainly isn't an option for JGit (because it's not\npure Java), and probably not for libgit2 (which would need the wildmatch\nauthors to grant the linking exception).\n\n> Yup, an area that is reasonably isolated from the remainder of the system like\n> this might be a good starting point. But I suspect that the invasion needs to\n> happen in the opposite direction in this particular case before it happens.\n> That is, if libgit2's implementation does not behave like how we do, it needs to\n> be fixed, possibly by discarding what they did and instead importing code from\n> us. After the behaviour of libgit2 is fixed, we can talk about the\n> invasion in the\n> opposite direction.\n\nUnfortunately, \"importing code from us\" is not so easy. :(\n\nThey'll either need to contact the wildmatch authors, or rewrite\nwildmatch from scratch.\n\n-Peff\n"},{"id":"275461","messageId":"CACsJy8BGskjxKKw0RGOxSzJYoA2=w_iW_cdrmKyPhpfp+AMmDw@mail.gmail.com","threadId":"41130","inReplyTo":"20160107020406.GA9358@sigill.intra.peff.net","subject":"Re: Git 2.7.0 gitignore behaviour regression","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2016-01-07T02:13:09Z","receivedAt":"2016-01-07T02:13:09Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, Jan 7, 2016 at 9:04 AM, Jeff King <peff@peff.net> wrote:\n>> Yup, an area that is reasonably isolated from the remainder of the system like\n>> this might be a good starting point. But I suspect that the invasion needs to\n>> happen in the opposite direction in this particular case before it happens.\n>> That is, if libgit2's implementation does not behave like how we do, it needs to\n>> be fixed, possibly by discarding what they did and instead importing code from\n>> us. After the behaviour of libgit2 is fixed, we can talk about the\n>> invasion in the\n>> opposite direction.\n>\n> Unfortunately, \"importing code from us\" is not so easy. :(\n>\n> They'll either need to contact the wildmatch authors, or rewrite\n> wildmatch from scratch.\n\nwildmatch author relicensed it on request before [1] so he might do it\nagain (hard to say). I'm not sure if there are other authors though.\nBut even with wildmatch good to go, there still a lot of work to do.\n\n[1] http://thread.gmane.org/gmane.comp.version-control.git/264312/focus=264328\n-- \nDuy\n"},{"id":"275515","messageId":"20160107234455.GB265296@vauxhall.crustytoothpaste.net","threadId":"41130","inReplyTo":"20160105150602.GA4130@sigill.intra.peff.net","subject":"Re: Git 2.7.0 gitignore behaviour regression","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2016-01-07T23:44:55Z","receivedAt":"2016-01-07T23:44:55Z","isPatch":false,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On Tue, Jan 05, 2016 at 10:06:02AM -0500, Jeff King wrote:\n> Thanks for giving a clear example. This bisects to Duy's 57534ee (dir.c:\n> don't exclude whole dir prematurely if neg pattern may match,\n> 2015-09-21). AFAICT (and I don't recall looking over this patch\n> previously), what you are seeing is the intended effect of the patch.\n> \n> Your final line unignores stuff inside of \"a\", so we're reporting it (if you gave\n> \"-uall\", you'd see the actual file \"a/b\"). Older versions of git\n> generally optimized out looking inside \"a/\" at all. This created a\n> hassle when people wanted to do things like:\n> \n>     a/\n>     !a/precious-file\n> \n> in their .gitignore.\n\nI think there's still a bug in the code here.  If you do\n\n  git init\n  mkdir -p base/a/\n  printf 'base/a/\\n!base/a/b.txt\\n' >.gitignore\n  git add .gitignore\n  git commit -m 'Add .gitignore'\n  >base/a/b.txt\n  git add base/a/b.txt\n  git commit -m 'Add base/a/b.txt'\n  >base/a/c.txt\n  git status --porcelain\n\ngit status outputs base/a/c.txt as unknown, when it should be ignored.\nWe saw this in a repository at $DAYJOB.\n-- \nbrian m. carlson / brian with sandals: Houston, Texas, US\n+1 832 623 2791 | https://www.crustytoothpaste.net/~bmc | My opinion only\nOpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187\n"},{"id":"275517","messageId":"CACsJy8C1R+JVmOXQ87eBP1COFNk3Vfqtb6AKzzT65catUhPczg@mail.gmail.com","threadId":"41130","inReplyTo":"20160107234455.GB265296@vauxhall.crustytoothpaste.net","subject":"Re: Git 2.7.0 gitignore behaviour regression","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2016-01-08T00:38:58Z","receivedAt":"2016-01-08T00:38:58Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Jan 8, 2016 at 6:44 AM, brian m. carlson\n<sandals@crustytoothpaste.net> wrote:\n> On Tue, Jan 05, 2016 at 10:06:02AM -0500, Jeff King wrote:\n>> Thanks for giving a clear example. This bisects to Duy's 57534ee (dir.c:\n>> don't exclude whole dir prematurely if neg pattern may match,\n>> 2015-09-21). AFAICT (and I don't recall looking over this patch\n>> previously), what you are seeing is the intended effect of the patch.\n>>\n>> Your final line unignores stuff inside of \"a\", so we're reporting it (if you gave\n>> \"-uall\", you'd see the actual file \"a/b\"). Older versions of git\n>> generally optimized out looking inside \"a/\" at all. This created a\n>> hassle when people wanted to do things like:\n>>\n>>     a/\n>>     !a/precious-file\n>>\n>> in their .gitignore.\n>\n> I think there's still a bug in the code here.  If you do\n>\n>   git init\n>   mkdir -p base/a/\n>   printf 'base/a/\\n!base/a/b.txt\\n' >.gitignore\n\nHere we have the ignore rule \"base/a/\", but gitignore.txt, section\nNOTES mentions this\n\n - The rules to exclude the parent directory must not end with a\n   trailing slash.\n\n>   git add .gitignore\n>   git commit -m 'Add .gitignore'\n>   >base/a/b.txt\n>   git add base/a/b.txt\n>   git commit -m 'Add base/a/b.txt'\n>   >base/a/c.txt\n>   git status --porcelain\n>\n> git status outputs base/a/c.txt as unknown, when it should be ignored.\n> We saw this in a repository at $DAYJOB.\n\nIf I delete that trailing slash, c.txt is ignored. So it's known\nlimitation. I think we can make trailing slash case work too, but if I\nremember correctly it would involve a lot more changes, so I didn't do\nit (there are other conditions to follow anyway to make it work).\n-- \nDuy\n"},{"id":"275518","messageId":"C4B28537-628F-4EF6-8284-BE071CA834BE@dwim.me","threadId":"41130","inReplyTo":"20160107020406.GA9358@sigill.intra.peff.net","subject":"Re: Git 2.7.0 gitignore behaviour regression","fromName":"Carlos Martín Nieto","fromEmail":"cmn@dwim.me","sentAt":"2016-01-08T01:47:46Z","receivedAt":"2016-01-08T01:47:46Z","isPatch":false,"sender":{"key":"cmn@dwim.me","avatar":"https://avatars.githubusercontent.com/u/335443?v=4"},"body":"On 07 Jan 2016, at 03:04, Jeff King <peff@peff.net> wrote:\n\n> [+cc Carlos and Shawn for libgit2/JGit talk]\n> \n> On Wed, Jan 06, 2016 at 10:58:37AM -0800, Junio C Hamano wrote:\n> \n>> On Wed, Jan 6, 2016 at 2:03 AM, Duy Nguyen <pclouds@gmail.com> wrote:\n>>> \n>>> Yeah.. it looks like libgit2's gitignore support was written new, not\n>>> imported from C Git, so behavior differences (especially in corner\n>>> cases) and even lack of some feature (\"**\" support comes to mind). For\n>>> isolated features like gitignore, perhaps we can have an option to\n>>> replace C Git code with libgit2 and therefore can test libgit2 against\n>>> C Git test suite. It could be a good start for libgit2 to invade C\n>>> Git. Not sure if anybody's interested in doing it though.\n> \n> Yeah, libgit2 is in the difficult position of trying to hit a moving\n> target. There's a good chance that it _was_ the same as git's behavior\n> when it was written. :)\n\nWe did try to match the rules which git followed at the time when we added the functionality, but sometimes small changes in git mean large changes for us. There’s a couple of recent issues complaining that we don’t match git where *git* doesn’t quite seem to match the rules as I know them.\n\nI don’t recall the details of how we brought ignore support in, but when we don’t just copy the code from git, it’s generally because it’s embedded into the rest of the code, or in some other way doesn’t make a lot of sense in a library API.\n\nWe do (at least I do) want to test libgit2 more against the git test suite; this either involves porting it to our test suite (generally non-trivial since we can’t use shell, making it harder to compare) or creating a command which pretends to be git but uses libgit2. The latter is what I think we’ll have to do, as we keep hitting complex pieces which git keeps changing like crlf and ignore handling. There’s been plans to do this, but it’s never been the top priority.\n\n> \n> JGit is in the same boat, and I wouldn't be surprised if they don't\n> handle \"**\" either (I didn't check). Note that git inherited that\n> feature (and probably some others) by importing a GPLv2 version of\n> wildmatch. That certainly isn't an option for JGit (because it's not\n> pure Java), and probably not for libgit2 (which would need the wildmatch\n> authors to grant the linking exception).\n> \n>> Yup, an area that is reasonably isolated from the remainder of the system like\n>> this might be a good starting point. But I suspect that the invasion needs to\n>> happen in the opposite direction in this particular case before it happens.\n>> That is, if libgit2's implementation does not behave like how we do, it needs to\n>> be fixed, possibly by discarding what they did and instead importing code from\n>> us. After the behaviour of libgit2 is fixed, we can talk about the\n>> invasion in the\n>> opposite direction.\n> \n> Unfortunately, \"importing code from us\" is not so easy. :(\n> \n> They'll either need to contact the wildmatch authors, or rewrite\n> wildmatch from scratch.\n\nYeah, we currently use the fnmatch code from Android IIRC. I’m not looking forward to writing a variant of that for double-star. If the wildmatch authors are receptive to allowing the linking exception, that would be ideal.\n\n   cmn\n"},{"id":"275519","messageId":"20160108024125.GD265296@vauxhall.crustytoothpaste.net","threadId":"41130","inReplyTo":"CACsJy8C1R+JVmOXQ87eBP1COFNk3Vfqtb6AKzzT65catUhPczg@mail.gmail.com","subject":"Re: Git 2.7.0 gitignore behaviour regression","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2016-01-08T02:41:25Z","receivedAt":"2016-01-08T02:41:25Z","isPatch":false,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On Fri, Jan 08, 2016 at 07:38:58AM +0700, Duy Nguyen wrote:\n> On Fri, Jan 8, 2016 at 6:44 AM, brian m. carlson\n> <sandals@crustytoothpaste.net> wrote:\n> > I think there's still a bug in the code here.  If you do\n> >\n> >   git init\n> >   mkdir -p base/a/\n> >   printf 'base/a/\\n!base/a/b.txt\\n' >.gitignore\n> \n> Here we have the ignore rule \"base/a/\", but gitignore.txt, section\n> NOTES mentions this\n> \n>  - The rules to exclude the parent directory must not end with a\n>    trailing slash.\n\nThe text here says, \"To re-include files or directories when their\nparent directory is excluded, the following conditions must be met\".  In\nother words, the text implies that it's required for re-inclusion to\nwork, not exclusion.\n\n> >   git add .gitignore\n> >   git commit -m 'Add .gitignore'\n> >   >base/a/b.txt\n> >   git add base/a/b.txt\n> >   git commit -m 'Add base/a/b.txt'\n> >   >base/a/c.txt\n> >   git status --porcelain\n> >\n> > git status outputs base/a/c.txt as unknown, when it should be ignored.\n> > We saw this in a repository at $DAYJOB.\n> \n> If I delete that trailing slash, c.txt is ignored. So it's known\n> limitation. I think we can make trailing slash case work too, but if I\n> remember correctly it would involve a lot more changes, so I didn't do\n> it (there are other conditions to follow anyway to make it work).\n\nThe case I'm seeing is that b.txt was already checked into the\nrepository before being re-added, and c.txt was not.  So it didn't\naffect us that b.txt was ignored (as it was already in the repo), but\nc.txt not being ignored broke a whole bunch of scripts that checked that\nthe repository was clean, simply because we upgraded Git.\n\nI think regardless of whether b.txt is re-included, c.txt should be\nignored.  If it isn't possible to re-include b.txt, that's fine, since\nthat isn't a regression, but ignored files should remain ignored.\n-- \nbrian m. carlson / brian with sandals: Houston, Texas, US\n+1 832 623 2791 | https://www.crustytoothpaste.net/~bmc | My opinion only\nOpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187\n"},{"id":"275523","messageId":"20160108090231.GA9609@lanh","threadId":"41130","inReplyTo":"20160108024125.GD265296@vauxhall.crustytoothpaste.net","subject":"Re: Git 2.7.0 gitignore behaviour regression","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2016-01-08T09:02:31Z","receivedAt":"2016-01-08T09:02:31Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Jan 08, 2016 at 02:41:25AM +0000, brian m. carlson wrote:\n> On Fri, Jan 08, 2016 at 07:38:58AM +0700, Duy Nguyen wrote:\n> > On Fri, Jan 8, 2016 at 6:44 AM, brian m. carlson\n> > <sandals@crustytoothpaste.net> wrote:\n> > > I think there's still a bug in the code here.  If you do\n> > >\n> > >   git init\n> > >   mkdir -p base/a/\n> > >   printf 'base/a/\\n!base/a/b.txt\\n' >.gitignore\n> > \n> > Here we have the ignore rule \"base/a/\", but gitignore.txt, section\n> > NOTES mentions this\n> > \n> >  - The rules to exclude the parent directory must not end with a\n> >    trailing slash.\n> \n> The text here says, \"To re-include files or directories when their\n> parent directory is excluded, the following conditions must be met\".  In\n> other words, the text implies that it's required for re-inclusion to\n> work, not exclusion.\n> \n> > >   git add .gitignore\n> > >   git commit -m 'Add .gitignore'\n> > >   >base/a/b.txt\n> > >   git add base/a/b.txt\n> > >   git commit -m 'Add base/a/b.txt'\n> > >   >base/a/c.txt\n> > >   git status --porcelain\n> > >\n> > > git status outputs base/a/c.txt as unknown, when it should be ignored.\n> > > We saw this in a repository at $DAYJOB.\n> > \n> > If I delete that trailing slash, c.txt is ignored. So it's known\n> > limitation. I think we can make trailing slash case work too, but if I\n> > remember correctly it would involve a lot more changes, so I didn't do\n> > it (there are other conditions to follow anyway to make it work).\n> \n> The case I'm seeing is that b.txt was already checked into the\n> repository before being re-added, and c.txt was not.  So it didn't\n> affect us that b.txt was ignored (as it was already in the repo), but\n> c.txt not being ignored broke a whole bunch of scripts that checked that\n> the repository was clean, simply because we upgraded Git.\n> \n> I think regardless of whether b.txt is re-included, c.txt should be\n> ignored.  If it isn't possible to re-include b.txt, that's fine, since\n> that isn't a regression, but ignored files should remain ignored.\n\nThanks for clarification. I looked at this the wrong way. I agree it\nis a regression.\n\nThe following should fix it. It looks correct (and does fix your test\ncase), but I will have to look harder over the weekend before sending\na proper patch.\n\n-- 8< --\ndiff --git a/dir.c b/dir.c\nindex d2a8f06..7934e87 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1008,6 +1008,7 @@ static struct exclude *last_exclude_matching_from_list(const char *pathname,\n \tif (exc &&\n \t    !(exc->flags & EXC_FLAG_NEGATIVE) &&\n \t    !(exc->flags & EXC_FLAG_NODIR) &&\n+\t    !(exc->flags & EXC_FLAG_MUSTBEDIR) &&\n \t    matched_negative_path)\n \t\texc = NULL;\n \treturn exc;\n-- 8< --\n--\nDuy\n"}]}