{"thread":{"id":"17604","subject":"How to find out which gitignore blocks my git-add","startedAt":"2009-02-06T09:38:45Z","lastAt":"2009-02-08T09:52:03Z","messageCount":17,"participants":["Gonzo","Jeff King","bisani","Sitaram Chamarty","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"103441","messageId":"498C0525.5040100@gonsolo.de","threadId":"17604","inReplyTo":null,"subject":"How to find out which gitignore blocks my git-add","fromName":"Gonzo","fromEmail":"gonzo@gonsolo.de","sentAt":"2009-02-06T09:38:45Z","receivedAt":"2009-02-06T09:38:45Z","isPatch":false,"sender":{"key":"gonzo@gonsolo.de","avatar":null},"body":"After doing a \"git add file\" I get the message:\n\n\"The following paths are ignored by one of your .gitignore files:\n...\"\n\nIs there an easy way to find out which line in which gitignore file \nblocks this add?\nWould this be a viable addition to \"git add -v\"?\n\ng\n"},{"id":"103548","messageId":"20090206193359.GF19494@coredump.intra.peff.net","threadId":"17604","inReplyTo":"498C0525.5040100@gonsolo.de","subject":"Re: How to find out which gitignore blocks my git-add","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-02-06T19:33:59Z","receivedAt":"2009-02-06T19:33:59Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Feb 06, 2009 at 10:38:45AM +0100, Gonzo wrote:\n\n> After doing a \"git add file\" I get the message:\n>\n> \"The following paths are ignored by one of your .gitignore files:\n> ...\"\n>\n> Is there an easy way to find out which line in which gitignore file  \n> blocks this add?\n\nNo, I don't think so.\n\n> Would this be a viable addition to \"git add -v\"?\n\nI think it might be useful to be able to get this information. However,\nrather than coupling it with \"git add\", it might make more sense to have\na separate way to query \"is this being ignored, and if so, by what\npattern\". Then you could use that tool to generally debug your\n.gitignore patterns.\n\nI'm not sure how painful it would be to implement. You'd probably have\nto record and pass back that information from dir.c:excluded, which is\nwhere we decide whether or not a file is ignored (most of the code calls\nit \"excluded\", but it is the same concept). Want to take a stab at\nwriting a patch?\n\n-Peff\n"},{"id":"103563","messageId":"loom.20090206T215836-960@post.gmane.org","threadId":"17604","inReplyTo":"498C0525.5040100@gonsolo.de","subject":"Re: How to find out which gitignore blocks my git-add","fromName":"","fromEmail":"bisani","sentAt":"2009-02-06T22:00:12Z","receivedAt":"2009-02-06T22:00:12Z","isPatch":false,"sender":{"key":"bisani","avatar":null},"body":"Gonzo <gonzo <at> gonsolo.de> writes:\n\n> \n> After doing a \"git add file\" I get the message:\n> \n> \"The following paths are ignored by one of your .gitignore files:\n> ...\"\n> \n> Is there an easy way to find out which line in which gitignore file \n> blocks this add?\n> Would this be a viable addition to \"git add -v\"?\n> \n> g\n> \n\nIt would be nice if a -v option also lists which pattern caused\n it to exclude.\n"},{"id":"103576","messageId":"slrngopp7n.his.sitaramc@sitaramc.homelinux.net","threadId":"17604","inReplyTo":"20090206193359.GF19494@coredump.intra.peff.net","subject":"Re: How to find out which gitignore blocks my git-add","fromName":"Sitaram Chamarty","fromEmail":"sitaramc@gmail.com","sentAt":"2009-02-07T01:33:43Z","receivedAt":"2009-02-07T01:33:43Z","isPatch":false,"sender":{"key":"sitaramc@gmail.com","avatar":"https://avatars.githubusercontent.com/u/43316?v=4"},"body":"On 2009-02-06, Jeff King <peff@peff.net> wrote:\n> On Fri, Feb 06, 2009 at 10:38:45AM +0100, Gonzo wrote:\n>> Is there an easy way to find out which line in which gitignore file  \n>> blocks this add?\n>\n> No, I don't think so.\n>\n>> Would this be a viable addition to \"git add -v\"?\n>\n> I think it might be useful to be able to get this information. However,\n> rather than coupling it with \"git add\", it might make more sense to have\n> a separate way to query \"is this being ignored, and if so, by what\n> pattern\". Then you could use that tool to generally debug your\n> .gitignore patterns.\n\nmaybe GIT_TRACE could print that as well, in some way?\n"},{"id":"103583","messageId":"20090207064221.GA14856@coredump.intra.peff.net","threadId":"17604","inReplyTo":"slrngopp7n.his.sitaramc@sitaramc.homelinux.net","subject":"Re: How to find out which gitignore blocks my git-add","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-02-07T06:42:21Z","receivedAt":"2009-02-07T06:42:21Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Feb 07, 2009 at 01:33:43AM +0000, Sitaram Chamarty wrote:\n\n> > I think it might be useful to be able to get this information. However,\n> > rather than coupling it with \"git add\", it might make more sense to have\n> > a separate way to query \"is this being ignored, and if so, by what\n> > pattern\". Then you could use that tool to generally debug your\n> > .gitignore patterns.\n> \n> maybe GIT_TRACE could print that as well, in some way?\n\nIt could, but I think reusing GIT_TRACE isn't a good idea. Currently it\ntraces _just_ exec information, so I wouldn't want to pollute that with\nthis information. But yes, you could trigger it through an environment\nvariable, which would let us dump at the lowest level.\n\nI spent a few minutes checking this out, and it looks to be a little\nmore complex than I had hoped, just because we don't have all of the\ninformation in the same place at the same time.\n\nA toy patch series follows; see 2/2 for a description of why it doesn't\nwork like you might hope. I'm not too interested in trying to deal with\nthe refactoring that would be required to do it right. But maybe\nsomebody else is.\n\n-Peff\n"},{"id":"103584","messageId":"20090207064405.GA14906@coredump.intra.peff.net","threadId":"17604","inReplyTo":"20090207064221.GA14856@coredump.intra.peff.net","subject":"[PATCH 1/2] refactor exclude handling","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-02-07T06:44:05Z","receivedAt":"2009-02-07T06:44:05Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"The excluded function uses the static helper excluded_1 to\nperform the inner loop over all of the exclude patterns. The\nhelper just tells us whether the path is included, excluded,\nor undecided.\n\nHowever, it may be useful to know _which_ pattern was\ntriggered. So let's pass out the entire exclude match, which\ncontains the status information we were already passing out.\n\nFurther patches can make use of this.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\nJust a cleanup for the next patch.\n\n dir.c |   25 ++++++++++++++-----------\n 1 files changed, 14 insertions(+), 11 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex cfd1ea5..0ea81b7 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -291,9 +291,10 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)\n }\n \n /* Scan the list and let the last match determines the fate.\n- * Return 1 for exclude, 0 for include and -1 for undecided.\n+ * Returns the exclude_list element which matched, or NULL for\n+ * undecided.\n  */\n-static int excluded_1(const char *pathname,\n+static struct exclude *excluded_1(const char *pathname,\n \t\t      int pathlen, const char *basename, int *dtype,\n \t\t      struct exclude_list *el)\n {\n@@ -303,7 +304,6 @@ static int excluded_1(const char *pathname,\n \t\tfor (i = el->nr - 1; 0 <= i; i--) {\n \t\t\tstruct exclude *x = el->excludes[i];\n \t\t\tconst char *exclude = x->pattern;\n-\t\t\tint to_exclude = x->to_exclude;\n \n \t\t\tif (x->flags & EXC_FLAG_MUSTBEDIR) {\n \t\t\t\tif (*dtype == DT_UNKNOWN)\n@@ -316,14 +316,14 @@ static int excluded_1(const char *pathname,\n \t\t\t\t/* match basename */\n \t\t\t\tif (x->flags & EXC_FLAG_NOWILDCARD) {\n \t\t\t\t\tif (!strcmp(exclude, basename))\n-\t\t\t\t\t\treturn to_exclude;\n+\t\t\t\t\t\treturn x;\n \t\t\t\t} else if (x->flags & EXC_FLAG_ENDSWITH) {\n \t\t\t\t\tif (x->patternlen - 1 <= pathlen &&\n \t\t\t\t\t    !strcmp(exclude + 1, pathname + pathlen - x->patternlen + 1))\n-\t\t\t\t\t\treturn to_exclude;\n+\t\t\t\t\t\treturn x;\n \t\t\t\t} else {\n \t\t\t\t\tif (fnmatch(exclude, basename, 0) == 0)\n-\t\t\t\t\t\treturn to_exclude;\n+\t\t\t\t\t\treturn x;\n \t\t\t\t}\n \t\t\t}\n \t\t\telse {\n@@ -342,16 +342,16 @@ static int excluded_1(const char *pathname,\n \n \t\t\t\tif (x->flags & EXC_FLAG_NOWILDCARD) {\n \t\t\t\t\tif (!strcmp(exclude, pathname + baselen))\n-\t\t\t\t\t\treturn to_exclude;\n+\t\t\t\t\t\treturn x;\n \t\t\t\t} else {\n \t\t\t\t\tif (fnmatch(exclude, pathname+baselen,\n \t\t\t\t\t\t    FNM_PATHNAME) == 0)\n-\t\t\t\t\t    return to_exclude;\n+\t\t\t\t\t    return x;\n \t\t\t\t}\n \t\t\t}\n \t\t}\n \t}\n-\treturn -1; /* undecided */\n+\treturn NULL;\n }\n \n int excluded(struct dir_struct *dir, const char *pathname, int *dtype_p)\n@@ -363,8 +363,11 @@ int excluded(struct dir_struct *dir, const char *pathname, int *dtype_p)\n \n \tprep_exclude(dir, pathname, basename-pathname);\n \tfor (st = EXC_CMDL; st <= EXC_FILE; st++) {\n-\t\tswitch (excluded_1(pathname, pathlen, basename,\n-\t\t\t\t   dtype_p, &dir->exclude_list[st])) {\n+\t\tstruct exclude *x = excluded_1(pathname, pathlen, basename,\n+\t\t\t\t\tdtype_p, &dir->exclude_list[st]);\n+\t\tif (!x)\n+\t\t\tcontinue;\n+\t\tswitch (x->to_exclude) {\n \t\tcase 0:\n \t\t\treturn 0;\n \t\tcase 1:\n-- \n1.6.1.2.552.g1682c.dirty\n"},{"id":"103586","messageId":"20090207064454.GB14906@coredump.intra.peff.net","threadId":"17604","inReplyTo":"20090207064221.GA14856@coredump.intra.peff.net","subject":"[PATCH 2/2] give exclude mechanism a debug option","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-02-07T06:44:55Z","receivedAt":"2009-02-07T06:44:55Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"Users can set GIT_DEBUG_IGNORE in the environment to get the\nexclusion mechanism to dump to stderr files mentioned in\n.gitignore along with the pattern that matched. The output\nlooks something like:\n\n  foo.c: exclude: *.c\n\nThis implementation has several shortcomings that make it\nunsuitable for inclusion:\n\n  1. Doing it as a debug environment variable is hack-ish.\n     A nicer interface would be a .gitignore equivalent of\n     \"git check-attr\".\n\n  2. If you ask for \"foo/bar\", and \"foo/\" is ignored, the\n     output will show only \"foo: exclude: foo\". This is an\n     artifact of the calling interface: you don't ask \"is\n     foo/bar excluded\", but rather while recursing through\n     \"foo/\" you ask \"should I bother even recursing into\n     foo?\". So the exclusion code never even knows that you\n     might have cared about foo/bar in the first place.\n\n  3. There is no indication of where patterns came from. We\n     could specify whether it came from the command-line,\n     from per-directory files, or from another file. But what\n     is most interesting is the actual _filename_ that it\n     came from. I.e., something like:\n\n       sub/foo.c: exclude: sub/.gitignore: *.c\n\n     But that information seems to have been forgotten by\n     the time we are actually doing excludes.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\nIn addition to the problems above, this is hardly tested. ;)\n\n dir.c |   21 +++++++++++++++++++++\n 1 files changed, 21 insertions(+), 0 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex 0ea81b7..1052496 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -8,6 +8,7 @@\n #include \"cache.h\"\n #include \"dir.h\"\n #include \"refs.h\"\n+#include \"quote.h\"\n \n struct path_simplify {\n \tint len;\n@@ -354,6 +355,24 @@ static struct exclude *excluded_1(const char *pathname,\n \treturn NULL;\n }\n \n+static int debug_ignore(void)\n+{\n+\tstatic int ignore = -1;\n+\tif (ignore == -1) {\n+\t\tconst char *env = getenv(\"GIT_DEBUG_IGNORE\");\n+\t\tignore = env ? git_config_bool(\"GIT_DEBUG_IGNORE\", env) : 0;\n+\t}\n+\treturn ignore;\n+}\n+\n+static void show_ignore(const char *path, struct exclude *x)\n+{\n+\tquote_c_style(path, NULL, stderr, 0);\n+\tfprintf(stderr, \": %s: %.*s\\n\",\n+\t\t(x->to_exclude ? \"exclude\" : \"include\"),\n+\t\tx->patternlen, x->pattern);\n+}\n+\n int excluded(struct dir_struct *dir, const char *pathname, int *dtype_p)\n {\n \tint pathlen = strlen(pathname);\n@@ -367,6 +386,8 @@ int excluded(struct dir_struct *dir, const char *pathname, int *dtype_p)\n \t\t\t\t\tdtype_p, &dir->exclude_list[st]);\n \t\tif (!x)\n \t\t\tcontinue;\n+\t\tif (debug_ignore())\n+\t\t\tshow_ignore(pathname, x);\n \t\tswitch (x->to_exclude) {\n \t\tcase 0:\n \t\t\treturn 0;\n-- \n1.6.1.2.552.g1682c.dirty\n"},{"id":"103591","messageId":"7vljsizog1.fsf@gitster.siamese.dyndns.org","threadId":"17604","inReplyTo":"20090207064454.GB14906@coredump.intra.peff.net","subject":"Re: [PATCH 2/2] give exclude mechanism a debug option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-02-07T07:38:38Z","receivedAt":"2009-02-07T07:38:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> Users can set GIT_DEBUG_IGNORE in the environment to get the\n> exclusion mechanism to dump to stderr files mentioned in\n> .gitignore along with the pattern that matched. The output\n> looks something like:\n>\n>   foo.c: exclude: *.c\n>\n> This implementation has several shortcomings that make it\n> unsuitable for inclusion:\n>\n>   1. Doing it as a debug environment variable is hack-ish.\n>      A nicer interface would be a .gitignore equivalent of\n>      \"git check-attr\".\n\nCorrect.\n\n>   2. If you ask for \"foo/bar\", and \"foo/\" is ignored, the\n>      output will show only \"foo: exclude: foo\". This is an\n>      artifact of the calling interface: you don't ask \"is\n>      foo/bar excluded\", but rather while recursing through\n>      \"foo/\" you ask \"should I bother even recursing into\n>      foo?\". So the exclusion code never even knows that you\n>      might have cared about foo/bar in the first place.\n\nI do not see why it is a problem.  It exactly is what you want to know,\nisn't it?\n\n>   3. There is no indication of where patterns came from. We\n>      could specify whether it came from the command-line,\n>      from per-directory files, or from another file. But what\n>      is most interesting is the actual _filename_ that it\n>      came from. I.e., something like:\n>\n>        sub/foo.c: exclude: sub/.gitignore: *.c\n>\n>      But that information seems to have been forgotten by\n>      the time we are actually doing excludes.\n\nFor this, you would need to add an element to exclude_stack structure to\nrecord the human readable name of the exclude source in prep_exclude().\nOnce you find the matched element using your new excluded_1() mechanism\nintroduced by patch 1/2, you can find which stack in dir->exclude_stack\nthe match element belongs to, and map it back the human readable source\nname recorded in the exclude_stack.\n.\n"},{"id":"103592","messageId":"7vhc36zo96.fsf@gitster.siamese.dyndns.org","threadId":"17604","inReplyTo":"7vljsizog1.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 2/2] give exclude mechanism a debug option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-02-07T07:42:45Z","receivedAt":"2009-02-07T07:42:45Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n>>   1. Doing it as a debug environment variable is hack-ish.\n>>      A nicer interface would be a .gitignore equivalent of\n>>      \"git check-attr\".\n>\n> Correct.\n\nI suspect that ls-files would be the good match for it.  Wasn't the\nexclude mechanism originally done for that command to begin with?\n"},{"id":"103611","messageId":"20090207114444.GB18079@coredump.intra.peff.net","threadId":"17604","inReplyTo":"7vljsizog1.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 2/2] give exclude mechanism a debug option","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-02-07T11:44:44Z","receivedAt":"2009-02-07T11:44:44Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Feb 06, 2009 at 11:38:38PM -0800, Junio C Hamano wrote:\n\n> >   2. If you ask for \"foo/bar\", and \"foo/\" is ignored, the\n> >      output will show only \"foo: exclude: foo\". This is an\n> >      artifact of the calling interface: you don't ask \"is\n> >      foo/bar excluded\", but rather while recursing through\n> >      \"foo/\" you ask \"should I bother even recursing into\n> >      foo?\". So the exclusion code never even knows that you\n> >      might have cared about foo/bar in the first place.\n> \n> I do not see why it is a problem.  It exactly is what you want to know,\n> isn't it?\n\nBecause I would expect \"git check-ignore foo/bar | grep ^foo/bar:\" to\ntell me if and how foo/bar is being excluded. But I have to instead\ncheck for ^foo and ^foo/bar.\n\nNot a big deal, perhaps. But it just seems like counter-intuitive output\nfor a query about how a specific path is excluded.\n\n-Peff\n"},{"id":"103610","messageId":"20090207114628.GC18079@coredump.intra.peff.net","threadId":"17604","inReplyTo":"7vhc36zo96.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 2/2] give exclude mechanism a debug option","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-02-07T11:46:28Z","receivedAt":"2009-02-07T11:46:28Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Feb 06, 2009 at 11:42:45PM -0800, Junio C Hamano wrote:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n> \n> >>   1. Doing it as a debug environment variable is hack-ish.\n> >>      A nicer interface would be a .gitignore equivalent of\n> >>      \"git check-attr\".\n> >\n> > Correct.\n> \n> I suspect that ls-files would be the good match for it.  Wasn't the\n> exclude mechanism originally done for that command to begin with?\n\nI think you are envisioning something like \"which files are excluded,\nand what patterns matched them?\" which ls-files is perhaps a good fit\nfor. I was imagining something more like \"which patterns are affecting\nthis particular path?\" which you could feed the output of a failed \"git\nadd\" to.\n\n-Peff\n"},{"id":"103615","messageId":"slrngor0hb.cq.sitaramc@sitaramc.homelinux.net","threadId":"17604","inReplyTo":"20090207064221.GA14856@coredump.intra.peff.net","subject":"Re: How to find out which gitignore blocks my git-add","fromName":"Sitaram Chamarty","fromEmail":"sitaramc@gmail.com","sentAt":"2009-02-07T12:44:27Z","receivedAt":"2009-02-07T12:44:27Z","isPatch":false,"sender":{"key":"sitaramc@gmail.com","avatar":"https://avatars.githubusercontent.com/u/43316?v=4"},"body":"On 2009-02-07, Jeff King <peff@peff.net> wrote:\n> A toy patch series follows; see 2/2 for a description of why it doesn't\n> work like you might hope. I'm not too interested in trying to deal with\n> the refactoring that would be required to do it right. But maybe\n> somebody else is.\n\nI was thinking it could simply be a separate utility in\ncontrib for starters, perhaps not even written in C.  I\ndon't mind volunteering to write one in shell+the usual\ntoolchain (and I'll test it on msysgit too, because I have\nWindows users).  My C days are a bit behind me, sadly...\n"},{"id":"103618","messageId":"20090207133108.GA20253@coredump.intra.peff.net","threadId":"17604","inReplyTo":"slrngor0hb.cq.sitaramc@sitaramc.homelinux.net","subject":"Re: How to find out which gitignore blocks my git-add","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-02-07T13:31:08Z","receivedAt":"2009-02-07T13:31:08Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Feb 07, 2009 at 12:44:27PM +0000, Sitaram Chamarty wrote:\n\n> On 2009-02-07, Jeff King <peff@peff.net> wrote:\n> > A toy patch series follows; see 2/2 for a description of why it doesn't\n> > work like you might hope. I'm not too interested in trying to deal with\n> > the refactoring that would be required to do it right. But maybe\n> > somebody else is.\n> \n> I was thinking it could simply be a separate utility in\n> contrib for starters, perhaps not even written in C.  I\n> don't mind volunteering to write one in shell+the usual\n> toolchain (and I'll test it on msysgit too, because I have\n> Windows users).  My C days are a bit behind me, sadly...\n\nSure, that might be an easy way to start. But in the long term,\nhaving a separate implementation handling .gitignore parsing and\nrules may diverge from what git is doing. OTOH, in theory those\nrules are pretty well set in stone since users are depending on\nthem.\n\n-Peff\n"},{"id":"103655","messageId":"7viqnludiv.fsf@gitster.siamese.dyndns.org","threadId":"17604","inReplyTo":"20090207114444.GB18079@coredump.intra.peff.net","subject":"Re: [PATCH 2/2] give exclude mechanism a debug option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-02-07T21:45:44Z","receivedAt":"2009-02-07T21:45:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Fri, Feb 06, 2009 at 11:38:38PM -0800, Junio C Hamano wrote:\n>\n>> >   2. If you ask for \"foo/bar\", and \"foo/\" is ignored, the\n>> >      output will show only \"foo: exclude: foo\". This is an\n>> >      artifact of the calling interface: you don't ask \"is\n>> >      foo/bar excluded\", but rather while recursing through\n>> >      \"foo/\" you ask \"should I bother even recursing into\n>> >      foo?\". So the exclusion code never even knows that you\n>> >      might have cared about foo/bar in the first place.\n>> \n>> I do not see why it is a problem.  It exactly is what you want to know,\n>> isn't it?\n>\n> Because I would expect \"git check-ignore foo/bar | grep ^foo/bar:\" to\n> tell me if and how foo/bar is being excluded. But I have to instead\n> check for ^foo and ^foo/bar.\n\nSorry, I do not understand why you need the downstream pipe that filters\nusing grep to begin with.\n\nShouldn't \"git check-ignore dir/path\" talk about the exclude entries that\ncaused dir/path to be excluded and no other patterns?  And if the reason\ndir/path is exclude is because there was a higher level entry to exclude\ndir/, the output would say so.  If there are unrelated exclude entries\nthat exclude dir's neighbour dir2 or dir/path's neighbour dir/path2, they\ndo not affect if dir/path is excluded, so check-ignore wouldn't show, no?\n"},{"id":"103702","messageId":"20090208085933.GB4392@coredump.intra.peff.net","threadId":"17604","inReplyTo":"7viqnludiv.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 2/2] give exclude mechanism a debug option","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-02-08T08:59:33Z","receivedAt":"2009-02-08T08:59:33Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Feb 07, 2009 at 01:45:44PM -0800, Junio C Hamano wrote:\n\n> > Because I would expect \"git check-ignore foo/bar | grep ^foo/bar:\" to\n> > tell me if and how foo/bar is being excluded. But I have to instead\n> > check for ^foo and ^foo/bar.\n> \n> Sorry, I do not understand why you need the downstream pipe that filters\n> using grep to begin with.\n\nSorry, I should have been more clear. The grep was meant to simulate\nwhat my eyes and brain are doing. That is, if I ask \"what are patterns\naffecting foo/bar?\", I expect to see \"foo/bar\" in the output.\n\nFor asking about one path, it may not be that big a deal to see that the\noutput matches to the input. But if I feed a hundred paths to\ncheck-ignore, I expect to be able to scan the output for the input I put\nin.\n\n> Shouldn't \"git check-ignore dir/path\" talk about the exclude entries that\n> caused dir/path to be excluded and no other patterns?  And if the reason\n\nYes, I would think so. Which maybe means using the current \"exclude\"\ncode is not appropriate. Because it is really about traversing the\ndirectory structure, excluding as we go. I don't know that you can\ndirectly ask it about a particular path.\n\n-Peff\n"},{"id":"103708","messageId":"7vmycxz28s.fsf@gitster.siamese.dyndns.org","threadId":"17604","inReplyTo":"20090208085933.GB4392@coredump.intra.peff.net","subject":"Re: [PATCH 2/2] give exclude mechanism a debug option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-02-08T09:50:27Z","receivedAt":"2009-02-08T09:50:27Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Sat, Feb 07, 2009 at 01:45:44PM -0800, Junio C Hamano wrote:\n>\n>> > Because I would expect \"git check-ignore foo/bar | grep ^foo/bar:\" to\n>> > tell me if and how foo/bar is being excluded. But I have to instead\n>> > check for ^foo and ^foo/bar.\n>> \n>> Sorry, I do not understand why you need the downstream pipe that filters\n>> using grep to begin with.\n>\n> Sorry, I should have been more clear. The grep was meant to simulate\n> what my eyes and brain are doing. That is, if I ask \"what are patterns\n> affecting foo/bar?\", I expect to see \"foo/bar\" in the output.\n\nOh, then the output format would, just like \"grep\" given more than one\nfile tells which file it found the match in, talk about which path the\noutput entry talks about when given more than one path.\n\nSomething like:\n\n\t$ git check-ignore foo/bar xyzzy~ hello.c\n\tfoo/bar: foo/.gitignore:4: ??r\n        xyzzy~: .git/info/excludes:22: *~\n\nthat says \"foo/bar is ignored because line 4 of foo/.gitignore tells us to\nignore any three-letter filename that ends with r, xyzzy~ is ignored\nbecause .git/info/excludes tells us to ignore everything that ends with\ntilde on line 22, and hello.c is not ignored at all.\"\n"},{"id":"103709","messageId":"20090208095203.GA12614@coredump.intra.peff.net","threadId":"17604","inReplyTo":"7vmycxz28s.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 2/2] give exclude mechanism a debug option","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-02-08T09:52:03Z","receivedAt":"2009-02-08T09:52:03Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Feb 08, 2009 at 01:50:27AM -0800, Junio C Hamano wrote:\n\n> Oh, then the output format would, just like \"grep\" given more than one\n> file tells which file it found the match in, talk about which path the\n> output entry talks about when given more than one path.\n> \n> Something like:\n> \n> \t$ git check-ignore foo/bar xyzzy~ hello.c\n> \tfoo/bar: foo/.gitignore:4: ??r\n>         xyzzy~: .git/info/excludes:22: *~\n\nRight, exactly. What I was trying to say in my original message was that\nmy toy implementation _didn't_ do that, and it is a downside.\n\n-Peff\n"}]}