{"thread":{"id":"31164","subject":"[PATCH/RFC] grep: add a grep.patternType configuration setting","startedAt":"2012-08-01T18:29:41Z","lastAt":"2012-08-02T14:47:43Z","messageCount":5,"participants":["J Smith","Junio C Hamano","Štěpán Němec"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"196297","messageId":"1343845781-69246-1-git-send-email-dark.panda@gmail.com","threadId":"31164","inReplyTo":null,"subject":"[PATCH/RFC] grep: add a grep.patternType configuration setting","fromName":"J Smith","fromEmail":"dark.panda@gmail.com","sentAt":"2012-08-01T18:29:41Z","receivedAt":"2012-08-01T18:29:41Z","isPatch":true,"sender":{"key":"dark.panda@gmail.com","avatar":"https://avatars.githubusercontent.com/u/84783?v=4"},"body":"Adds the grep.patternType configuration setting which sets the default\npattern matching behavior. The values \"basic\", \"extended\", \"fixed\", and\n\"perl\" can be used to set \"--basic-regexp\", \"--extended-regexp\",\n\"--fixed-strings\", and \"--perl-regexp\" options by default respectively.\n\nA value of true is equivalent to \"extended\" as with grep.extendedRegexp,\nand a value of false leaves the pattern type as unspecified and follows\nthe default grep behavior.\n\nThis setting overrides the value set in grep.extendedRegexp which will\nbe ignored completely if grep.patternType is set.\n---\n Documentation/config.txt   |  11 ++-\n Documentation/git-grep.txt |  11 ++-\n builtin/grep.c             | 106 ++++++++++++++++---------\n grep.h                     |   9 +++\n t/t7810-grep.sh            | 187 +++++++++++++++++++++++++++++++++++++++++++++\n 5 files changed, 284 insertions(+), 40 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex a95e5a4..38d56d8 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -1210,8 +1210,17 @@ gitweb.snapshot::\n grep.lineNumber::\n \tIf set to true, enable '-n' option by default.\n\n+grep.patternType::\n+\tSets the default matching behavior. This option can be set to a\n+\tboolean value or one of 'basic', 'extended', 'fixed', or 'perl'\n+\twhich will enable the '--basic-regexp', '--extended-regexp',\n+\t'--fixed-strings' or '--perl-regexp' options accordingly. The value\n+\tof true is equivalent to 'extended' while false leaves the\n+\tsettings in their default state.\n+\n grep.extendedRegexp::\n-\tIf set to true, enable '--extended-regexp' option by default.\n+\tIf set to true, enable '--extended-regexp' option by default. This\n+\toption is ignored when the 'grep.patternType' option is set.\n\n gpg.program::\n \tUse this custom program instead of \"gpg\" found on $PATH when\ndiff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt\nindex 3bec036..f56f67f 100644\n--- a/Documentation/git-grep.txt\n+++ b/Documentation/git-grep.txt\n@@ -42,8 +42,17 @@ CONFIGURATION\n grep.lineNumber::\n \tIf set to true, enable '-n' option by default.\n\n+grep.patternType::\n+\tSets the default matching behavior. This option can be set to a\n+\tboolean value or one of 'basic', 'extended', 'fixed', or 'perl'\n+\twhich will enable the '--basic-regexp', '--extended-regexp',\n+\t'--fixed-strings' or '--perl-regexp' options accordingly. The value\n+\tof true is equivalent to 'extended' while false leaves the\n+\tsettings in their default state.\n+\n grep.extendedRegexp::\n-\tIf set to true, enable '--extended-regexp' option by default.\n+\tIf set to true, enable '--extended-regexp' option by default. This\n+\toption is ignored when the 'grep.patternType' option is set.\n\n\n OPTIONS\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 29adb0a..1de7e76 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -260,6 +260,55 @@ static int wait_all(void)\n }\n #endif\n\n+static int parse_pattern_type_arg(const char *opt, const char *arg)\n+{\n+\tswitch (git_config_maybe_bool(opt, arg)) {\n+\tcase 1:\n+\t\treturn GREP_PATTERN_TYPE_ERE;\n+\tcase 0:\n+\t\treturn GREP_PATTERN_TYPE_UNSPECIFIED;\n+\tdefault:\n+\t\tif (!strcmp(arg, \"basic\"))\n+\t\t\treturn GREP_PATTERN_TYPE_BRE;\n+\t\telse if (!strcmp(arg, \"extended\"))\n+\t\t\treturn GREP_PATTERN_TYPE_ERE;\n+\t\telse if (!strcmp(arg, \"fixed\"))\n+\t\t\treturn GREP_PATTERN_TYPE_FIXED;\n+\t\telse if (!strcmp(arg, \"perl\"))\n+\t\t\treturn GREP_PATTERN_TYPE_PCRE;\n+\t\tdie(\"bad %s argument: %s\", opt, arg);\n+\t}\n+}\n+\n+static void grep_pattern_type_options(const int pattern_type, struct grep_opt *opt)\n+{\n+\tswitch (pattern_type) {\n+\t\tcase GREP_PATTERN_TYPE_BRE:\n+\t\t\topt->fixed = 0;\n+\t\t\topt->pcre = 0;\n+\t\t\topt->regflags &= ~REG_EXTENDED;\n+\t\t\tbreak;\n+\n+\t\tcase GREP_PATTERN_TYPE_ERE:\n+\t\t\topt->fixed = 0;\n+\t\t\topt->pcre = 0;\n+\t\t\topt->regflags |= REG_EXTENDED;\n+\t\t\tbreak;\n+\n+\t\tcase GREP_PATTERN_TYPE_FIXED:\n+\t\t\topt->fixed = 1;\n+\t\t\topt->pcre = 0;\n+\t\t\topt->regflags &= ~REG_EXTENDED;\n+\t\t\tbreak;\n+\n+\t\tcase GREP_PATTERN_TYPE_PCRE:\n+\t\t\topt->fixed = 0;\n+\t\t\topt->pcre = 1;\n+\t\t\topt->regflags &= ~REG_EXTENDED;\n+\t\t\tbreak;\n+\t}\n+}\n+\n static int grep_config(const char *var, const char *value, void *cb)\n {\n \tstruct grep_opt *opt = cb;\n@@ -269,13 +318,21 @@ static int grep_config(const char *var, const char *value, void *cb)\n \t\treturn -1;\n\n \tif (!strcmp(var, \"grep.extendedregexp\")) {\n-\t\tif (git_config_bool(var, value))\n-\t\t\topt->regflags |= REG_EXTENDED;\n-\t\telse\n-\t\t\topt->regflags &= ~REG_EXTENDED;\n+\t\tif (!opt->pattern_type_used) {\n+\t\t\tif (git_config_bool(var, value))\n+\t\t\t\topt->regflags |= REG_EXTENDED;\n+\t\t\telse\n+\t\t\t\topt->regflags &= ~REG_EXTENDED;\n+\t\t}\n \t\treturn 0;\n \t}\n\n+\tif (!strcmp(var, \"grep.patterntype\")) {\n+\t\tgrep_pattern_type_options(parse_pattern_type_arg(var, value), opt);\n+\t\topt->pattern_type_used = 1;\n+\t\treturn 0;\n+  }\n+\n \tif (!strcmp(var, \"grep.linenumber\")) {\n \t\topt->linenum = git_config_bool(var, value);\n \t\treturn 0;\n@@ -669,14 +726,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n \tint i;\n \tint dummy;\n \tint use_index = 1;\n-\tenum {\n-\t\tpattern_type_unspecified = 0,\n-\t\tpattern_type_bre,\n-\t\tpattern_type_ere,\n-\t\tpattern_type_fixed,\n-\t\tpattern_type_pcre,\n-\t};\n-\tint pattern_type = pattern_type_unspecified;\n+\tint pattern_type = GREP_PATTERN_TYPE_UNSPECIFIED;\n\n \tstruct option options[] = {\n \t\tOPT_BOOLEAN(0, \"cached\", &cached,\n@@ -705,16 +755,16 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n \t\tOPT_GROUP(\"\"),\n \t\tOPT_SET_INT('E', \"extended-regexp\", &pattern_type,\n \t\t\t    \"use extended POSIX regular expressions\",\n-\t\t\t    pattern_type_ere),\n+\t\t\t    GREP_PATTERN_TYPE_ERE),\n \t\tOPT_SET_INT('G', \"basic-regexp\", &pattern_type,\n \t\t\t    \"use basic POSIX regular expressions (default)\",\n-\t\t\t    pattern_type_bre),\n+\t\t\t    GREP_PATTERN_TYPE_BRE),\n \t\tOPT_SET_INT('F', \"fixed-strings\", &pattern_type,\n \t\t\t    \"interpret patterns as fixed strings\",\n-\t\t\t    pattern_type_fixed),\n+\t\t\t    GREP_PATTERN_TYPE_FIXED),\n \t\tOPT_SET_INT('P', \"perl-regexp\", &pattern_type,\n \t\t\t    \"use Perl-compatible regular expressions\",\n-\t\t\t    pattern_type_pcre),\n+\t\t\t    GREP_PATTERN_TYPE_PCRE),\n \t\tOPT_GROUP(\"\"),\n \t\tOPT_BOOLEAN('n', \"line-number\", &opt.linenum, \"show line numbers\"),\n \t\tOPT_NEGBIT('h', NULL, &opt.pathname, \"don't show filenames\", 1),\n@@ -824,28 +874,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n \t\t\t     PARSE_OPT_KEEP_DASHDASH |\n \t\t\t     PARSE_OPT_STOP_AT_NON_OPTION |\n \t\t\t     PARSE_OPT_NO_INTERNAL_HELP);\n-\tswitch (pattern_type) {\n-\tcase pattern_type_fixed:\n-\t\topt.fixed = 1;\n-\t\topt.pcre = 0;\n-\t\tbreak;\n-\tcase pattern_type_bre:\n-\t\topt.fixed = 0;\n-\t\topt.pcre = 0;\n-\t\topt.regflags &= ~REG_EXTENDED;\n-\t\tbreak;\n-\tcase pattern_type_ere:\n-\t\topt.fixed = 0;\n-\t\topt.pcre = 0;\n-\t\topt.regflags |= REG_EXTENDED;\n-\t\tbreak;\n-\tcase pattern_type_pcre:\n-\t\topt.fixed = 0;\n-\t\topt.pcre = 1;\n-\t\tbreak;\n-\tdefault:\n-\t\tbreak; /* nothing */\n-\t}\n+\n+\tgrep_pattern_type_options(pattern_type, &opt);\n\n \tif (use_index && !startup_info->have_repository)\n \t\t/* die the same way as if we did it at the beginning */\ndiff --git a/grep.h b/grep.h\nindex ed7de6b..9a6cdde 100644\n--- a/grep.h\n+++ b/grep.h\n@@ -58,6 +58,14 @@ enum grep_expr_node {\n \tGREP_NODE_OR\n };\n\n+enum grep_pattern_type {\n+\tGREP_PATTERN_TYPE_UNSPECIFIED = 0,\n+\tGREP_PATTERN_TYPE_BRE,\n+\tGREP_PATTERN_TYPE_ERE,\n+\tGREP_PATTERN_TYPE_FIXED,\n+\tGREP_PATTERN_TYPE_PCRE\n+};\n+\n struct grep_expr {\n \tenum grep_expr_node node;\n \tunsigned hit;\n@@ -103,6 +111,7 @@ struct grep_opt {\n \tint max_depth;\n \tint funcname;\n \tint funcbody;\n+\tint pattern_type_used;\n \tchar color_context[COLOR_MAXLEN];\n \tchar color_filename[COLOR_MAXLEN];\n \tchar color_function[COLOR_MAXLEN];\ndiff --git a/t/t7810-grep.sh b/t/t7810-grep.sh\nindex 523d041..4fa24b4 100755\n--- a/t/t7810-grep.sh\n+++ b/t/t7810-grep.sh\n@@ -245,11 +245,41 @@ do\n \t\ttest_cmp expected actual\n \t'\n\n+\ttest_expect_success \"grep $L with grep.patternType=false\" '\n+\t\techo \"ab:a+bc\" >expected &&\n+\t\tgit -c grep.patternType=false grep \"a+b*c\" ab >actual &&\n+\t\ttest_cmp expected actual\n+\t'\n+\n \ttest_expect_success \"grep $L with grep.extendedRegexp=true\" '\n \t\techo \"ab:abc\" >expected &&\n \t\tgit -c grep.extendedRegexp=true grep \"a+b*c\" ab >actual &&\n \t\ttest_cmp expected actual\n \t'\n+\n+\ttest_expect_success \"grep $L with grep.patternType=true\" '\n+\t\techo \"ab:abc\" >expected &&\n+\t\tgit -c grep.patternType=true grep \"a+b*c\" ab >actual &&\n+\t\ttest_cmp expected actual\n+\t'\n+\n+\ttest_expect_success \"grep $L with grep.patternType=false and grep.extendedRegexp=true\" '\n+\t\techo \"ab:a+bc\" >expected &&\n+\t\tgit \\\n+\t\t\t-c grep.patternType=false \\\n+\t\t\t-c grep.extendedRegexp=true \\\n+\t\t\tgrep \"a+b*c\" ab >actual &&\n+\t\ttest_cmp expected actual\n+\t'\n+\n+\ttest_expect_success \"grep $L with grep.patternType=true and grep.extendedRegexp=false\" '\n+\t\techo \"ab:abc\" >expected &&\n+\t\tgit \\\n+\t\t\t-c grep.patternType=true \\\n+\t\t\t-c grep.extendedRegexp=false \\\n+\t\t\tgrep \"a+b*c\" ab >actual &&\n+\t\ttest_cmp expected actual\n+\t'\n done\n\n cat >expected <<EOF\n@@ -725,12 +755,43 @@ test_expect_success 'grep pattern with grep.extendedRegexp=true' '\n \ttest_cmp empty actual\n '\n\n+test_expect_success 'grep pattern with grep.patternType=true' '\n+\t>empty &&\n+\ttest_must_fail git -c grep.patternType=true \\\n+\t\tgrep \"\\p{Ps}.*?\\p{Pe}\" hello.c >actual &&\n+\ttest_cmp empty actual\n+'\n+\n+test_expect_success 'grep pattern with grep.patternType=basic and grep.extendedRegexp=true' '\n+\t>empty &&\n+\ttest_must_fail git \\\n+\t\t-c grep.patterntype=basic \\\n+\t\t-c grep.extendedregexp=true \\\n+\t\tgrep \"a?\" hello.c >actual &&\n+\ttest_cmp empty actual\n+'\n+\n+test_expect_success 'grep pattern with grep.patternType=false and grep.extendedRegexp=true' '\n+\t>empty &&\n+\ttest_must_fail git \\\n+\t\t-c grep.patterntype=false \\\n+\t\t-c grep.extendedregexp=true \\\n+\t\tgrep \"a?\" hello.c >actual &&\n+\ttest_cmp empty actual\n+'\n+\n test_expect_success LIBPCRE 'grep -P pattern with grep.extendedRegexp=true' '\n \tgit -c grep.extendedregexp=true \\\n \t\tgrep -P \"\\p{Ps}.*?\\p{Pe}\" hello.c >actual &&\n \ttest_cmp expected actual\n '\n\n+test_expect_success LIBPCRE 'grep pattern with grep.patternType=perl' '\n+\tgit -c grep.patternType=perl \\\n+\t\tgrep -P \"\\p{Ps}.*?\\p{Pe}\" hello.c >actual &&\n+\ttest_cmp expected actual\n+'\n+\n test_expect_success LIBPCRE 'grep -P -v pattern' '\n \t{\n \t\techo \"ab:a+b*c\"\n@@ -761,44 +822,170 @@ test_expect_success 'grep -G invalidpattern properly dies ' '\n \ttest_must_fail git grep -G \"a[\"\n '\n\n+test_expect_success 'grep invalidpattern properly dies with grep.patternType=basic' '\n+\ttest_must_fail git -c patterntype=basic grep \"a[\"\n+'\n+\n test_expect_success 'grep -E invalidpattern properly dies ' '\n \ttest_must_fail git grep -E \"a[\"\n '\n\n+test_expect_success 'grep invalidpattern properly dies with grep.patternType=extended' '\n+\ttest_must_fail git -c patterntype=extended grep \"a[\"\n+'\n+\n test_expect_success LIBPCRE 'grep -P invalidpattern properly dies ' '\n \ttest_must_fail git grep -P \"a[\"\n '\n\n+test_expect_success LIBPCRE 'grep invalidpattern properly dies with grep.patternType=perl' '\n+\ttest_must_fail git -c patterntype=perl grep \"a[\"\n+'\n+\n test_expect_success 'grep -G -E -F pattern' '\n \techo \"ab:a+b*c\" >expected &&\n \tgit grep -G -E -F \"a+b*c\" ab >actual &&\n \ttest_cmp expected actual\n '\n\n+test_expect_success 'grep pattern with grep.patternType=basic, =extended, =fixed' '\n+\techo \"ab:a+b*c\" >expected &&\n+\tgit \\\n+\t\t-c grep.patterntype=basic \\\n+\t\t-c grep.patterntype=extended \\\n+\t\t-c grep.patterntype=fixed \\\n+\t\tgrep \"a+b*c\" ab >actual &&\n+\ttest_cmp expected actual\n+'\n+\n test_expect_success 'grep -E -F -G pattern' '\n \techo \"ab:a+bc\" >expected &&\n \tgit grep -E -F -G \"a+b*c\" ab >actual &&\n \ttest_cmp expected actual\n '\n\n+test_expect_success 'grep pattern with grep.patternType=extended, =fixed, =basic' '\n+\techo \"ab:a+bc\" >expected &&\n+\tgit \\\n+\t\t-c grep.patterntype=extended \\\n+\t\t-c grep.patterntype=fixed \\\n+\t\t-c grep.patterntype=basic \\\n+\t\tgrep \"a+b*c\" ab >actual &&\n+\ttest_cmp expected actual\n+'\n+\n test_expect_success 'grep -F -G -E pattern' '\n \techo \"ab:abc\" >expected &&\n \tgit grep -F -G -E \"a+b*c\" ab >actual &&\n \ttest_cmp expected actual\n '\n\n+test_expect_success 'grep pattern with grep.patternType=fixed, =basic, =extended' '\n+\techo \"ab:abc\" >expected &&\n+\tgit \\\n+\t\t-c grep.patterntype=fixed \\\n+\t\t-c grep.patterntype=basic \\\n+\t\t-c grep.patterntype=extended \\\n+\t\tgrep \"a+b*c\" ab >actual &&\n+\ttest_cmp expected actual\n+'\n+\n test_expect_success 'grep -G -F -P -E pattern' '\n \t>empty &&\n \ttest_must_fail git grep -G -F -P -E \"a\\x{2b}b\\x{2a}c\" ab >actual &&\n \ttest_cmp empty actual\n '\n\n+test_expect_success 'grep pattern with grep.patternType=fixed, =basic, =perl, =extended' '\n+\t>empty &&\n+\ttest_must_fail git \\\n+\t\t-c grep.patterntype=fixed \\\n+\t\t-c grep.patterntype=basic \\\n+\t\t-c grep.patterntype=perl \\\n+\t\t-c grep.patterntype=extended \\\n+\t\tgrep \"a\\x{2b}b\\x{2a}c\" ab >actual &&\n+\ttest_cmp empty actual\n+'\n+\n test_expect_success LIBPCRE 'grep -G -F -E -P pattern' '\n \techo \"ab:a+b*c\" >expected &&\n \tgit grep -G -F -E -P \"a\\x{2b}b\\x{2a}c\" ab >actual &&\n \ttest_cmp expected actual\n '\n\n+test_expect_success LIBPCRE 'grep pattern with grep.patternType=fixed, =basic, =extended, =perl' '\n+\techo \"ab:a+b*c\" >expected &&\n+\tgit \\\n+\t\t-c grep.patterntype=fixed \\\n+\t\t-c grep.patterntype=basic \\\n+\t\t-c grep.patterntype=extended \\\n+\t\t-c grep.patterntype=perl \\\n+\t\tgrep \"a\\x{2b}b\\x{2a}c\" ab >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success LIBPCRE 'grep -P pattern with grep.patternType=fixed, =basic, =extended' '\n+\techo \"ab:a+b*c\" >expected &&\n+\tgit \\\n+\t\t-c grep.patterntype=fixed \\\n+\t\t-c grep.patterntype=basic \\\n+\t\t-c grep.patterntype=extended \\\n+\t\t-c grep.patterntype=perl \\\n+\t\tgrep -P \"a\\x{2b}b\\x{2a}c\" ab >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'grep -F pattern with grep.patternType=fixed, =basic, =extended, =perl' '\n+\techo \"ab:a+b*c\" >expected &&\n+\tgit \\\n+\t\t-c grep.patterntype=fixed \\\n+\t\t-c grep.patterntype=basic \\\n+\t\t-c grep.patterntype=extended \\\n+\t\t-c grep.patterntype=perl \\\n+\t\tgrep -F \"*c\" ab >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'grep -G pattern with grep.patternType=fixed, =basic, =extended, =perl' '\n+\t{\n+\t\techo \"ab:a+b*c\"\n+\t\techo \"ab:a+bc\"\n+\t} >expected &&\n+\tgit \\\n+\t\t-c grep.patterntype=fixed \\\n+\t\t-c grep.patterntype=basic \\\n+\t\t-c grep.patterntype=extended \\\n+\t\t-c grep.patterntype=perl \\\n+\t\tgrep -G \"a+b\" ab >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'grep -E pattern with grep.patternType=fixed, =basic, =extended, =perl' '\n+\t{\n+\t\techo \"ab:a+b*c\"\n+\t\techo \"ab:a+bc\"\n+\t\techo \"ab:abc\"\n+\t} >expected &&\n+\tgit \\\n+\t\t-c grep.patterntype=fixed \\\n+\t\t-c grep.patterntype=basic \\\n+\t\t-c grep.patterntype=extended \\\n+\t\t-c grep.patterntype=perl \\\n+\t\tgrep -E \"a+\" ab >actual &&\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'grep pattern with grep.patternType=extended and grep.extendedRegexp=false' '\n+\tcat >expected <<-EOF\n+\thello.c:int main(int argc, const char **argv)\n+\tEOF\n+\tgit \\\n+\t\t-c grep.patterntype=extended \\\n+\t\t-c grep.extendedregexp=false \\\n+\t\tgrep \"con?st\" hello.c >actual &&\n+\ttest_cmp expected actual\n+'\n+\n test_config() {\n \tgit config \"$1\" \"$2\" &&\n \ttest_when_finished \"git config --unset $1\"\n--\n1.7.11.3\n"},{"id":"196311","messageId":"7vpq7ae0pj.fsf@alter.siamese.dyndns.org","threadId":"31164","inReplyTo":"1343845781-69246-1-git-send-email-dark.panda@gmail.com","subject":"Re: [PATCH/RFC] grep: add a grep.patternType configuration setting","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-08-01T21:55:52Z","receivedAt":"2012-08-01T21:55:52Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"J Smith <dark.panda@gmail.com> writes:\n\nAs the basic structure and the direction looks good, let's start\nnitpicking ;-)\n\n> Adds the grep.patternType configuration setting which sets the default\n> pattern matching behavior. The values \"basic\", \"extended\", \"fixed\", and\n> \"perl\" can be used to set \"--basic-regexp\", \"--extended-regexp\",\n> \"--fixed-strings\", and \"--perl-regexp\" options by default respectively.\n\nWe tend to write the commit log message in imperative mood, as if\nyou are giving an order to the codebase to \"behave this way!\".  Also\nwe tend to give the justification behind the change first and then\npresent the solution.\n\n\tThere is grep.extendedRegexp configuration variable to\n\tenable the -E command line flag by default, but there is no\n\tequivalent for the -P (pcre) flag.  We could keep adding\n\tgrep.fooRegexp variables for different regular expression\n\tvariants, but that will be unwieldy.\n\n\tInstead, add a \"grep.patternType\" variable that can be set\n\tto \"basic\", \"extended\", \"fixed\" and \"perl\" to use\n\t\"--basic-regexp\", \"--extended-regexp\", \"--fixed-strings\",\n\tand \"--perl-regexp\" options by default respectively.\n\n\tIgnore grep.extendedRegexp when grep.patternType is set.\n\n> A value of true is equivalent to \"extended\" as with grep.extendedRegexp,\n> and a value of false leaves the pattern type as unspecified and follows\n> the default grep behavior.\n\nWith this round, we are not updating an existing a bool variable,\nbut are introducing a brand new one; does it still make sense to\nsupport the boolean values for this new variable?\n\n> This setting overrides the value set in grep.extendedRegexp which will\n> be ignored completely if grep.patternType is set.\n> ---\n\nSign-off?\n\n>  Documentation/config.txt   |  11 ++-\n>  Documentation/git-grep.txt |  11 ++-\n>  builtin/grep.c             | 106 ++++++++++++++++---------\n>  grep.h                     |   9 +++\n>  t/t7810-grep.sh            | 187 +++++++++++++++++++++++++++++++++++++++++++++\n>  5 files changed, 284 insertions(+), 40 deletions(-)\n>\n> diff --git a/Documentation/config.txt b/Documentation/config.txt\n> index a95e5a4..38d56d8 100644\n> --- a/Documentation/config.txt\n> +++ b/Documentation/config.txt\n> @@ -1210,8 +1210,17 @@ gitweb.snapshot::\n>  grep.lineNumber::\n>  \tIf set to true, enable '-n' option by default.\n>\n> +grep.patternType::\n> +\tSets the default matching behavior. This option can be set to a\n> +\tboolean value or one of 'basic', 'extended', 'fixed', or 'perl'\n> +\twhich will enable the '--basic-regexp', '--extended-regexp',\n> +\t'--fixed-strings' or '--perl-regexp' options accordingly. The value\n> +\tof true is equivalent to 'extended' while false leaves the\n> +\tsettings in their default state.\n\nPerhaps s/Sets the/The/ or at least s/Sets/Set/ (notice that the\ndescription for grep.extendedRegexp says \"enable foo\", not \"enables\nfoo\").\n\nThe same comment as above applies to the \"boolean\"-ness part.\n\n>  grep.extendedRegexp::\n> -\tIf set to true, enable '--extended-regexp' option by default.\n> +\tIf set to true, enable '--extended-regexp' option by default. This\n> +\toption is ignored when the 'grep.patternType' option is set.\n\nWe are not going to make grep.patternType a boolean, so \"when ... is\nset\" is fine, but if we were to allow grep.patternType to be set to\n\"false\", the description gives ambiguity to some readers who do.\nPerhaps s/is set/is given/ is safer.\n\n> diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt\n> index 3bec036..f56f67f 100644\n> --- a/Documentation/git-grep.txt\n> +++ b/Documentation/git-grep.txt\n> @@ -42,8 +42,17 @@ CONFIGURATION\n>  grep.lineNumber::\n>  \tIf set to true, enable '-n' option by default.\n>\n> +grep.patternType::\n> ...\n>  grep.extendedRegexp::\n> -\tIf set to true, enable '--extended-regexp' option by default.\n> +\tIf set to true, enable '--extended-regexp' option by default. This\n> +\toption is ignored when the 'grep.patternType' option is set.\n\nLikewise.\n\n> diff --git a/builtin/grep.c b/builtin/grep.c\n> index 29adb0a..1de7e76 100644\n> --- a/builtin/grep.c\n> +++ b/builtin/grep.c\n> @@ -260,6 +260,55 @@ static int wait_all(void)\n>  }\n>  #endif\n>\n> +static int parse_pattern_type_arg(const char *opt, const char *arg)\n> +{\n> +\tswitch (git_config_maybe_bool(opt, arg)) {\n> +\tcase 1:\n> +\t\treturn GREP_PATTERN_TYPE_ERE;\n> +\tcase 0:\n> +\t\treturn GREP_PATTERN_TYPE_UNSPECIFIED;\n> +\tdefault:\n> +\t\tif (!strcmp(arg, \"basic\"))\n> +\t\t\treturn GREP_PATTERN_TYPE_BRE;\n> +\t\telse if (!strcmp(arg, \"extended\"))\n> +\t\t\treturn GREP_PATTERN_TYPE_ERE;\n> +\t\telse if (!strcmp(arg, \"fixed\"))\n> +\t\t\treturn GREP_PATTERN_TYPE_FIXED;\n> +\t\telse if (!strcmp(arg, \"perl\"))\n> +\t\t\treturn GREP_PATTERN_TYPE_PCRE;\n> +\t\tdie(\"bad %s argument: %s\", opt, arg);\n> +\t}\n\nLet's not do maybe-bool, as we are not upgrading an old bool-only\nvariable any more.\n\n> +static void grep_pattern_type_options(const int pattern_type, struct grep_opt *opt)\n> +{\n> +\tswitch (pattern_type) {\n> +\t\tcase GREP_PATTERN_TYPE_BRE:\n> +\t\t\topt->fixed = 0;\n> ...\n> +\t\t\tbreak;\n> +\t}\n\nPlease de-dent these lines inside switch() one level; switch and\ncase align.\n\n> diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh\n> index 523d041..4fa24b4 100755\n> --- a/t/t7810-grep.sh\n> +++ b/t/t7810-grep.sh\n> @@ -245,11 +245,41 @@ do\n>  \t\ttest_cmp expected actual\n>  \t'\n>\n> +\ttest_expect_success \"grep $L with grep.patternType=false\" '\n> +\t\techo \"ab:a+bc\" >expected &&\n> +\t\tgit -c grep.patternType=false grep \"a+b*c\" ab >actual &&\n> +\t\ttest_cmp expected actual\n> +\t'\n> +\n>  \ttest_expect_success \"grep $L with grep.extendedRegexp=true\" '\n>  \t\techo \"ab:abc\" >expected &&\n>  \t\tgit -c grep.extendedRegexp=true grep \"a+b*c\" ab >actual &&\n>  \t\ttest_cmp expected actual\n>  \t'\n> +\n> +\ttest_expect_success \"grep $L with grep.patternType=true\" '\n> +\t\techo \"ab:abc\" >expected &&\n> +\t\tgit -c grep.patternType=true grep \"a+b*c\" ab >actual &&\n> +\t\ttest_cmp expected actual\n> +\t'\n> +\n> +\ttest_expect_success \"grep $L with grep.patternType=false and grep.extendedRegexp=true\" '\n> +\t\techo \"ab:a+bc\" >expected &&\n> +\t\tgit \\\n> +\t\t\t-c grep.patternType=false \\\n> +\t\t\t-c grep.extendedRegexp=true \\\n> +\t\t\tgrep \"a+b*c\" ab >actual &&\n> +\t\ttest_cmp expected actual\n> +\t'\n> +\n> +\ttest_expect_success \"grep $L with grep.patternType=true and grep.extendedRegexp=false\" '\n> +\t\techo \"ab:abc\" >expected &&\n> +\t\tgit \\\n> +\t\t\t-c grep.patternType=true \\\n> +\t\t\t-c grep.extendedRegexp=false \\\n> +\t\t\tgrep \"a+b*c\" ab >actual &&\n> +\t\ttest_cmp expected actual\n> +\t'\n\nIt might make sense to also make sure the order in which the\nconfiguration variables are given does not make a difference with\nthese tests.\n\n> @@ -725,12 +755,43 @@ test_expect_success 'grep pattern with grep.extendedRegexp=true' '\n>  \ttest_cmp empty actual\n>  '\n>\n> +test_expect_success 'grep pattern with grep.patternType=true' '\n> +\t>empty &&\n> +\ttest_must_fail git -c grep.patternType=true \\\n> +\t\tgrep \"\\p{Ps}.*?\\p{Pe}\" hello.c >actual &&\n> +\ttest_cmp empty actual\n> +'\n\nWhen told to use basic-regexp, PCRE should not be used.  Good.\n\n> +test_expect_success 'grep pattern with grep.patternType=basic and grep.extendedRegexp=true' '\n> +\t>empty &&\n> +\ttest_must_fail git \\\n> +\t\t-c grep.patterntype=basic \\\n> +\t\t-c grep.extendedregexp=true \\\n> +\t\tgrep \"a?\" hello.c >actual &&\n> +\ttest_cmp empty actual\n> +'\n\nWhen told to use basic-regexp via patternType, extendedRegexp should\nnot be used.  Good.\n\n> +\n> +test_expect_success 'grep pattern with grep.patternType=false and grep.extendedRegexp=true' '\n> +\t>empty &&\n> +\ttest_must_fail git \\\n> +\t\t-c grep.patterntype=false \\\n> +\t\t-c grep.extendedregexp=true \\\n> +\t\tgrep \"a?\" hello.c >actual &&\n> +\ttest_cmp empty actual\n> +'\n\nWith the removal of \"bool-or-type\", this will become redundant.\n\n>  test_expect_success LIBPCRE 'grep -P pattern with grep.extendedRegexp=true' '\n>  \tgit -c grep.extendedregexp=true \\\n>  \t\tgrep -P \"\\p{Ps}.*?\\p{Pe}\" hello.c >actual &&\n>  \ttest_cmp expected actual\n>  '\n>\n> +test_expect_success LIBPCRE 'grep pattern with grep.patternType=perl' '\n> +\tgit -c grep.patternType=perl \\\n> +\t\tgrep -P \"\\p{Ps}.*?\\p{Pe}\" hello.c >actual &&\n> +\ttest_cmp expected actual\n> +'\n\nWhat does this test?  grep.patternType=perl configuration is\ncorrectly overridden by a command line flag -P?  But you cannot tell\nwhich one turned pcre with this test.  Drop -P from the command\nline, perhaps?\n\nYou want a test that runs \"git -c grep.patternType=basic grep -P\" or\nsomething, guarded with LIBPCRE prerequisite, to make sure pcre\npatterns are used because command line -P trumps over configured\ndefault, too.\n\n> @@ -761,44 +822,170 @@ test_expect_success 'grep -G invalidpattern properly dies ' '\n>  \ttest_must_fail git grep -G \"a[\"\n>  '\n>\n> +test_expect_success 'grep invalidpattern properly dies with grep.patternType=basic' '\n> +\ttest_must_fail git -c patterntype=basic grep \"a[\"\n> +'\n> +\n>  test_expect_success 'grep -E invalidpattern properly dies ' '\n>  \ttest_must_fail git grep -E \"a[\"\n>  '\n>\n> +test_expect_success 'grep invalidpattern properly dies with grep.patternType=extended' '\n> +\ttest_must_fail git -c patterntype=extended grep \"a[\"\n> +'\n> +\n>  test_expect_success LIBPCRE 'grep -P invalidpattern properly dies ' '\n>  \ttest_must_fail git grep -P \"a[\"\n>  '\n>\n> +test_expect_success LIBPCRE 'grep invalidpattern properly dies with grep.patternType=perl' '\n> +\ttest_must_fail git -c patterntype=perl grep \"a[\"\n> +'\n> +\n\nThese three may not add much value, as long as we make sure that the\nconfiguration \"-c grep.patterntype\" triggers the pattern matching\nbackend just like command line flags do with other tests.\n\nBesides, I do not think you are testing the right thing in them\nanyway (notice the lack of \"grep.\" prefix).\n\n> +test_expect_success 'grep pattern with grep.patternType=basic, =extended, =fixed' '\n> +\techo \"ab:a+b*c\" >expected &&\n> +\tgit \\\n> +\t\t-c grep.patterntype=basic \\\n> +\t\t-c grep.patterntype=extended \\\n> +\t\t-c grep.patterntype=fixed \\\n> +\t\tgrep \"a+b*c\" ab >actual &&\n> +\ttest_cmp expected actual\n> +'\n\nWhat does this test?  The last one wins?\n\nFor the command line flags, people can do \"alias g 'git grep -E'\"\nand then countermand the flags in the alias by appending a\ncontradicting flag when using it, e.g. \"g -G\", last one wins is a\ndefined and useful semantics, but for configuration variables that\nare meant to take a single value, I do not think we give such a\nstrong guarantee on ordering (it may happen to work by accident,\nthough).\n\nI would _not_ strongly suggest removing this test, but instead wait\nuntil we hear from others, as they may disagree.\n\n>  test_expect_success 'grep -E -F -G pattern' '\n>  \techo \"ab:a+bc\" >expected &&\n>  \tgit grep -E -F -G \"a+b*c\" ab >actual &&\n>  \ttest_cmp expected actual\n>  '\n>\n> +test_expect_success 'grep pattern with grep.patternType=extended, =fixed, =basic' '\n> +\techo \"ab:a+bc\" >expected &&\n> +\tgit \\\n> +\t\t-c grep.patterntype=extended \\\n> +\t\t-c grep.patterntype=fixed \\\n> +\t\t-c grep.patterntype=basic \\\n> +\t\tgrep \"a+b*c\" ab >actual &&\n> +\ttest_cmp expected actual\n> +'\n> +\n\nLikewise.\n\n>  test_expect_success 'grep -F -G -E pattern' '\n>  \techo \"ab:abc\" >expected &&\n>  \tgit grep -F -G -E \"a+b*c\" ab >actual &&\n>  \ttest_cmp expected actual\n>  '\n>\n> +test_expect_success 'grep pattern with grep.patternType=fixed, =basic, =extended' '\n> +\techo \"ab:abc\" >expected &&\n> +\tgit \\\n> +\t\t-c grep.patterntype=fixed \\\n> +\t\t-c grep.patterntype=basic \\\n> +\t\t-c grep.patterntype=extended \\\n> +\t\tgrep \"a+b*c\" ab >actual &&\n> +\ttest_cmp expected actual\n> +'\n\nLikewise.\n\n>  test_expect_success 'grep -G -F -P -E pattern' '\n>  \t>empty &&\n>  \ttest_must_fail git grep -G -F -P -E \"a\\x{2b}b\\x{2a}c\" ab >actual &&\n>  \ttest_cmp empty actual\n>  '\n>\n> +test_expect_success 'grep pattern with grep.patternType=fixed, =basic, =perl, =extended' '\n> +\t>empty &&\n> +\ttest_must_fail git \\\n> +\t\t-c grep.patterntype=fixed \\\n> +\t\t-c grep.patterntype=basic \\\n> +\t\t-c grep.patterntype=perl \\\n> +\t\t-c grep.patterntype=extended \\\n> +\t\tgrep \"a\\x{2b}b\\x{2a}c\" ab >actual &&\n> +\ttest_cmp empty actual\n> +'\n\nLikewise.\n\n>  test_expect_success LIBPCRE 'grep -G -F -E -P pattern' '\n>  \techo \"ab:a+b*c\" >expected &&\n>  \tgit grep -G -F -E -P \"a\\x{2b}b\\x{2a}c\" ab >actual &&\n>  \ttest_cmp expected actual\n>  '\n>\n> +test_expect_success LIBPCRE 'grep pattern with grep.patternType=fixed, =basic, =extended, =perl' '\n> +\techo \"ab:a+b*c\" >expected &&\n> +\tgit \\\n> +\t\t-c grep.patterntype=fixed \\\n> +\t\t-c grep.patterntype=basic \\\n> +\t\t-c grep.patterntype=extended \\\n> +\t\t-c grep.patterntype=perl \\\n> +\t\tgrep \"a\\x{2b}b\\x{2a}c\" ab >actual &&\n> +\ttest_cmp expected actual\n> +'\n\nLikewise.\n\n> +test_expect_success LIBPCRE 'grep -P pattern with grep.patternType=fixed, =basic, =extended' '\n> +\techo \"ab:a+b*c\" >expected &&\n> +\tgit \\\n> +\t\t-c grep.patterntype=fixed \\\n> +\t\t-c grep.patterntype=basic \\\n> +\t\t-c grep.patterntype=extended \\\n> +\t\t-c grep.patterntype=perl \\\n> +\t\tgrep -P \"a\\x{2b}b\\x{2a}c\" ab >actual &&\n> +\ttest_cmp expected actual\n> +'\n\nAs you are expecting the \"last one wins\" behaviour among\nconfiguration variables, running a test with -P option would not let\nyou catch bugs coming from potentially screwed-up precedence between\nthe configuration and command line flags, would it?  At least, leave\nthe \"-c grep.patterntype=perl\" out from here to make sure what the\nvariable and the flag tell the command conflict with each other.  I\nwould also prefer to see only one \"-c grep.patterntype=<foo>\" used.\n\n> +test_expect_success 'grep -F pattern with grep.patternType=fixed, =basic, =extended, =perl' '\n> +\techo \"ab:a+b*c\" >expected &&\n> +\tgit \\\n> +\t\t-c grep.patterntype=fixed \\\n> +\t\t-c grep.patterntype=basic \\\n> +\t\t-c grep.patterntype=extended \\\n> +\t\t-c grep.patterntype=perl \\\n> +\t\tgrep -F \"*c\" ab >actual &&\n> +\ttest_cmp expected actual\n> +'\n\nLikewise.\n\n> +test_expect_success 'grep -G pattern with grep.patternType=fixed, =basic, =extended, =perl' '\n> +\t{\n> +\t\techo \"ab:a+b*c\"\n> +\t\techo \"ab:a+bc\"\n> +\t} >expected &&\n> +\tgit \\\n> +\t\t-c grep.patterntype=fixed \\\n> +\t\t-c grep.patterntype=basic \\\n> +\t\t-c grep.patterntype=extended \\\n> +\t\t-c grep.patterntype=perl \\\n> +\t\tgrep -G \"a+b\" ab >actual &&\n> +\ttest_cmp expected actual\n> +'\n\nLikewise.\n\n> +test_expect_success 'grep -E pattern with grep.patternType=fixed, =basic, =extended, =perl' '\n> +\t{\n> +\t\techo \"ab:a+b*c\"\n> +\t\techo \"ab:a+bc\"\n> +\t\techo \"ab:abc\"\n> +\t} >expected &&\n> +\tgit \\\n> +\t\t-c grep.patterntype=fixed \\\n> +\t\t-c grep.patterntype=basic \\\n> +\t\t-c grep.patterntype=extended \\\n> +\t\t-c grep.patterntype=perl \\\n> +\t\tgrep -E \"a+\" ab >actual &&\n> +\ttest_cmp expected actual\n> +'\n\nLikewise.\n\n> +test_expect_success 'grep pattern with grep.patternType=extended and grep.extendedRegexp=false' '\n> +\tcat >expected <<-EOF\n> +\thello.c:int main(int argc, const char **argv)\n> +\tEOF\n> +\tgit \\\n> +\t\t-c grep.patterntype=extended \\\n> +\t\t-c grep.extendedregexp=false \\\n> +\t\tgrep \"con?st\" hello.c >actual &&\n> +\ttest_cmp expected actual\n> +'\n\nWhat does this test?  patterntype trumps extendedregexp?\n\nThat may sit better next to the earlier \"patterntype says basic but\nextendedregexp says true\" test, if you can move this test easily\nthere.\n\nThanks.\n"},{"id":"196313","messageId":"876292ntlo.fsf@gmail.com","threadId":"31164","inReplyTo":"7vpq7ae0pj.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH/RFC] grep: add a grep.patternType configuration setting","fromName":"Štěpán Němec","fromEmail":"stepnem@gmail.com","sentAt":"2012-08-01T22:19:15Z","receivedAt":"2012-08-01T22:19:15Z","isPatch":true,"sender":{"key":"stepnem@gmail.com","avatar":"https://avatars.githubusercontent.com/u/106838?v=4"},"body":"On Wed, 01 Aug 2012 14:55:52 -0700\nJunio C. Hamano wrote:\n\n> J Smith <dark.panda@gmail.com> writes:\n>\n>>  grep.extendedRegexp::\n>> -\tIf set to true, enable '--extended-regexp' option by default.\n>> +\tIf set to true, enable '--extended-regexp' option by default. This\n>> +\toption is ignored when the 'grep.patternType' option is set.\n>\n> We are not going to make grep.patternType a boolean, so \"when ... is\n> set\" is fine, but if we were to allow grep.patternType to be set to\n> \"false\", the description gives ambiguity to some readers who do.\n> Perhaps s/is set/is given/ is safer.\n\nI'm not a native speaker, but to me \"is given\" implies command line (the\nmeaning is clear here, it just sounds a bit weird). If it's not just me,\n\"is used\" or \"has a value\" might be better.\n\n-- \nŠtěpán\n"},{"id":"196317","messageId":"CADFUPgdX44pCFhytPj-hHSCPH9UHNBKk5pYkpses86M1ntxvyA@mail.gmail.com","threadId":"31164","inReplyTo":"7vpq7ae0pj.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH/RFC] grep: add a grep.patternType configuration setting","fromName":"J Smith","fromEmail":"dark.panda@gmail.com","sentAt":"2012-08-01T22:49:02Z","receivedAt":"2012-08-01T22:49:02Z","isPatch":true,"sender":{"key":"dark.panda@gmail.com","avatar":"https://avatars.githubusercontent.com/u/84783?v=4"},"body":"On Wed, Aug 1, 2012 at 5:55 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>\n> As the basic structure and the direction looks good, let's start\n> nitpicking ;-)\n\nSounds good.\n\n> We tend to write the commit log message in imperative mood, as if\n> you are giving an order to the codebase to \"behave this way!\".  Also\n> we tend to give the justification behind the change first and then\n> present the solution.\n\nSounds good to me. I'll re-word the commit messages in future\nrevisions of the patch.\n\n> With this round, we are not updating an existing a bool variable,\n> but are introducing a brand new one; does it still make sense to\n> support the boolean values for this new variable?\n\nYeah, I thought about that, having noticed in your edited patch that\nthe boolean options were still in there for patternType. I do think it\nwould be useful to have a way to get back to the default settings, say\non a per-repo basis to override a global setting. I was thinking that\na \"false\" value could provide that, but perhaps a value of \"default\"\nwould make more sense?\n\n> You want a test that runs \"git -c grep.patternType=basic grep -P\" or\n> something, guarded with LIBPCRE prerequisite, to make sure pcre\n> patterns are used because command line -P trumps over configured\n> default, too.\n\nWill add.\n\n> Besides, I do not think you are testing the right thing in them\n> anyway (notice the lack of \"grep.\" prefix).\n\nAh geez. Yeah, that's just stupidity.\n\n> What does this test?  The last one wins?\n>\n> For the command line flags, people can do \"alias g 'git grep -E'\"\n> and then countermand the flags in the alias by appending a\n> contradicting flag when using it, e.g. \"g -G\", last one wins is a\n> defined and useful semantics, but for configuration variables that\n> are meant to take a single value, I do not think we give such a\n> strong guarantee on ordering (it may happen to work by accident,\n> though).\n>\n> I would _not_ strongly suggest removing this test, but instead wait\n> until we hear from others, as they may disagree.\n\nI'll wait for others and we'll see. I'm not overly attached to them or anything.\n\n> As you are expecting the \"last one wins\" behaviour among\n> configuration variables, running a test with -P option would not let\n> you catch bugs coming from potentially screwed-up precedence between\n> the configuration and command line flags, would it?  At least, leave\n> the \"-c grep.patterntype=perl\" out from here to make sure what the\n> variable and the flag tell the command conflict with each other.  I\n> would also prefer to see only one \"-c grep.patterntype=<foo>\" used.\n\nAh, yes, that was how the test was supposed to be written. That was an\noversight.\n\n> What does this test?  patterntype trumps extendedregexp?\n>\n> That may sit better next to the earlier \"patterntype says basic but\n> extendedregexp says true\" test, if you can move this test easily\n> there.\n\nYep, I'll move it around.\n\nCheers\n"},{"id":"196360","messageId":"CADFUPgfeEYSOH8scLatTGqCWQQ=goA2KZogLC+UmVNZWi3UrcA@mail.gmail.com","threadId":"31164","inReplyTo":"CADFUPgdX44pCFhytPj-hHSCPH9UHNBKk5pYkpses86M1ntxvyA@mail.gmail.com","subject":"Re: [PATCH/RFC] grep: add a grep.patternType configuration setting","fromName":"J Smith","fromEmail":"dark.panda@gmail.com","sentAt":"2012-08-02T14:47:43Z","receivedAt":"2012-08-02T14:47:43Z","isPatch":true,"sender":{"key":"dark.panda@gmail.com","avatar":"https://avatars.githubusercontent.com/u/84783?v=4"},"body":"Alright, I have revised the patch and fixed up the nits that were\npicked and made a quick modification. I've added a setting for\ngrep.patternType for \"default\" which can restore the default grep\npattern matching behaviour and restores the functionality back to\ngrep.extendedRegexp. I added this functionality for situations like\nwhere you would have grep.patternType set to, say, \"perl\" in your\n$HOME/.gitconfig but don't want that functionality set in a specific\nrepo and would rather to have it fall back to the older\ngrep.extendedRegexp behaviour so you can set it to \"default\" in the\nrepo's .git/config.\n\nThis change also lets us determine the final set of pattern type\noptions in one place rather than the current code which does two\nchecks -- once when we call grep_config to determine the configuration\noptions and then another a few lines later when we call it for the\narguments given to grep. Now we capture the values we receive from\ngrep.patternType and grep.extendedRegexp in the grep_opt struct as\npattern_type_option and extended_regexp_option, capture the pattern\ntype argument given to the command itself, and then make the final\ndetermination for the options to be used in one place rather than the\ncurrent manner. I think it should be more obvious this way.\n\nI'll post the latest patch shortly for review if this sounds reasonable. Cheers.\n"}]}