{"thread":{"id":"4668","subject":"[PATCH] git-grep: allow patterns starting with -","startedAt":"2006-06-25T15:38:41Z","lastAt":"2006-07-03T07:54:22Z","messageCount":32,"participants":["Matthias Lederhofer","Timo Hirvonen","Johannes Schindelin","Thomas Glanzmann","Junio C Hamano","Jakub Narebski","Andreas Ericsson"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"22566","messageId":"E1FuWh7-0008Ry-HX@moooo.ath.cx","threadId":"4668","inReplyTo":null,"subject":"[PATCH] git-grep: allow patterns starting with -","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-06-25T15:38:41Z","receivedAt":"2006-06-25T15:38:41Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Signed-off-by: Matthias Lederhofer <matled@gmx.net>\n---\nI did not find another way to use patterns starting with -, if it is\npossible without the patch please tell me and ignore the patch :)\nexample:\n% git grep -- --bla HEAD HEAD~1 -- --foo\nHEAD:--foo/bla:test --bla foo\n\n builtin-grep.c |    7 ++++++-\n 1 files changed, 6 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin-grep.c b/builtin-grep.c\nindex 2e7986c..d0677cc 100644\n--- a/builtin-grep.c\n+++ b/builtin-grep.c\n@@ -817,8 +817,13 @@ int cmd_grep(int argc, const char **argv\n \t\t\t}\n \t\t\tusage(builtin_grep_usage);\n \t\t}\n-\t\tif (!strcmp(\"--\", arg))\n+\t\tif (!strcmp(\"--\", arg)) {\n+\t\t\tif (!opt.pattern_list && argc > 0) {\n+\t\t\t\targc--; argv++;\n+\t\t\t\tadd_pattern(&opt, *argv, \"command line\", 0);\n+\t\t\t}\n \t\t\tbreak;\n+\t\t}\n \t\tif (*arg == '-')\n \t\t\tusage(builtin_grep_usage);\n \n-- \n1.4.1.rc1.g29f4a-dirty\n"},{"id":"22568","messageId":"20060625184757.f8273820.tihirvon@gmail.com","threadId":"4668","inReplyTo":"E1FuWh7-0008Ry-HX@moooo.ath.cx","subject":"Re: [PATCH] git-grep: allow patterns starting with -","fromName":"Timo Hirvonen","fromEmail":"tihirvon@gmail.com","sentAt":"2006-06-25T15:47:57Z","receivedAt":"2006-06-25T15:47:57Z","isPatch":true,"sender":{"key":"tihirvon@gmail.com","avatar":null},"body":"Matthias Lederhofer <matled@gmx.net> wrote:\n\n> Signed-off-by: Matthias Lederhofer <matled@gmx.net>\n> ---\n> I did not find another way to use patterns starting with -, if it is\n> possible without the patch please tell me and ignore the patch :)\n> example:\n> % git grep -- --bla HEAD HEAD~1 -- --foo\n> HEAD:--foo/bla:test --bla foo\n\ngit grep -e --bla\n\nIt's not very well documented.\n\n-- \nhttp://onion.dynserv.net/~timo/\n"},{"id":"22569","messageId":"E1FuX8l-0001H5-2z@moooo.ath.cx","threadId":"4668","inReplyTo":"20060625184757.f8273820.tihirvon@gmail.com","subject":"[PATCH] correct documentation for git grep","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-06-25T16:07:15Z","receivedAt":"2006-06-25T16:07:15Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"---\n> git grep -e --bla\n> \n> It's not very well documented.\nLet's change that!\n\n Documentation/git-grep.txt |    7 ++++++-\n 1 files changed, 6 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt\nindex 7b810df..62a8e7f 100644\n--- a/Documentation/git-grep.txt\n+++ b/Documentation/git-grep.txt\n@@ -16,7 +16,7 @@ SYNOPSIS\n \t   [-n] [-l | --files-with-matches] [-L | --files-without-match]\n \t   [-c | --count]\n \t   [-A <post-context>] [-B <pre-context>] [-C <context>]\n-\t   [-f <file>] [-e <pattern>]\n+\t   [-f <file>] [-e] <pattern>\n \t   [<tree>...]\n \t   [--] [<path>...]\n \n@@ -71,6 +71,11 @@ OPTIONS\n -f <file>::\n \tRead patterns from <file>, one per line.\n \n+-e::\n+\tThe next parameter is the pattern. This option has to be\n+\tused for patterns starting with - and should be used in\n+\tscripts passing user input to grep.\n+\n `<tree>...`::\n \tSearch blobs in the trees for specified patterns.\n \n-- \n1.4.1.rc1.gc594\n"},{"id":"22571","messageId":"E1FuXK0-0001fy-1T@moooo.ath.cx","threadId":"4668","inReplyTo":"20060625184757.f8273820.tihirvon@gmail.com","subject":"Re: [PATCH] git-grep: allow patterns starting with -","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-06-25T16:18:52Z","receivedAt":"2006-06-25T16:18:52Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"> Matthias Lederhofer <matled@gmx.net> wrote:\n> \n> > Signed-off-by: Matthias Lederhofer <matled@gmx.net>\n> > ---\n> > I did not find another way to use patterns starting with -, if it is\n> > possible without the patch please tell me and ignore the patch :)\n> > example:\n> > % git grep -- --bla HEAD HEAD~1 -- --foo\n> > HEAD:--foo/bla:test --bla foo\n> \n> git grep -e --bla\nPerhaps the original patch may be applied anyways for consistency with\nthe GNU grep? :)\nBut it's really not important to me and well, having -- twice in the\ncommand line is a bit strange too.\n"},{"id":"22579","messageId":"Pine.LNX.4.63.0606260108510.29667@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"4668","inReplyTo":"E1FuX8l-0001H5-2z@moooo.ath.cx","subject":"Re: [PATCH] correct documentation for git grep","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2006-06-25T23:10:33Z","receivedAt":"2006-06-25T23:10:33Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sun, 25 Jun 2006, Matthias Lederhofer wrote:\n\n> +-e::\n> +\tThe next parameter is the pattern. This option has to be\n> +\tused for patterns starting with - and should be used in\n> +\tscripts passing user input to grep.\n\n... and by the far the most common use is to pass more than one pattern. \nAlso, the usage is \"[-e] <pattern> [-e <pattern>...]\".\n\nCiao,\nDscho\n"},{"id":"22582","messageId":"E1FueCE-0003W3-4Q@moooo.ath.cx","threadId":"4668","inReplyTo":"Pine.LNX.4.63.0606260108510.29667@wbgn013.biozentrum.uni-wuerzburg.de","subject":"[PATCH] correct documentation for git grep","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-06-25T23:39:18Z","receivedAt":"2006-06-25T23:39:18Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Signed-off-by: Matthias Lederhofer <matled@gmx.net>\n---\n> ... and by the far the most common use is to pass more than one pattern. \n> Also, the usage is \"[-e] <pattern> [-e <pattern>...]\".\nOk, so I changed the patch :)\n\n Documentation/git-grep.txt |    8 +++++++-\n 1 files changed, 7 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt\nindex 7b810df..3dd1bdd 100644\n--- a/Documentation/git-grep.txt\n+++ b/Documentation/git-grep.txt\n@@ -16,7 +16,7 @@ SYNOPSIS\n \t   [-n] [-l | --files-with-matches] [-L | --files-without-match]\n \t   [-c | --count]\n \t   [-A <post-context>] [-B <pre-context>] [-C <context>]\n-\t   [-f <file>] [-e <pattern>]\n+\t   [-f <file>] [-e] <pattern> [-e <pattern> [..]]\n \t   [<tree>...]\n \t   [--] [<path>...]\n \n@@ -71,6 +71,12 @@ OPTIONS\n -f <file>::\n \tRead patterns from <file>, one per line.\n \n+-e::\n+\tThe next parameter is a pattern. This option has to be\n+\tused for patterns starting with - and should be used in\n+\tscripts passing user input to grep. You can specify multiple\n+\tpatterns which will be combined by or.\n+\n `<tree>...`::\n \tSearch blobs in the trees for specified patterns.\n \n-- \n1.4.1.rc1.g72a4-dirty\n"},{"id":"22583","messageId":"E1FueYh-0004XE-Fg@moooo.ath.cx","threadId":"4668","inReplyTo":"Pine.LNX.4.63.0606260108510.29667@wbgn013.biozentrum.uni-wuerzburg.de","subject":"[PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-06-26T00:02:31Z","receivedAt":"2006-06-26T00:02:31Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Signed-off-by: Matthias Lederhofer <matled@gmx.net>\n---\n> ... and by the far the most common use is to pass more than one pattern. \n> Also, the usage is \"[-e] <pattern> [-e <pattern>...]\".\n\nHere is a patch to allow combination of patterns with 'and' instead of\n'or'. This makes it easier to search for combinations of words in a line\nwithout using grep multiple times combined by pipes. So it is still\npossible to use -A/-B/-C (something I miss in normal grep). --and\ncannot be passed down, so we have to use the built-in version if it is\nset.\n\n Documentation/git-grep.txt |    5 ++++-\n builtin-grep.c             |   17 +++++++++++++----\n 2 files changed, 17 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt\nindex ebfe51b..df9d705 100644\n--- a/Documentation/git-grep.txt\n+++ b/Documentation/git-grep.txt\n@@ -16,7 +16,7 @@ SYNOPSIS\n \t   [-n] [-l | --files-with-matches] [-L | --files-without-match]\n \t   [-c | --count]\n \t   [-A <post-context>] [-B <pre-context>] [-C <context>]\n-\t   [-f <file>] [-e] <pattern> [-e <pattern> [..]]\n+\t   [-f <file>] [-e] <pattern> [-e <pattern> [..]] [--and]\n \t   [<tree>...]\n \t   [--] [<path>...]\n \n@@ -77,6 +77,9 @@ OPTIONS\n \tscripts passing user input to grep. You can specify multiple\n \tpatterns which will be combined by 'or'.\n \n+--and::\n+\tCombine multiple patterns by 'and' instead of 'or'.\n+\n `<tree>...`::\n \tSearch blobs in the trees for specified patterns.\n \ndiff --git a/builtin-grep.c b/builtin-grep.c\nindex d0677cc..a2a034a 100644\n--- a/builtin-grep.c\n+++ b/builtin-grep.c\n@@ -96,6 +96,7 @@ struct grep_opt {\n \tregex_t regexp;\n \tunsigned linenum:1;\n \tunsigned invert:1;\n+\tunsigned and:1;\n \tunsigned name_only:1;\n \tunsigned unmatch_name_only:1;\n \tunsigned count:1;\n@@ -268,7 +269,11 @@ static int grep_buffer(struct grep_opt *\n \t\t\t\t    word_char(bol[pmatch[0].rm_eo]))\n \t\t\t\t\thit = 0;\n \t\t\t}\n-\t\t\tif (hit)\n+\t\t\tif (opt->and && !hit) {\n+\t\t\t\thit = 0;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (!opt->and && hit)\n \t\t\t\tbreak;\n \t\t}\n \t\t/* \"grep -v -e foo -e bla\" should list lines\n@@ -553,10 +558,10 @@ static int grep_cache(struct grep_opt *o\n #ifdef __unix__\n \t/*\n \t * Use the external \"grep\" command for the case where\n-\t * we grep through the checked-out files. It tends to\n-\t * be a lot more optimized\n+\t * we grep through the checked-out files and do not use\n+\t * non-standard options. It tends to be a lot more optimized.\n \t */\n-\tif (!cached) {\n+\tif (!cached && !opt->and) {\n \t\thit = external_grep(opt, paths, cached);\n \t\tif (hit >= 0)\n \t\t\treturn hit;\n@@ -690,6 +695,10 @@ int cmd_grep(int argc, const char **argv\n \t\t\topt.binary = GREP_BINARY_TEXT;\n \t\t\tcontinue;\n \t\t}\n+\t\tif (!strcmp(\"--and\", arg)) {\n+\t\t\topt.and = 1;\n+\t\t\tcontinue;\n+\t\t}\n \t\tif (!strcmp(\"-i\", arg) ||\n \t\t    !strcmp(\"--ignore-case\", arg)) {\n \t\t\topt.regflags |= REG_ICASE;\n-- \n1.4.1.rc1.g72a4-dirty\n"},{"id":"22584","messageId":"E1Fuecp-0004iI-RG@moooo.ath.cx","threadId":"4668","inReplyTo":"E1FueCE-0003W3-4Q@moooo.ath.cx","subject":"[PATCH] correct documentation for git grep","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-06-26T00:06:47Z","receivedAt":"2006-06-26T00:06:47Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Signed-off-by: Matthias Lederhofer <matled@gmx.net>\n---\nThe 'or' as logic or should be marked in the text. I did\nthat in the patch with --and too so if this is accepted the\ndocumentation should be consistent. Sorry for the noise.\n\n Documentation/git-grep.txt |    8 +++++++-\n 1 files changed, 7 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt\nindex 7b810df..ebfe51b 100644\n--- a/Documentation/git-grep.txt\n+++ b/Documentation/git-grep.txt\n@@ -16,7 +16,7 @@ SYNOPSIS\n \t   [-n] [-l | --files-with-matches] [-L | --files-without-match]\n \t   [-c | --count]\n \t   [-A <post-context>] [-B <pre-context>] [-C <context>]\n-\t   [-f <file>] [-e <pattern>]\n+\t   [-f <file>] [-e] <pattern> [-e <pattern> [..]]\n \t   [<tree>...]\n \t   [--] [<path>...]\n \n@@ -71,6 +71,12 @@ OPTIONS\n -f <file>::\n \tRead patterns from <file>, one per line.\n \n+-e::\n+\tThe next parameter is a pattern. This option has to be\n+\tused for patterns starting with - and should be used in\n+\tscripts passing user input to grep. You can specify multiple\n+\tpatterns which will be combined by 'or'.\n+\n `<tree>...`::\n \tSearch blobs in the trees for specified patterns.\n \n-- \n1.4.1.rc1.g72a4-dirty\n"},{"id":"22589","messageId":"Pine.LNX.4.63.0606260858050.29667@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"4668","inReplyTo":"E1Fuecp-0004iI-RG@moooo.ath.cx","subject":"Re: [PATCH] correct documentation for git grep","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2006-06-26T06:59:46Z","receivedAt":"2006-06-26T06:59:46Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 26 Jun 2006, Matthias Lederhofer wrote:\n\n> -\t   [-f <file>] [-e <pattern>]\n> +\t   [-f <file>] [-e] <pattern> [-e <pattern> [..]]\n>  \t   [<tree>...]\n>  \t   [--] [<path>...]\n\nMinor nit: as you can see from the two latter lines, \"<bla>...\" is the \nstandard notation, whereas \"<bla> [..]\" is not.\n\nCiao,\nDscho\n"},{"id":"22850","messageId":"20060629222009.GA9310@cip.informatik.uni-erlangen.de","threadId":"4668","inReplyTo":"E1FueYh-0004XE-Fg@moooo.ath.cx","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Thomas Glanzmann","fromEmail":"sithglan@stud.uni-erlangen.de","sentAt":"2006-06-29T22:20:09Z","receivedAt":"2006-06-29T22:20:09Z","isPatch":true,"sender":{"key":"sithglan@stud.uni-erlangen.de","avatar":null},"body":"Hello,\n\n> *AND* more than one pattern. (something I miss in normal grep)\n\nso do I, is it possible to use git-grep outside of git for files that\nare not in a repository? Or are there any grep implementations available\nwhich bring this feature to me?\n\n        Thomas\n"},{"id":"22855","messageId":"7vejx7oa3x.fsf@assigned-by-dhcp.cox.net","threadId":"4668","inReplyTo":"20060629222009.GA9310@cip.informatik.uni-erlangen.de","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-06-29T22:44:34Z","receivedAt":"2006-06-29T22:44:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Glanzmann <sithglan@stud.uni-erlangen.de> writes:\n\n> Hello,\n>\n>> *AND* more than one pattern. (something I miss in normal grep)\n>\n> so do I.\n\nSo do I.\n\nI am wondering if we would rather want to do something like\nexpression `find` command let's you build.  In other words:\n\n\tgit grep --extended-expression '(' 'foo' -o 'bar' ')' -a 'frotz'\n\nmight be what we would eventually want.  And I have this nagging\nsuspicion that if we allow to say something like this\n\n\tgit grep --and -e a -e b\n\nright now, it would make it more cumbersome (read: backward\ncompatibility wart) to support both styles later.\n\nI could be talked into\n\n\tgit grep -e a -a -e b\n\nbut that would already be building that expression engine, so...\n"},{"id":"22877","messageId":"E1Fw8hS-00023y-FY@moooo.ath.cx","threadId":"4668","inReplyTo":"7vejx7oa3x.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-06-30T02:25:42Z","receivedAt":"2006-06-30T02:25:42Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"So here is my proposal how extended expressions would work:\n\nextended expressions have three operators:\n    AND, OR (binary), NOT (unary)\nextended expressions do not need an extra option. They will be usable\nby adding operators between the expressions; a default operator is\nused if no operator is specified. The default operator is by default\nOR because currently multiple patterns are combined by OR.\n\nOR and AND have precedence, so there are two possibilities, I'd take\nthe first one.\n1. OR, AND:\n    This will make it easier to read because OR can be skipped:\n      pat1 pat2 AND pat3 pat4\n    = pat1 OR pat2 AND pat3 OR pat4\n    = (pat1 OR pat2) AND (pat3 OR pat4)\n2. AND, OR:\n    This is a bit more logic if you think of AND as * and OR as +.\n\nParenthesis may be used to explicitly override the default precedence.\n\nWith this setup we can add an option -FOO (I don't now how to call it,\nit is the --and from the patch) which changes the default operator and\nthe precedence.  With -FOO you'd get AND as default operator and\nprecedence AND, OR.  Without this option it was easy to write the\nformula in a conjungtive form (conjunction of disjunctions), now it is\neasy to write a disjunctive form (disjunction of conjunctions):\n  pat1 pat2 OR pat3 pat4\n= pat1 AND pat2 OR pat3 AND pat4\n= (pat1 AND pat2) OR (pat3 AND pat4)\n\nWith all this as plan for extended expressions we may also introduce\n-FOO now with exactly the behaviour of --and in my patch because\ncurrently no explicit operators and parenthesis are allowed, so only\nthe default operator may be used and -FOO would change the default\noperator.\n\nA short example:\n(pat1 AND pat2 AND pat3) OR pat4\ncould be written as\n-FOO pat1 pat2 pat3 OR pat4\nwhich is imho quite readable.\n\nSo the next problem are names for the options. We would need\n - AND: between patterns\n - OR:  between patterns\n - NOT: before a pattern\n - FOO: change default operator and precedence\nUnfortunately -o, -a, -n are taken and I think the options should be\nunique even though they are only allowed at certain positions of the\nargument list. I'll think about it a bit, perhaps someone else has a\ngood idea. FOO should not be named --and imo but I don't have any idea\nfor a good name atm.\n"},{"id":"22883","messageId":"7v7j2zmgbu.fsf@assigned-by-dhcp.cox.net","threadId":"4668","inReplyTo":"E1Fw8hS-00023y-FY@moooo.ath.cx","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-06-30T04:13:09Z","receivedAt":"2006-06-30T04:13:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthias Lederhofer <matled@gmx.net> writes:\n\n> OR and AND have precedence, so there are two possibilities, I'd take\n> the first one.\n> 1. OR, AND:\n>     This will make it easier to read because OR can be skipped:\n>       pat1 pat2 AND pat3 pat4\n>     = pat1 OR pat2 AND pat3 OR pat4\n>     = (pat1 OR pat2) AND (pat3 OR pat4)\n> 2. AND, OR:\n>     This is a bit more logic if you think of AND as * and OR as +.\n\n> ... FOO should not be named --and imo but I don't have any idea\n> for a good name atm.\n\nI personally feel FOO should not even exist.  An option that\ncovers the entire expression to make operator precedence in it\nsounds quite evil.  \n\nI would say make --and bind tighter than --or and use\nparentheses as needed.  Making --or optional sounds fine as that\nwould make the default \"multiple -e\" case similar to what GNU\ngrep does without any --and nor --or.\n"},{"id":"22899","messageId":"E1FwDiI-0007Xp-2s@moooo.ath.cx","threadId":"4668","inReplyTo":"7v7j2zmgbu.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-06-30T07:46:53Z","receivedAt":"2006-06-30T07:46:53Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"(Junio: please reply to this one, forgot the Cc in the first one :/)\n\nJunio C Hamano wrote:\n> Matthias Lederhofer <matled@gmx.net> writes:\n> \n> > OR and AND have precedence, so there are two possibilities, I'd take\n> > the first one.\n> > 1. OR, AND:\n> >     This will make it easier to read because OR can be skipped:\n> >       pat1 pat2 AND pat3 pat4\n> >     = pat1 OR pat2 AND pat3 OR pat4\n> >     = (pat1 OR pat2) AND (pat3 OR pat4)\n> > 2. AND, OR:\n> >     This is a bit more logic if you think of AND as * and OR as +.\n> \n> > ... FOO should not be named --and imo but I don't have any idea\n> > for a good name atm.\n> \n> I personally feel FOO should not even exist.  An option that\n> covers the entire expression to make operator precedence in it\n> sounds quite evil.  \n> \n> I would say make --and bind tighter than --or and use parentheses as\n> needed.\nOk, perhaps changing operator precedence is a bit much. What do you\nthink of that then:\nOperator precedence AND, OR. The FOO options changes the default\noperator to AND. This also seems quite natural if you think of\nAND as * and OR as +:\nA B + C D = A * B + C * D = (A * B) + (C * D)\n\nA few examples to get an impression how the command line could look\nlike:\nA OR B OR (C AND D)    => A B C AND D\n(A OR B OR C) AND D    => (A B C) AND D\nA AND B AND (C OR D)   => -FOO A B (C OR D)\n(A AND B AND C) OR D   => -FOO A B C OR D\n\nPerhaps we even could use options which are similar to * and +, for\nexample:\n - -* and -+ (-* should not be expanded often but is annoying anyway)\n - -. and -+\n - -t and -p (A -t B is A times B, A -p B is A plus B)\n\n> Making --or optional sounds fine as that\n> would make the default \"multiple -e\" case similar to what GNU\n> grep does without any --and nor --or.\nThat's exactly what I was thinking about: make extended expressions\ncompatible to current grep options. This will confuse less people and\nthere is no need for an extra option to activate this.\n"},{"id":"22901","messageId":"7v3bdnkrfb.fsf@assigned-by-dhcp.cox.net","threadId":"4668","inReplyTo":"E1FwDiI-0007Xp-2s@moooo.ath.cx","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-06-30T07:56:24Z","receivedAt":"2006-06-30T07:56:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthias Lederhofer <matled@gmx.net> writes:\n\n> (Junio: please reply to this one, forgot the Cc in the first one :/)\n\nHuh?\n\n>> I personally feel FOO should not even exist.  An option that\n>> covers the entire expression to make operator precedence in it\n>> sounds quite evil.  \n>> \n>> I would say make --and bind tighter than --or and use parentheses as\n>> needed.\n> Ok, perhaps changing operator precedence is a bit much. What do you\n> think of that then:\n> ...\n\nI see you are trying hard to think of a way to justify your\noriginal prefix \"--and\" (or --FOO) implementation, but I simply\ndo not see much point in that.  I doubt changing the default\noperator from --or to --and is less confusing than changing the\nprecedence for the users, so you would hear the same \"I\npersonally feel FOO should not even exist\" objection from me.\n"},{"id":"22907","messageId":"7vsllnj6rh.fsf_-_@assigned-by-dhcp.cox.net","threadId":"4668","inReplyTo":"7v3bdnkrfb.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH] git-grep: boolean expression on pattern matching.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-06-30T10:08:02Z","receivedAt":"2006-06-30T10:08:02Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This extends the behaviour of git-grep when multiple -e options\nare given.  So far, we allowed multiple -e to behave just like\nregular grep with multiple -e, i.e. the patterns are OR'ed\ntogether.\n\nWith this change, you can also have multiple patterns AND'ed\ntogether, or form boolean expressions, like this (the\nparentheses are quoted from the shell in this example):\n\n\t$ git grep -e _PATTERN --and \\( -e atom -e token \\)\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n\n * OR'ing together, admittably, can be done easily by saying\n   something like -e 'atom\\|token', so being able to say --and\n   as you argued is of more practical importance, and doing\n   boolean expression like this might be too much frill.\n\n   Only very lightly tested; it is obviously not slated for\n   1.4.1.\n\n builtin-grep.c |  378 ++++++++++++++++++++++++++++++++++++++++++++++++--------\n 1 files changed, 327 insertions(+), 51 deletions(-)\n\ndiff --git a/builtin-grep.c b/builtin-grep.c\nindex 2e7986c..70b1fd2 100644\n--- a/builtin-grep.c\n+++ b/builtin-grep.c\n@@ -82,17 +82,47 @@ static int pathspec_matches(const char *\n \treturn 0;\n }\n \n+enum grep_pat_token {\n+\tGREP_PATTERN,\n+\tGREP_AND,\n+\tGREP_OPEN_PAREN,\n+\tGREP_CLOSE_PAREN,\n+\tGREP_NOT,\n+\tGREP_OR,\n+};\n+\n struct grep_pat {\n \tstruct grep_pat *next;\n \tconst char *origin;\n \tint no;\n+\tenum grep_pat_token token;\n \tconst char *pattern;\n \tregex_t regexp;\n };\n \n+enum grep_expr_node {\n+\tGREP_NODE_ATOM,\n+\tGREP_NODE_NOT,\n+\tGREP_NODE_AND,\n+\tGREP_NODE_OR,\n+};\n+\n+struct grep_expr {\n+\tenum grep_expr_node node;\n+\tunion {\n+\t\tstruct grep_pat *atom;\n+\t\tstruct grep_expr *unary;\n+\t\tstruct {\n+\t\t\tstruct grep_expr *left;\n+\t\t\tstruct grep_expr *right;\n+\t\t} binary;\n+\t} u;\n+};\n+\n struct grep_opt {\n \tstruct grep_pat *pattern_list;\n \tstruct grep_pat **pattern_tail;\n+\tstruct grep_expr *pattern_expression;\n \tregex_t regexp;\n \tunsigned linenum:1;\n \tunsigned invert:1;\n@@ -105,43 +135,224 @@ #define GREP_BINARY_DEFAULT\t0\n #define GREP_BINARY_NOMATCH\t1\n #define GREP_BINARY_TEXT\t2\n \tunsigned binary:2;\n+\tunsigned extended:1;\n \tint regflags;\n \tunsigned pre_context;\n \tunsigned post_context;\n };\n \n static void add_pattern(struct grep_opt *opt, const char *pat,\n-\t\t\tconst char *origin, int no)\n+\t\t\tconst char *origin, int no, enum grep_pat_token t)\n {\n \tstruct grep_pat *p = xcalloc(1, sizeof(*p));\n \tp->pattern = pat;\n \tp->origin = origin;\n \tp->no = no;\n+\tp->token = t;\n \t*opt->pattern_tail = p;\n \topt->pattern_tail = &p->next;\n \tp->next = NULL;\n }\n \n+static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)\n+{\n+\tint err = regcomp(&p->regexp, p->pattern, opt->regflags);\n+\tif (err) {\n+\t\tchar errbuf[1024];\n+\t\tchar where[1024];\n+\t\tif (p->no)\n+\t\t\tsprintf(where, \"In '%s' at %d, \",\n+\t\t\t\tp->origin, p->no);\n+\t\telse if (p->origin)\n+\t\t\tsprintf(where, \"%s, \", p->origin);\n+\t\telse\n+\t\t\twhere[0] = 0;\n+\t\tregerror(err, &p->regexp, errbuf, 1024);\n+\t\tregfree(&p->regexp);\n+\t\tdie(\"%s'%s': %s\", where, p->pattern, errbuf);\n+\t}\n+}\n+\n+#if DEBUG\n+static inline void indent(int in)\n+{\n+\tint i;\n+\tfor (i = 0; i < in; i++) putchar(' ');\n+}\n+\n+static void dump_pattern_exp(struct grep_expr *x, int in)\n+{\n+\tswitch (x->node) {\n+\tcase GREP_NODE_ATOM:\n+\t\tindent(in);\n+\t\tputs(x->u.atom->pattern);\n+\t\tbreak;\n+\tcase GREP_NODE_NOT:\n+\t\tindent(in);\n+\t\tputs(\"--not\");\n+\t\tdump_pattern_exp(x->u.unary, in+1);\n+\t\tbreak;\n+\tcase GREP_NODE_AND:\n+\t\tdump_pattern_exp(x->u.binary.left, in+1);\n+\t\tindent(in);\n+\t\tputs(\"--and\");\n+\t\tdump_pattern_exp(x->u.binary.right, in+1);\n+\t\tbreak;\n+\tcase GREP_NODE_OR:\n+\t\tdump_pattern_exp(x->u.binary.left, in+1);\n+\t\tindent(in);\n+\t\tputs(\"--or\");\n+\t\tdump_pattern_exp(x->u.binary.right, in+1);\n+\t\tbreak;\n+\t}\n+}\n+\n+static void looking_at(const char *msg, struct grep_pat **list)\n+{\n+\tstruct grep_pat *p = *list;\n+\tfprintf(stderr, \"%s: looking at \", msg);\n+\tif (!p)\n+\t\tfprintf(stderr, \"empty\\n\");\n+\telse\n+\t\tfprintf(stderr, \"<%s>\\n\", p->pattern);\n+}\n+#else\n+#define looking_at(a,b) do {} while(0)\n+#endif\n+\n+static struct grep_expr *compile_pattern_expr(struct grep_pat **);\n+static struct grep_expr *compile_pattern_atom(struct grep_pat **list)\n+{\n+\tstruct grep_pat *p;\n+\tstruct grep_expr *x;\n+\n+\tlooking_at(\"atom\", list);\n+\n+\tp = *list;\n+\tswitch (p->token) {\n+\tcase GREP_PATTERN: /* atom */\n+\t\tx = xcalloc(1, sizeof (struct grep_expr));\n+\t\tx->node = GREP_NODE_ATOM;\n+\t\tx->u.atom = p;\n+\t\t*list = p->next;\n+\t\treturn x;\n+\tcase GREP_OPEN_PAREN:\n+\t\t*list = p->next;\n+\t\tx = compile_pattern_expr(list);\n+\t\tif (!x)\n+\t\t\treturn NULL;\n+\t\tif (!*list || (*list)->token != GREP_CLOSE_PAREN)\n+\t\t\tdie(\"unmatched parenthesis\");\n+\t\t*list = (*list)->next;\n+\t\treturn x;\n+\tdefault:\n+\t\treturn NULL;\n+\t}\n+}\n+\n+static struct grep_expr *compile_pattern_not(struct grep_pat **list)\n+{\n+\tstruct grep_pat *p;\n+\tstruct grep_expr *x;\n+\n+\tlooking_at(\"not\", list);\n+\n+\tp = *list;\n+\tswitch (p->token) {\n+\tcase GREP_NOT:\n+\t\tif (!p->next)\n+\t\t\tdie(\"--not not followed by pattern expression\");\n+\t\t*list = p->next;\n+\t\tx = xcalloc(1, sizeof (struct grep_expr));\n+\t\tx->node = GREP_NODE_NOT;\n+\t\tx->u.unary = compile_pattern_not(list);\n+\t\tif (!x->u.unary)\n+\t\t\tdie(\"--not followed by non pattern expression\");\n+\t\treturn x;\n+\tdefault:\n+\t\treturn compile_pattern_atom(list);\n+\t}\n+}\n+\n+static struct grep_expr *compile_pattern_and(struct grep_pat **list)\n+{\n+\tstruct grep_pat *p;\n+\tstruct grep_expr *x, *y, *z;\n+\n+\tlooking_at(\"and\", list);\n+\n+\tx = compile_pattern_not(list);\n+\tp = *list;\n+\tif (p && p->token == GREP_AND) {\n+\t\tif (!p->next)\n+\t\t\tdie(\"--and not followed by pattern expression\");\n+\t\t*list = p->next;\n+\t\ty = compile_pattern_and(list);\n+\t\tif (!y)\n+\t\t\tdie(\"--and not followed by pattern expression\");\n+\t\tz = xcalloc(1, sizeof (struct grep_expr));\n+\t\tz->node = GREP_NODE_AND;\n+\t\tz->u.binary.left = x;\n+\t\tz->u.binary.right = y;\n+\t\treturn z;\n+\t}\n+\treturn x;\n+}\n+\n+static struct grep_expr *compile_pattern_or(struct grep_pat **list)\n+{\n+\tstruct grep_pat *p;\n+\tstruct grep_expr *x, *y, *z;\n+\n+\tlooking_at(\"or\", list);\n+\n+\tx = compile_pattern_and(list);\n+\tp = *list;\n+\tif (x && p && p->token != GREP_CLOSE_PAREN) {\n+\t\ty = compile_pattern_or(list);\n+\t\tif (!y)\n+\t\t\tdie(\"not a pattern expression %s\", p->pattern);\n+\t\tz = xcalloc(1, sizeof (struct grep_expr));\n+\t\tz->node = GREP_NODE_OR;\n+\t\tz->u.binary.left = x;\n+\t\tz->u.binary.right = y;\n+\t\treturn z;\n+\t}\n+\treturn x;\n+}\n+\n+static struct grep_expr *compile_pattern_expr(struct grep_pat **list)\n+{\n+\tlooking_at(\"expr\", list);\n+\n+\treturn compile_pattern_or(list);\n+}\n+\n static void compile_patterns(struct grep_opt *opt)\n {\n \tstruct grep_pat *p;\n+\n+\t/* First compile regexps */\n \tfor (p = opt->pattern_list; p; p = p->next) {\n-\t\tint err = regcomp(&p->regexp, p->pattern, opt->regflags);\n-\t\tif (err) {\n-\t\t\tchar errbuf[1024];\n-\t\t\tchar where[1024];\n-\t\t\tif (p->no)\n-\t\t\t\tsprintf(where, \"In '%s' at %d, \",\n-\t\t\t\t\tp->origin, p->no);\n-\t\t\telse if (p->origin)\n-\t\t\t\tsprintf(where, \"%s, \", p->origin);\n-\t\t\telse\n-\t\t\t\twhere[0] = 0;\n-\t\t\tregerror(err, &p->regexp, errbuf, 1024);\n-\t\t\tregfree(&p->regexp);\n-\t\t\tdie(\"%s'%s': %s\", where, p->pattern, errbuf);\n-\t\t}\n+\t\tif (p->token == GREP_PATTERN)\n+\t\t\tcompile_regexp(p, opt);\n+\t\telse\n+\t\t\topt->extended = 1;\n \t}\n+\n+\tif (!opt->extended)\n+\t\treturn;\n+\n+\t/* Then bundle them up in an expression.\n+\t * A classic recursive descent parser would do.\n+\t */\n+\tp = opt->pattern_list;\n+\topt->pattern_expression = compile_pattern_expr(&p);\n+#if DEBUG\n+\tdump_pattern_exp(opt->pattern_expression, 0);\n+#endif\n+\tif (p)\n+\t\tdie(\"incomplete pattern expression: %s\", p->pattern);\n }\n \n static char *end_of_line(char *cp, unsigned long *left)\n@@ -196,6 +407,79 @@ static int fixmatch(const char *pattern,\n \t}\n }\n \n+static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol, char *eol)\n+{\n+\tint hit = 0;\n+\tregmatch_t pmatch[10];\n+\n+\tif (!opt->fixed) {\n+\t\tregex_t *exp = &p->regexp;\n+\t\thit = !regexec(exp, bol, ARRAY_SIZE(pmatch),\n+\t\t\t       pmatch, 0);\n+\t}\n+\telse {\n+\t\thit = !fixmatch(p->pattern, bol, pmatch);\n+\t}\n+\n+\tif (hit && opt->word_regexp) {\n+\t\t/* Match beginning must be either\n+\t\t * beginning of the line, or at word\n+\t\t * boundary (i.e. the last char must\n+\t\t * not be alnum or underscore).\n+\t\t */\n+\t\tif ((pmatch[0].rm_so < 0) ||\n+\t\t    (eol - bol) <= pmatch[0].rm_so ||\n+\t\t    (pmatch[0].rm_eo < 0) ||\n+\t\t    (eol - bol) < pmatch[0].rm_eo)\n+\t\t\tdie(\"regexp returned nonsense\");\n+\t\tif (pmatch[0].rm_so != 0 &&\n+\t\t    word_char(bol[pmatch[0].rm_so-1]))\n+\t\t\thit = 0;\n+\t\tif (pmatch[0].rm_eo != (eol-bol) &&\n+\t\t    word_char(bol[pmatch[0].rm_eo]))\n+\t\t\thit = 0;\n+\t}\n+\treturn hit;\n+}\n+\n+static int match_expr_eval(struct grep_opt *opt,\n+\t\t\t   struct grep_expr *x,\n+\t\t\t   char *bol, char *eol)\n+{\n+\tswitch (x->node) {\n+\tcase GREP_NODE_ATOM:\n+\t\treturn match_one_pattern(opt, x->u.atom, bol, eol);\n+\t\tbreak;\n+\tcase GREP_NODE_NOT:\n+\t\treturn !match_expr_eval(opt, x->u.unary, bol, eol);\n+\tcase GREP_NODE_AND:\n+\t\treturn (match_expr_eval(opt, x->u.binary.left, bol, eol) &&\n+\t\t\tmatch_expr_eval(opt, x->u.binary.right, bol, eol));\n+\tcase GREP_NODE_OR:\n+\t\treturn (match_expr_eval(opt, x->u.binary.left, bol, eol) ||\n+\t\t\tmatch_expr_eval(opt, x->u.binary.right, bol, eol));\n+\t}\n+\tdie(\"Unexpected node type (internal error) %d\\n\", x->node);\n+}\n+\n+static int match_expr(struct grep_opt *opt, char *bol, char *eol)\n+{\n+\tstruct grep_expr *x = opt->pattern_expression;\n+\treturn match_expr_eval(opt, x, bol, eol);\n+}\n+\n+static int match_line(struct grep_opt *opt, char *bol, char *eol)\n+{\n+\tstruct grep_pat *p;\n+\tif (opt->extended)\n+\t\treturn match_expr(opt, bol, eol);\n+\tfor (p = opt->pattern_list; p; p = p->next) {\n+\t\tif (match_one_pattern(opt, p, bol, eol))\n+\t\t\treturn 1;\n+\t}\n+\treturn 0;\n+}\n+\n static int grep_buffer(struct grep_opt *opt, const char *name,\n \t\t       char *buf, unsigned long size)\n {\n@@ -231,46 +515,15 @@ static int grep_buffer(struct grep_opt *\n \t\thunk_mark = \"--\\n\";\n \n \twhile (left) {\n-\t\tregmatch_t pmatch[10];\n \t\tchar *eol, ch;\n \t\tint hit = 0;\n-\t\tstruct grep_pat *p;\n \n \t\teol = end_of_line(bol, &left);\n \t\tch = *eol;\n \t\t*eol = 0;\n \n-\t\tfor (p = opt->pattern_list; p; p = p->next) {\n-\t\t\tif (!opt->fixed) {\n-\t\t\t\tregex_t *exp = &p->regexp;\n-\t\t\t\thit = !regexec(exp, bol, ARRAY_SIZE(pmatch),\n-\t\t\t\t\t       pmatch, 0);\n-\t\t\t}\n-\t\t\telse {\n-\t\t\t\thit = !fixmatch(p->pattern, bol, pmatch);\n-\t\t\t}\n+\t\thit = match_line(opt, bol, eol);\n \n-\t\t\tif (hit && opt->word_regexp) {\n-\t\t\t\t/* Match beginning must be either\n-\t\t\t\t * beginning of the line, or at word\n-\t\t\t\t * boundary (i.e. the last char must\n-\t\t\t\t * not be alnum or underscore).\n-\t\t\t\t */\n-\t\t\t\tif ((pmatch[0].rm_so < 0) ||\n-\t\t\t\t    (eol - bol) <= pmatch[0].rm_so ||\n-\t\t\t\t    (pmatch[0].rm_eo < 0) ||\n-\t\t\t\t    (eol - bol) < pmatch[0].rm_eo)\n-\t\t\t\t\tdie(\"regexp returned nonsense\");\n-\t\t\t\tif (pmatch[0].rm_so != 0 &&\n-\t\t\t\t    word_char(bol[pmatch[0].rm_so-1]))\n-\t\t\t\t\thit = 0;\n-\t\t\t\tif (pmatch[0].rm_eo != (eol-bol) &&\n-\t\t\t\t    word_char(bol[pmatch[0].rm_eo]))\n-\t\t\t\t\thit = 0;\n-\t\t\t}\n-\t\t\tif (hit)\n-\t\t\t\tbreak;\n-\t\t}\n \t\t/* \"grep -v -e foo -e bla\" should list lines\n \t\t * that do not have either, so inversion should\n \t\t * be done outside.\n@@ -452,6 +705,8 @@ static int external_grep(struct grep_opt\n \tchar *argptr = randarg;\n \tstruct grep_pat *p;\n \n+\tif (opt->extended)\n+\t\treturn -1;\n \tlen = nr = 0;\n \tpush_arg(\"grep\");\n \tif (opt->fixed)\n@@ -801,16 +1056,36 @@ int cmd_grep(int argc, const char **argv\n \t\t\t\t/* ignore empty line like grep does */\n \t\t\t\tif (!buf[0])\n \t\t\t\t\tcontinue;\n-\t\t\t\tadd_pattern(&opt, strdup(buf), argv[1], ++lno);\n+\t\t\t\tadd_pattern(&opt, strdup(buf), argv[1], ++lno,\n+\t\t\t\t\t    GREP_PATTERN);\n \t\t\t}\n \t\t\tfclose(patterns);\n \t\t\targv++;\n \t\t\targc--;\n \t\t\tcontinue;\n \t\t}\n+\t\tif (!strcmp(\"--not\", arg)) {\n+\t\t\tadd_pattern(&opt, arg, \"command line\", 0, GREP_NOT);\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(\"--and\", arg)) {\n+\t\t\tadd_pattern(&opt, arg, \"command line\", 0, GREP_AND);\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(\"--or\", arg))\n+\t\t\tcontinue; /* no-op */\n+\t\tif (!strcmp(\"(\", arg)) {\n+\t\t\tadd_pattern(&opt, arg, \"command line\", 0, GREP_OPEN_PAREN);\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(\")\", arg)) {\n+\t\t\tadd_pattern(&opt, arg, \"command line\", 0, GREP_CLOSE_PAREN);\n+\t\t\tcontinue;\n+\t\t}\n \t\tif (!strcmp(\"-e\", arg)) {\n \t\t\tif (1 < argc) {\n-\t\t\t\tadd_pattern(&opt, argv[1], \"-e option\", 0);\n+\t\t\t\tadd_pattern(&opt, argv[1], \"-e option\", 0,\n+\t\t\t\t\t    GREP_PATTERN);\n \t\t\t\targv++;\n \t\t\t\targc--;\n \t\t\t\tcontinue;\n@@ -824,7 +1099,8 @@ int cmd_grep(int argc, const char **argv\n \n \t\t/* First unrecognized non-option token */\n \t\tif (!opt.pattern_list) {\n-\t\t\tadd_pattern(&opt, arg, \"command line\", 0);\n+\t\t\tadd_pattern(&opt, arg, \"command line\", 0,\n+\t\t\t\t    GREP_PATTERN);\n \t\t\tbreak;\n \t\t}\n \t\telse {\n-- \n1.4.1.rc2.gfff62\n"},{"id":"22908","messageId":"e82u4l$fvb$1@sea.gmane.org","threadId":"4668","inReplyTo":"7vsllnj6rh.fsf_-_@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] git-grep: boolean expression on pattern matching.","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-06-30T10:24:32Z","receivedAt":"2006-06-30T10:24:32Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano wrote:\n\n> This extends the behaviour of git-grep when multiple -e options\n> are given.  So far, we allowed multiple -e to behave just like\n> regular grep with multiple -e, i.e. the patterns are OR'ed\n> together.\n> \n> With this change, you can also have multiple patterns AND'ed\n> together, or form boolean expressions, like this (the\n> parentheses are quoted from the shell in this example):\n> \n>       $ git grep -e _PATTERN --and \\( -e atom -e token \\)\n\nAnd where is documentation update?\n \n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"22910","messageId":"7vk66zj5rw.fsf@assigned-by-dhcp.cox.net","threadId":"4668","inReplyTo":"e82u4l$fvb$1@sea.gmane.org","subject":"Re: [PATCH] git-grep: boolean expression on pattern matching.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-06-30T10:29:23Z","receivedAt":"2006-06-30T10:29:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> writes:\n\n>> \n>>       $ git grep -e _PATTERN --and \\( -e atom -e token \\)\n>\n> And where is documentation update?\n\nHeh, real men do not do documentation ;-).\n\nI am going to bed now, and am hoping a kind soul would be\nsending out a patch while I am sleeping.\n"},{"id":"22911","messageId":"E1FwGgm-0006Nc-9a@moooo.ath.cx","threadId":"4668","inReplyTo":"7v3bdnkrfb.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-06-30T10:57:32Z","receivedAt":"2006-06-30T10:57:32Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Junio C Hamano wrote:\n> I see you are trying hard to think of a way to justify your\n> original prefix \"--and\" (or --FOO) implementation, but I simply\n> do not see much point in that.  I doubt changing the default\n> operator from --or to --and is less confusing than changing the\n> precedence for the users, so you would hear the same \"I\n> personally feel FOO should not even exist\" objection from me.\n\nIt just happens to make more sense to me and I don't see a reason not to\nadd this. If no one else is interested in this I'll just stop arguing :)\nHere again an overview of the arguments if anyone is interested:\n- Less to type for common searches using only AND (or more ANDs than\n  ORs).\n- Easy to implement (both with and without extended expressions).\n- AND/* is the normal implicit operator in other contexts than grep\n  (math).\n- The high precedence operator (AND) should be implicit rather than\n  the low precedence one (OR) (so this is only fulfilled when the\n  option is used).\n"},{"id":"22924","messageId":"E1FwKeN-000087-5x@moooo.ath.cx","threadId":"4668","inReplyTo":"7vsllnj6rh.fsf_-_@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] git-grep: boolean expression on pattern matching.","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-06-30T15:11:19Z","receivedAt":"2006-06-30T15:11:19Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"> This extends the behaviour of git-grep when multiple -e options\n> are given.  So far, we allowed multiple -e to behave just like\n> regular grep with multiple -e, i.e. the patterns are OR'ed\n> together.\n> \n> With this change, you can also have multiple patterns AND'ed\n> together, or form boolean expressions, like this (the\n> parentheses are quoted from the shell in this example):\n> \n> \t$ git grep -e _PATTERN --and \\( -e atom -e token \\)\nThis looks really nice. So for a few trivial tests it did not fail :)\n\nI noticed an unrelated bug. The context separators (\"--\") are missing\nbetween matches in different files:\n\n$ git-grep -e foobar -A 1 (this uses external grep)\nDocumentation/git-diff-tree.txt:I.e. \"foo\" does not pick up `foobar.h`.  \"foo\" does match `foo/bar.h`\nDocumentation/git-diff-tree.txt-so it can be used to name subdirectories.\n--\ngit-send-email.perl:#$initial_reply_to = ''; #<20050203173208.GA23964@foobar.com>';\ngit-send-email.perl-\n--\n[..]\n\n$ git-grep -e foobar -A 1 master (this is internal grep)\nmaster:Documentation/git-diff-tree.txt:I.e. \"foo\" does not pick up `foobar.h`.  \"foo\" does match `foo/bar.h`\nmaster:Documentation/git-diff-tree.txt-so it can be used to name subdirectories.\nmaster:git-send-email.perl:#$initial_reply_to = ''; #<20050203173208.GA23964@foobar.com>';\nmaster:git-send-email.perl-\n[..]\n\nI think this cannot be fixed in the loop in builtin-grep.c:grep_cache\nbecause after the last hit there should be no separator but it is not\nknown if a grep_sha1/grep_file will match and produce output. So I\nthink there has to be a variable passed down which tells those\nfunctions to print the separator before any other output.\n"},{"id":"22926","messageId":"7vejx6k54p.fsf@assigned-by-dhcp.cox.net","threadId":"4668","inReplyTo":"E1FwGgm-0006Nc-9a@moooo.ath.cx","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-06-30T15:57:58Z","receivedAt":"2006-06-30T15:57:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthias Lederhofer <matled@gmx.net> writes:\n\n> Junio C Hamano wrote:\n>> I see you are trying hard to think of a way to justify your\n>> original prefix \"--and\" (or --FOO) implementation, but I simply\n>> do not see much point in that.  I doubt changing the default\n>> operator from --or to --and is less confusing than changing the\n>> precedence for the users, so you would hear the same \"I\n>> personally feel FOO should not even exist\" objection from me.\n>\n> It just happens to make more sense to me and I don't see a reason not to\n> add this. If no one else is interested in this I'll just stop arguing :)\n> Here again an overview of the arguments if anyone is interested:\n> - Less to type for common searches using only AND (or more ANDs than\n>   ORs).\n> - Easy to implement (both with and without extended expressions).\n> - AND/* is the normal implicit operator in other contexts than grep\n>   (math).\n> - The high precedence operator (AND) should be implicit rather than\n>   the low precedence one (OR) (so this is only fulfilled when the\n>   option is used).\n\nSide note.  It would be interesting to have a slightly different\nform of --and called --near.  You would use it like this:\n\n\tgit grep -C -e AND --near -e OR\n\nto find lines that has AND on it, and within the context\ndistance there is a line that has OR on it.  The lines that are\nhit with such a query are still the ones that have AND on them\n(in other words, a line that has OR is used to further filter\nout the results so it will be prefixed with '-', not ':', unless\nthat line happens to also have AND on it).\n\nWith your syntax perhaps this is spelled as \"--near -C -e AND -e\nOR\".\n"},{"id":"22930","messageId":"E1FwMPf-0005XA-N9@moooo.ath.cx","threadId":"4668","inReplyTo":"7vejx6k54p.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-06-30T17:04:15Z","receivedAt":"2006-06-30T17:04:15Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"> Side note.  It would be interesting to have a slightly different\n> form of --and called --near.  You would use it like this:\n> \n> \tgit grep -C -e AND --near -e OR\n> \n> to find lines that has AND on it, and within the context\n> distance there is a line that has OR on it.  The lines that are\n> hit with such a query are still the ones that have AND on them\n> (in other words, a line that has OR is used to further filter\n> out the results so it will be prefixed with '-', not ':', unless\n> that line happens to also have AND on it).\nNice idea even though I don't now about practical importance but it\nsounds quite handy.  A few questions about this (some or all of those\nfeatures may make it quite complex):\n1. Should the context of near be the same as -[ABC] or perhaps\n   --near=N / --near=N:M (default could be the same as specified by\n   -[ABC]).\n2. Should it be possible to specify another boolean expression after\n   --near? e.g. --near ( -e foo --or ( -e bar --and -e baz )) to match\n   if the context contains foo or 'bar and baz'.\n3. Is --near just another subexpression? e.g. search for foo with\n   either A or B in the context:\n   -e foo --and ( --near A --or --near B )\n   This does not make sense without 1 and 2.\n\nWith some or all of those features quite mighty and complex\nexpressions can be build:\n-e A --and --near=3:-1 ( -e B --and --near=0:0 ( -e foo --and -e bar ) )\nThis could mean: find lines containing A and have B in any of the 3\nlines before A (without the line containing A). Additionally foo and\nbar have to be found on the same line before A.\n\nI'm really not asking for this, just telling about some ideas that\ncome to my mind for --near.\n\n> With your syntax perhaps this is spelled as \"--near -C -e AND -e\n> OR\".\nHuh? What do you mean by \"my syntax\"? The only thing different is the\noption to change the default operator to 'and'.\n\nWith the new extended expressions it would be really nice if git-grep\ncould also be used outside a git repository :)\n"},{"id":"22932","messageId":"7vpsgqimu7.fsf@assigned-by-dhcp.cox.net","threadId":"4668","inReplyTo":"E1FwMPf-0005XA-N9@moooo.ath.cx","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-06-30T17:18:24Z","receivedAt":"2006-06-30T17:18:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthias Lederhofer <matled@gmx.net> writes:\n\n> 1. Should the context of near be the same as -[ABC] or perhaps\n>    --near=N / --near=N:M (default could be the same as specified by\n>    -[ABC]).\n\nAs an end-user, I do not care either way.\n\n> 2. Should it be possible to specify another boolean expression after\n>    --near? e.g. --near ( -e foo --or ( -e bar --and -e baz )) to match\n>    if the context contains foo or 'bar and baz'.\n\nI would say why not.\n\n> 3. Is --near just another subexpression? e.g. search for foo with\n>    either A or B in the context:\n>    -e foo --and ( --near A --or --near B )\n>    This does not make sense without 1 and 2.\n\nAh, interesting.  I was thinking --near to be weaker form of --and,\nbut you made it to be a unary predicate (like --not).  That\nwould be neater.\n\n> With some or all of those features quite mighty and complex\n> expressions can be build:\n> -e A --and --near=3:-1 ( -e B --and --near=0:0 ( -e foo --and -e bar ) )\n> This could mean: find lines containing A and have B in any of the 3\n> lines before A (without the line containing A). Additionally foo and\n> bar have to be found on the same line before A.\n\nHaving said that, I suspect the above made-up example may not be\nso useful in practice.  I think a more realistic usage is \"I\nwant to find lines that contain `made-up' and `realistic' but\nthe paragraph might have been filled by the editor and they may\nbe found on separate nearby lines.  Instead of saying `-e\nmade-up --and -e realistic', I would say `-e made-up --near -e\nrealistic' to find what I want\".  That would find the first two\nlines of this paragraph, among others.\n\n> With the new extended expressions it would be really nice if git-grep\n> could also be used outside a git repository :)\n\nI am not sure about `outside' but it might be useful to extend\nthe working tree walker and glob filter used there to match what\nls-files uses so that it can do untracked files as well.\n"},{"id":"22933","messageId":"e83n97$973$1@sea.gmane.org","threadId":"4668","inReplyTo":"7vpsgqimu7.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-06-30T17:33:38Z","receivedAt":"2006-06-30T17:33:38Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano wrote:\n\n> Matthias Lederhofer <matled@gmx.net> writes:\n\n>> 3. Is --near just another subexpression? e.g. search for foo with\n>>    either A or B in the context:\n>>    -e foo --and ( --near A --or --near B )\n>>    This does not make sense without 1 and 2.\n> \n> Ah, interesting.  I was thinking --near to be weaker form of --and,\n> but you made it to be a unary predicate (like --not).  That\n> would be neater.\n\nI think --near _has_ to be non-symmetric binary operator, i.e. first\nargument specifies line to be found, second argument has to be in context\nfor first line if it is found.\n\nSo the above expression would be written as:\n\n  -e foo --near \\( A --or B \\)\n\n\nBTW. we can make -e equivalent to --or, and empty (default) operator to\n--and, but of course you have to delimit expression from files, i.e. either\n\n  git grep A B C D -- files\n\nor\n\n  git grep -e \\( A B C D \\) files\n\nwhich would be equivalent to\n\n  git grep A --and B --and C --and D files\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"22935","messageId":"E1FwN7M-0007GI-Ng@moooo.ath.cx","threadId":"4668","inReplyTo":"e83n97$973$1@sea.gmane.org","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-06-30T17:49:24Z","receivedAt":"2006-06-30T17:49:24Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Jakub Narebski wrote:\n> I think --near _has_ to be non-symmetric binary operator, i.e. first\n> argument specifies line to be found, second argument has to be in context\n> for first line if it is found.\n> \n> So the above expression would be written as:\n> \n>   -e foo --near \\( A --or B \\)\nWhy is that?\n-e foo --and --near \\( -e A -- or -e B \\)\nwould mean lines containing foo and either A or B in the context and\n-e foo --or  --near \\( -e A -- or -e B \\)\nwould mean lines containing foo or having A or B in the context.\n\n> BTW. we can make -e equivalent to --or, and empty (default) operator to\n> --and, but of course you have to delimit expression from files, i.e. either\n> \n>   git grep A B C D -- files\nThis is incompatible with the current implementation.\n'git grep A B C D -- files' means A is the pattern, B, C, D are\nrevisions and files is the pathspec.\n\n> or\n> \n>   git grep -e \\( A B C D \\) files\n> \n> which would be equivalent to\n> \n>   git grep A --and B --and C --and D files\nI think this could probably be used.  But I think having two different\nimplicit operators depending on the context is too confusing.\n"},{"id":"22936","messageId":"7vfyhmil07.fsf@assigned-by-dhcp.cox.net","threadId":"4668","inReplyTo":"E1FwN7M-0007GI-Ng@moooo.ath.cx","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-06-30T17:58:00Z","receivedAt":"2006-06-30T17:58:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthias Lederhofer <matled@gmx.net> writes:\n\n> -e foo --or  --near \\( -e A -- or -e B \\)\n> would mean lines containing foo or having A or B in the context.\n\nHow would that \"--near\" be useful?  You will see A or B either way.\n"},{"id":"22937","messageId":"e83p0q$dla$1@sea.gmane.org","threadId":"4668","inReplyTo":"E1FwN7M-0007GI-Ng@moooo.ath.cx","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-06-30T18:03:19Z","receivedAt":"2006-06-30T18:03:19Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Matthias Lederhofer wrote:\n\n> Jakub Narebski wrote:\n>> I think --near _has_ to be non-symmetric binary operator, i.e. first\n>> argument specifies line to be found, second argument has to be in context\n>> for first line if it is found.\n>> \n>> So the above expression would be written as:\n>> \n>>   -e foo --near \\( A --or B \\)\n> Why is that?\n>   -e foo --and --near \\( -e A --or -e B \\)\n> would mean lines containing foo and either A or B in the context and\n>   -e foo --or  --near \\( -e A --or -e B \\)\n> would mean lines containing foo or having A or B in the context.\n\nBecause --near needs an expression it check context for (context is for\nfound match of lhs expression). So\n\n  -e foo --near \\( -e A --or -e B \\)\n\nmeans lines containing foo and either A or B in the context _for \"foo\"_.\n\n--and --near could be shorthand for --and-near, and --or --near for\n--or-near... except that the second one doesn't have much sense:\n\nWhat is the difference between\n  -e foo --or --near \\( -e A --or -e B \\)\nand\n  -e foo --or \\( -e A --or -e B \\)\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"22939","messageId":"7v1wt6ik4x.fsf@assigned-by-dhcp.cox.net","threadId":"4668","inReplyTo":"e83p0q$dla$1@sea.gmane.org","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-06-30T18:16:46Z","receivedAt":"2006-06-30T18:16:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> writes:\n\n> Because --near needs an expression it check context for (context is for\n> found match of lhs expression). So\n>\n>   -e foo --near \\( -e A --or -e B \\)\n>\n> means lines containing foo and either A or B in the context _for \"foo\"_.\n\nThe syntax and semantics of --near I suggested (and you are\nfollowing) and what Matthias discusses are different and I think\nthat is why you two are talking past each other.\n\nWhat I originally suggested is that you can (syntactically)\nreplace --near with --and.  That is, the LHS is the match and\nRHS is \"the LHS must match, but in addition RHS must match but\nunlike --and RHS does not have to be exactly on the same line\nbut it is OK if it is a line somewhere nearby\".\n\nThe --near Matthias talk about is syntactically not like --and\nbut more like --not.  It takes a condition for a line after\nthat, and loosens it to cover nearby lines.  So \"-e A\"\nmeans \"the line must have A on it\" but \"--near -e A\" means \"the\nline must be nearby a line that satisfies `-e A'\".\n\nMatthias's \"--near EXP\" is spelled as \"-e '' --near EXP\" (the\nfirst one is always true) with our syntax, in other words.\n\nI do not think either of these semantics is invalid; they are\njust different.  The version by Matthias is more general and\nmore expressive.\n"},{"id":"22940","messageId":"E1FwNb7-0000BL-Ad@moooo.ath.cx","threadId":"4668","inReplyTo":"7vfyhmil07.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-06-30T18:20:09Z","receivedAt":"2006-06-30T18:20:09Z","isPatch":true,"sender":{"key":"matled@gmx.net","avatar":null},"body":"Junio C Hamano wrote:\n> Matthias Lederhofer <matled@gmx.net> writes:\n> \n> > -e foo --or  --near \\( -e A -- or -e B \\)\n> > would mean lines containing foo or having A or B in the context.\n> \n> How would that \"--near\" be useful?  You will see A or B either way.\nOk, this example was quite bad.\n\nIf --near is binary\n-e foo --and ( --near=3:0 -e A --or --near=0:3 -e B )\ncould not be done anymore, could it (without repeating the first\npattern)? (Find foo with A in the 3 lines before or B in the 3 lines\nafter the line.)\nWithout different contexts for multiple --near it probably does not\nmatter if --near is binary or unary.\n"},{"id":"22945","messageId":"e83t0m$4s0$2@sea.gmane.org","threadId":"4668","inReplyTo":"7v1wt6ik4x.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-06-30T19:11:31Z","receivedAt":"2006-06-30T19:11:31Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano wrote:\n\n> The --near Matthias talk about is syntactically not like --and\n> but more like --not.  It takes a condition for a line after\n> that, and loosens it to cover nearby lines.  So \"-e A\"\n> means \"the line must have A on it\" but \"--near -e A\" means \"the\n> line must be nearby a line that satisfies `-e A'\".\n> \n> Matthias's \"--near EXP\" is spelled as \"-e '' --near EXP\" (the\n> first one is always true) with our syntax, in other words.\n> \n> I do not think either of these semantics is invalid; they are\n> just different.  The version by Matthias is more general and\n> more expressive.\n\nIt also uses the fact that grep search for _lines_, the fact I have forgot\nabout. But if we cannot search for multiline regexp using git-grep,\nMatthias version is truly more expressive, especially with context limiting\nextension. \n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"22946","messageId":"7vmzbugzjz.fsf@assigned-by-dhcp.cox.net","threadId":"4668","inReplyTo":"e83t0m$4s0$2@sea.gmane.org","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-06-30T20:26:40Z","receivedAt":"2006-06-30T20:26:40Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> writes:\n\n> Matthias version is truly more expressive, especially with context limiting\n> extension. \n\nThat's orthogonal.  I do not think there is any reason you\ncannot make the version whose --near is similar to --and to\nunderstand different ranges for each \"neighbor search\"\nexpression using --near=M:N syntax.\n\nNow stop talking and code it up, please ;-).\n"},{"id":"23088","messageId":"44A8CD2E.8020208@op5.se","threadId":"4668","inReplyTo":"7vejx6k54p.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] git-grep: --and to combine patterns with and instead of or","fromName":"Andreas Ericsson","fromEmail":"ae@op5.se","sentAt":"2006-07-03T07:54:22Z","receivedAt":"2006-07-03T07:54:22Z","isPatch":true,"sender":{"key":"ae@op5.se","avatar":"https://gravatar.com/avatar/426e89595c75a8f5252dd0c989e5fabe5bcac616e68557427ad9aef6b0ca342a?d=mp&s=160"},"body":"Junio C Hamano wrote:\n> Matthias Lederhofer <matled@gmx.net> writes:\n> \n> \n>>Junio C Hamano wrote:\n>>\n>>>I see you are trying hard to think of a way to justify your\n>>>original prefix \"--and\" (or --FOO) implementation, but I simply\n>>>do not see much point in that.  I doubt changing the default\n>>>operator from --or to --and is less confusing than changing the\n>>>precedence for the users, so you would hear the same \"I\n>>>personally feel FOO should not even exist\" objection from me.\n>>\n>>It just happens to make more sense to me and I don't see a reason not to\n>>add this. If no one else is interested in this I'll just stop arguing :)\n>>Here again an overview of the arguments if anyone is interested:\n>>- Less to type for common searches using only AND (or more ANDs than\n>>  ORs).\n>>- Easy to implement (both with and without extended expressions).\n>>- AND/* is the normal implicit operator in other contexts than grep\n>>  (math).\n>>- The high precedence operator (AND) should be implicit rather than\n>>  the low precedence one (OR) (so this is only fulfilled when the\n>>  option is used).\n> \n> \n> Side note.  It would be interesting to have a slightly different\n> form of --and called --near.  You would use it like this:\n> \n> \tgit grep -C -e AND --near -e OR\n> \n> to find lines that has AND on it, and within the context\n> distance there is a line that has OR on it.  The lines that are\n> hit with such a query are still the ones that have AND on them\n> (in other words, a line that has OR is used to further filter\n> out the results so it will be prefixed with '-', not ':', unless\n> that line happens to also have AND on it).\n> \n\nIt would also be neat to have --inside main or some such, to make it \nonly check for things inside whatever's printed on the diff --git line.\n\n-- \nAndreas Ericsson                   andreas.ericsson@op5.se\nOP5 AB                             www.op5.se\nTel: +46 8-230225                  Fax: +46 8-230231\n"}]}