{"thread":{"id":"28436","subject":"Git 1.7.6: Sparse checkouts do not work with directory exclusions","startedAt":"2011-09-19T22:03:34Z","lastAt":"2011-09-20T15:22:47Z","messageCount":4,"participants":["Joshua Jensen","Nguyen Thai Ngoc Duy","Michael J Gruber"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"175817","messageId":"4E77BC36.7060005@workspacewhiz.com","threadId":"28436","inReplyTo":null,"subject":"Git 1.7.6: Sparse checkouts do not work with directory exclusions","fromName":"Joshua Jensen","fromEmail":"jjensen@workspacewhiz.com","sentAt":"2011-09-19T22:03:34Z","receivedAt":"2011-09-19T22:03:34Z","isPatch":false,"sender":{"key":"jjensen@workspacewhiz.com","avatar":"https://avatars.githubusercontent.com/u/111687?v=4"},"body":"Sometime after Git 1.7.3.2, sparse checkouts stopped working for me.  My \nsparse-checkout file looks something like:\n\n*\n!DirA/\n!DirB/\nDirC/\n\nI have restored some lines of code that were removed in November 2010.  \nThis resolves the sparse checkout issue for me, but my guess is the \nsolution is not implemented properly.\n\nCan anyone confirm the issue and describe why those lines were removed?\n\nThanks.\n\nJosh\n\n---\n  dir.c |    5 ++++-\n  1 files changed, 4 insertions(+), 1 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex 6e4494e..3f057b6 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -507,7 +507,10 @@ int excluded_from_list(const char *pathname,\n              int to_exclude = x->to_exclude;\n\n              if (x->flags & EXC_FLAG_MUSTBEDIR) {\n-                if (*dtype == DT_UNKNOWN)\n+                if (!prefixcmp(pathname, exclude) &&\n+                    pathname[x->patternlen] == '/')\n+                    return to_exclude;\n+                else if (*dtype == DT_UNKNOWN)\n                      *dtype = get_dtype(NULL, pathname, pathlen);\n                  if (*dtype != DT_DIR)\n                      continue;\n-- \n1.7.6.msysgit.1\n"},{"id":"175849","messageId":"CACsJy8CDtswtPJVt-T911_1y0WqShonvcCbXhFtWu2zjEqLa4A@mail.gmail.com","threadId":"28436","inReplyTo":"4E77BC36.7060005@workspacewhiz.com","subject":"Re: Git 1.7.6: Sparse checkouts do not work with directory exclusions","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-09-20T10:09:42Z","receivedAt":"2011-09-20T10:09:42Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Tue, Sep 20, 2011 at 8:03 AM, Joshua Jensen\n<jjensen@workspacewhiz.com> wrote:\n> Sometime after Git 1.7.3.2, sparse checkouts stopped working for me.  My\n> sparse-checkout file looks something like:\n>\n> *\n> !DirA/\n> !DirB/\n> DirC/\n>\n> I have restored some lines of code that were removed in November 2010.  This\n> resolves the sparse checkout issue for me, but my guess is the solution is\n> not implemented properly.\n>\n> Can anyone confirm the issue\n\nConfirmed. It got me wonder why the negated pattern tests did not\ncatch this. Turns out this works:\n\n/*\n!DirA/\n!DirB/\nDirC\n\nThis is my theory why yours does not work: negated patterns !DirA and\n!DirB excludes both directories, but git still descends in them\nbecause you may have other patterns that re-include parts of\nDirA/DirB, for example:\n\nDirA/DirD\n!DirA\n\nWhen it's in DirA/DirB, \"*\" tells git to match everything (equivalent\n\"DirA/*\" and \"DirB/*\"), so it matches all entries in DirA/DirB again,\nessentially reverting \"!DirA\" and \"!DirB\" effects.\n\nBy using \"/*\" instead of \"*\", we tell git to just match entries at top\nlevel, not all levels.\n\nI think it makes sense, but it's a bit tricky.\n\n> and describe why those lines were removed?\n\nQuotes from 9e08273: \"The commit provided a workaround for matching\ndirectories in index. But it is no longer needed.\"\n-- \nDuy\n"},{"id":"175868","messageId":"4E78A558.6090903@drmicha.warpmail.net","threadId":"28436","inReplyTo":"4E77BC36.7060005@workspacewhiz.com","subject":"Re: Git 1.7.6: Sparse checkouts do not work with directory exclusions","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2011-09-20T14:38:16Z","receivedAt":"2011-09-20T14:38:16Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Joshua Jensen venit, vidit, dixit 20.09.2011 00:03:\n> Sometime after Git 1.7.3.2, sparse checkouts stopped working for me.  My \n> sparse-checkout file looks something like:\n> \n> *\n> !DirA/\n> !DirB/\n> DirC/\n> \n> I have restored some lines of code that were removed in November 2010.  \n> This resolves the sparse checkout issue for me, but my guess is the \n> solution is not implemented properly.\n> \n> Can anyone confirm the issue and describe why those lines were removed?\n> \n> Thanks.\n> \n> Josh\n> \n> ---\n>   dir.c |    5 ++++-\n>   1 files changed, 4 insertions(+), 1 deletions(-)\n> \n> diff --git a/dir.c b/dir.c\n> index 6e4494e..3f057b6 100644\n> --- a/dir.c\n> +++ b/dir.c\n> @@ -507,7 +507,10 @@ int excluded_from_list(const char *pathname,\n>               int to_exclude = x->to_exclude;\n> \n>               if (x->flags & EXC_FLAG_MUSTBEDIR) {\n> -                if (*dtype == DT_UNKNOWN)\n> +                if (!prefixcmp(pathname, exclude) &&\n> +                    pathname[x->patternlen] == '/')\n> +                    return to_exclude;\n> +                else if (*dtype == DT_UNKNOWN)\n>                       *dtype = get_dtype(NULL, pathname, pathlen);\n>                   if (*dtype != DT_DIR)\n>                       continue;\n\nThat code was in git only between\n\nc84de70 (excluded_1(): support exclude files in index, 2009-08-20)\n\nand\n\n9e08273 (Revert \"excluded_1(): support exclude files in index\", 2010-11-27)\n\ni.e. after v1.6.4 and before v1.7.3.2\n\nCcing Duy who will know more.\n\nMichael\n"},{"id":"175874","messageId":"4E78AFC7.4050102@workspacewhiz.com","threadId":"28436","inReplyTo":"CACsJy8CDtswtPJVt-T911_1y0WqShonvcCbXhFtWu2zjEqLa4A@mail.gmail.com","subject":"Re: Git 1.7.6: Sparse checkouts do not work with directory exclusions","fromName":"Joshua Jensen","fromEmail":"jjensen@workspacewhiz.com","sentAt":"2011-09-20T15:22:47Z","receivedAt":"2011-09-20T15:22:47Z","isPatch":false,"sender":{"key":"jjensen@workspacewhiz.com","avatar":"https://avatars.githubusercontent.com/u/111687?v=4"},"body":"----- Original Message -----\nFrom: Nguyen Thai Ngoc Duy\nDate: 9/20/2011 4:09 AM\n> On Tue, Sep 20, 2011 at 8:03 AM, Joshua Jensen\n> <jjensen@workspacewhiz.com>  wrote:\n>> Sometime after Git 1.7.3.2, sparse checkouts stopped working for me.  My\n>> sparse-checkout file looks something like:\n>>\n>> *\n>> !DirA/\n>> !DirB/\n>> DirC/\n> Confirmed. It got me wonder why the negated pattern tests did not\n> catch this. Turns out this works:\n>\n> /*\n> !DirA/\n> !DirB/\n> DirC\n>\n> This is my theory why yours does not work: negated patterns !DirA and\n> !DirB excludes both directories, but git still descends in them\n> because you may have other patterns that re-include parts of\n> DirA/DirB, for example:\n>\n> DirA/DirD\n> !DirA\n>\n> When it's in DirA/DirB, \"*\" tells git to match everything (equivalent\n> \"DirA/*\" and \"DirB/*\"), so it matches all entries in DirA/DirB again,\n> essentially reverting \"!DirA\" and \"!DirB\" effects.\n>\n> By using \"/*\" instead of \"*\", we tell git to just match entries at top\n> level, not all levels.\n>\n> I think it makes sense, but it's a bit tricky.\nI can confirm this fix works for me, but it is certainly tricky.  IMO, \nit should either be documented or some kind of fix should be added to a \nfuture version of Git to allow * by itself to work again.\n\n>> and describe why those lines were removed?\n> Quotes from 9e08273: \"The commit provided a workaround for matching\n> directories in index. But it is no longer needed.\"\nYeah, I saw that, but it made little sense to me, especially since it \nseems to break a behavior that worked before.\n\nThanks!\n\nJosh\n"}]}