{"thread":{"id":"12880","subject":"Bug in .gitignore handling","startedAt":"2008-03-26T20:01:58Z","lastAt":"2008-03-26T20:49:14Z","messageCount":7,"participants":["Tommy Thorn","Junio C Hamano","Linus Torvalds"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"73156","messageId":"47EAABB6.30803@thorn.ws","threadId":"12880","inReplyTo":null,"subject":"Bug in .gitignore handling","fromName":"Tommy Thorn","fromEmail":"tommy-git@thorn.ws","sentAt":"2008-03-26T20:01:58Z","receivedAt":"2008-03-26T20:01:58Z","isPatch":false,"sender":{"key":"tommy-git@thorn.ws","avatar":null},"body":"For reasons too upsetting to explain, I have to keep a collection of \nsymlinks inside my tree but outside of git's control, such as\n\nmydir/foo -> ../otherdir/foo\n\nTo stop git clean from removing it, I added \"foo\" to .gitignore\n\nThe problem is that I foo appears in build paths inside the tree that I \nwould like git clean to pick up, however the pattern \"foo\" is applied \ngenerally and matches stuff like\n\nmydir/mousetrap/foo/objs\n\nAccording to the man page, I should be able to change .gitignore to \n\"foo/\" to stop it from looking recursively, but that doesn't work, as \nnow git clean -n -f -d wants to remove mydir/foo but not mydir/foo/objs\n\nMy desperate attempts \"./foo\" and \"^foo\" also didn't work. Please note \nthat this is a vastly simplified version of the real problem, so I can't \njust use \"!mousetrap/foo\".\n\nIt seems \"foo/\" _should_ work even though foo isn't a directory.\n\nThanks\nTommy\n"},{"id":"73158","messageId":"7vhcetck5m.fsf@gitster.siamese.dyndns.org","threadId":"12880","inReplyTo":"47EAABB6.30803@thorn.ws","subject":"Re: Bug in .gitignore handling","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-26T20:20:05Z","receivedAt":"2008-03-26T20:20:05Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Tommy Thorn <tommy-git@thorn.ws> writes:\n\n> According to the man page, I should be able to change .gitignore to\n> \"foo/\" to stop it from looking recursively, but that doesn't work, as\n> now git clean -n -f -d wants to remove mydir/foo but not mydir/foo/objs\n>\n> My desperate attempts \"./foo\" and \"^foo\" also didn't work. Please note\n> that this is a vastly simplified version of the real problem, so I\n> can't just use \"!mousetrap/foo\".\n>\n> It seems \"foo/\" _should_ work even though foo isn't a directory.\n\nAre you talking about d6b8fc3 (gitignore(5): Allow \"foo/\" in ignore list\nto match directory \"foo\", 2008-01-31), specifically this part of the\nmanual?\n\n    diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt\n    index 08373f5..e847b3b 100644\n    --- a/Documentation/gitignore.txt\n    +++ b/Documentation/gitignore.txt\n    @@ -57,6 +57,13 @@ Patterns have the following 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    +\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\nIncidentally I notice that the above patch did not include new tests to\nsee if \"git clean\" honors the corrected pattern matching rule.  If your\n\"real problem\" is too complex to describe, perhaps an additional test that\nexercises \"git clean\" with test_expect_failure would help motivated\nparties to triage and fix the problem.\n\n\"git clean\" has always been an ugly and unreliable stepchild, and I would\nnot be surprised at all if it is ridden with corner case bugs, especially\naround the area to skip untracked directories; but in this case you are\nnot dealing with a directory but a symlink, and it should not get confused\nby the fact that the symlink happens to point at a directory.\n"},{"id":"73159","messageId":"47EAB187.4070009@thorn.ws","threadId":"12880","inReplyTo":"7vhcetck5m.fsf@gitster.siamese.dyndns.org","subject":"Re: Bug in .gitignore handling","fromName":"Tommy Thorn","fromEmail":"tommy-git@thorn.ws","sentAt":"2008-03-26T20:26:47Z","receivedAt":"2008-03-26T20:26:47Z","isPatch":false,"sender":{"key":"tommy-git@thorn.ws","avatar":null},"body":"Junio C Hamano wrote:\n> Are you talking about d6b8fc3 (gitignore(5): Allow \"foo/\" in ignore list\n> to match directory \"foo\", 2008-01-31), specifically this part of the\n> manual?\n>   \n\nYes, thanks.\n\n> \"git clean\" has always been an ugly and unreliable stepchild, and I would\n> not be surprised at all if it is ridden with corner case bugs, especially\n> around the area to skip untracked directories; but in this case you are\n> not dealing with a directory but a symlink, and it should not get confused\n> by the fact that the symlink happens to point at a directory.\n>   \n\n\nThanks, but first step is in ensuring that my understanding is correct. \nHere's the gist of the test case:\n\nmkdir mydir\ncd mydir\ngit init\nmkdir mousetrap\ntouch mousetrap/nonempty\ngit add mousetrap/nonempty\ngit commit -m \"initial\"\nln -s ../otherdir/foo .\necho \"foo/\" > .gitignore\necho \".gitignore\" >> .gitignore\ngit clean -n -f -d\n\nI expect the last command to report \"Would remove mousetrap/foo/\", but\nI currently get \"Would remove foo\".\n\nThanks,\nTommy\n"},{"id":"73161","messageId":"alpine.LFD.1.00.0803261324380.2775@woody.linux-foundation.org","threadId":"12880","inReplyTo":"47EAABB6.30803@thorn.ws","subject":"Re: Bug in .gitignore handling","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2008-03-26T20:27:50Z","receivedAt":"2008-03-26T20:27:50Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 26 Mar 2008, Tommy Thorn wrote:\n> \n> My desperate attempts \"./foo\" and \"^foo\" also didn't work. Please note that\n> this is a vastly simplified version of the real problem, so I can't just use\n> \"!mousetrap/foo\".\n> \n> It seems \"foo/\" _should_ work even though foo isn't a directory.\n\nClose but no cigar.\n\nUse \"/foo\" and it should be ok.\n\nBasically, a path with a slash in it is considered absolute, but if the \nslash is at the end it will only match a directory. A slash at the \n*beginning* will match the root of the git repository, though.\n\n\t\t\tLinus\n"},{"id":"73162","messageId":"alpine.LFD.1.00.0803261330280.2775@woody.linux-foundation.org","threadId":"12880","inReplyTo":"alpine.LFD.1.00.0803261324380.2775@woody.linux-foundation.org","subject":"Re: Bug in .gitignore handling","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2008-03-26T20:32:31Z","receivedAt":"2008-03-26T20:32:31Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 26 Mar 2008, Linus Torvalds wrote:\n> \n> Basically, a path with a slash in it is considered absolute, but if the \n> slash is at the end it will only match a directory.\n\nActually, to clarify: a path with a slash in it *anywhere*else* than at \nthe end will be considered absolute. At the end it means \"only match \ndirectories\".\n\nSo \n\n\tfoo\n\nwill match any file or directory anywhere in the tree, while\n\n\tfoo/\n\nwill match a directory called \"foo\" anywhere in the tree, and\n\n\t/foo\n\nwill match either a file or directory called \"foo\", but only at the root \nof the repository.\n\nAnd no, I didn't test it, but that's how it should work, afaik.\n\n\t\tLinus\n"},{"id":"73163","messageId":"47EAB3AD.5070507@thorn.ws","threadId":"12880","inReplyTo":"alpine.LFD.1.00.0803261324380.2775@woody.linux-foundation.org","subject":"Re: Bug in .gitignore handling","fromName":"Tommy Thorn","fromEmail":"tommy-git@thorn.ws","sentAt":"2008-03-26T20:35:57Z","receivedAt":"2008-03-26T20:35:57Z","isPatch":false,"sender":{"key":"tommy-git@thorn.ws","avatar":null},"body":"Linus Torvalds wrote:\n> On Wed, 26 Mar 2008, Tommy Thorn wrote:\n>   \n>> My desperate attempts \"./foo\" and \"^foo\" also didn't work. Please note that\n>> this is a vastly simplified version of the real problem, so I can't just use\n>> \"!mousetrap/foo\".\n>>\n>> It seems \"foo/\" _should_ work even though foo isn't a directory.\n>>     \n>\n> Close but no cigar.\n>\n> Use \"/foo\" and it should be ok.\n>\n> Basically, a path with a slash in it is considered absolute, but if the \n> slash is at the end it will only match a directory. A slash at the \n> *beginning* will match the root of the git repository, though.\n\nD'oh, of course that works. I double check the documentation and it \nactually isn't obvious that that is allowed, so I propose this patch.\n\nTommy\n\n\n From c0a003e995e325d5d9e056137b4b02c370c9dc03 Mon Sep 17 00:00:00 2001\nFrom: Tommy Thorn <tommy-git@thorn.ws>\nDate: Wed, 26 Mar 2008 13:34:34 -0700\nSubject: [PATCH] Documentation/gitginore.txt: Be explicit about the /foo \nform\n\nSigned-off-by: Tommy Thorn <tommy-git@thorn.ws>\n---\n Documentation/gitignore.txt |    3 +++\n 1 files changed, 3 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt\nindex e847b3b..941a8a4 100644\n--- a/Documentation/gitignore.txt\n+++ b/Documentation/gitignore.txt\n@@ -57,6 +57,9 @@ Patterns have the following format:\n    included again.  If a negated pattern matches, this will\n    override lower precedence patterns sources.\n \n+ - If the pattern begins with a slash '/', the pattern will only\n+   match in the current directory.\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-- \n1.5.5.rc1\n"},{"id":"73164","messageId":"7vd4phcit1.fsf@gitster.siamese.dyndns.org","threadId":"12880","inReplyTo":"47EAB3AD.5070507@thorn.ws","subject":"Re: Bug in .gitignore handling","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-26T20:49:14Z","receivedAt":"2008-03-26T20:49:14Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Tommy Thorn <tommy-git@thorn.ws> writes:\n\n> Linus Torvalds wrote:\n>> On Wed, 26 Mar 2008, Tommy Thorn wrote:\n> ...\n>> Use \"/foo\" and it should be ok.\n>>\n>> Basically, a path with a slash in it is considered absolute, but if\n>> the slash is at the end it will only match a directory. A slash at\n>> the *beginning* will match the root of the git repository, though.\n>\n> D'oh, of course that works. I double check the documentation and it\n> actually isn't obvious that that is allowed, so I propose this patch.\n>\n> diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt\n> index e847b3b..941a8a4 100644\n> --- a/Documentation/gitignore.txt\n> +++ b/Documentation/gitignore.txt\n> @@ -57,6 +57,9 @@ Patterns have the following format:\n>    included again.  If a negated pattern matches, this will\n>    override lower precedence patterns sources.\n>\n> + - If the pattern begins with a slash '/', the pattern will only\n> +   match in the current directory.\n> +\n\nDid you fully read the existing description and Linus's resopnse?\n\nThe above is just a special case of a pattern that contains a slash '/'\n(iow, that falls into \"Otherwise\" rule that follows \"If the pattern does\nnot contain a slash '/'\").\n\n\n \n"}]}