From 15fabd1bbd4c997d0edb2249295e2717bc18b6c7 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 9 Oct 2012 16:04:12 -0700 Subject: [PATCH 1/7] builtin/grep.c: make configuration callback more reusable The grep_config() function takes one instance of grep_opt as its callback parameter, and populates it by running git_config(). This has three practical implications: - You have to have an instance of grep_opt already when you call the configuration, but that is not necessarily always true. You may be trying to initialize the grep_filter member of rev_info, but are not ready to call init_revisions() on it yet. - It is not easy to enhance grep_config() in such a way to make it cascade to other callback functions to grab other variables in one call of git_config(); grep_config() can be cascaded into from other callbacks, but it has to be at the leaf level of a cascade. - If you ever need to use more than one instance of grep_opt, you will have to open and read the configuration file(s) every time you initialize them. Rearrange the configuration mechanism and model it after how diff configuration variables are handled. An early call to git_config() reads and remembers the values taken from the configuration in the default "template", and a separate call to grep_init() uses this template to instantiate a grep_opt. The next step will be to move some of this out of this file so that the other user of the grep machinery (i.e. "log") can use it. Signed-off-by: Junio C Hamano --- builtin/grep.c | 104 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 79 insertions(+), 25 deletions(-) diff --git a/builtin/grep.c b/builtin/grep.c index 82530a61b4..83232c93e2 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -308,9 +308,41 @@ static void grep_pattern_type_options(const int pattern_type, struct grep_opt *o } } +static struct grep_opt grep_defaults; + +/* + * Initialize the grep_defaults template with hardcoded defaults. + * We could let the compiler do this, but without C99 initializers + * the code gets unwieldy and unreadable, so... + */ +static void init_grep_defaults(void) +{ + struct grep_opt *opt = &grep_defaults; + + memset(opt, 0, sizeof(*opt)); + opt->relative = 1; + opt->pathname = 1; + opt->regflags = REG_NEWLINE; + opt->max_depth = -1; + opt->pattern_type_option = GREP_PATTERN_TYPE_UNSPECIFIED; + opt->extended_regexp_option = 0; + strcpy(opt->color_context, ""); + strcpy(opt->color_filename, ""); + strcpy(opt->color_function, ""); + strcpy(opt->color_lineno, ""); + strcpy(opt->color_match, GIT_COLOR_BOLD_RED); + strcpy(opt->color_selected, ""); + strcpy(opt->color_sep, GIT_COLOR_CYAN); + opt->color = -1; +} + +/* + * Read the configuration file once and store it in + * the grep_defaults template. + */ static int grep_config(const char *var, const char *value, void *cb) { - struct grep_opt *opt = cb; + struct grep_opt *opt = &grep_defaults; char *color = NULL; if (userdiff_config(var, value) < 0) @@ -327,7 +359,7 @@ static int grep_config(const char *var, const char *value, void *cb) if (!strcmp(var, "grep.patterntype")) { opt->pattern_type_option = parse_pattern_type_arg(var, value); return 0; - } + } if (!strcmp(var, "grep.linenumber")) { opt->linenum = git_config_bool(var, value); @@ -350,8 +382,7 @@ static int grep_config(const char *var, const char *value, void *cb) color = opt->color_selected; else if (!strcmp(var, "color.grep.separator")) color = opt->color_sep; - else - return git_color_default_config(var, value, cb); + if (color) { if (!value) return config_error_nonbool(var); @@ -360,6 +391,47 @@ static int grep_config(const char *var, const char *value, void *cb) return 0; } +/* + * Initialize one instance of grep_opt and copy the + * default values from the template we read the configuration + * information in an earlier call to git_config(grep_config). + */ +static void grep_init(struct grep_opt *opt, const char *prefix) +{ + struct grep_opt *def = &grep_defaults; + + memset(opt, 0, sizeof(*opt)); + opt->prefix = prefix; + opt->prefix_length = (prefix && *prefix) ? strlen(prefix) : 0; + opt->pattern_tail = &opt->pattern_list; + opt->header_tail = &opt->header_list; + + opt->color = def->color; + opt->extended_regexp_option = def->extended_regexp_option; + opt->pattern_type_option = def->pattern_type_option; + opt->linenum = def->linenum; + opt->max_depth = def->max_depth; + opt->pathname = def->pathname; + opt->regflags = def->regflags; + opt->relative = def->relative; + + strcpy(opt->color_context, def->color_context); + strcpy(opt->color_filename, def->color_filename); + strcpy(opt->color_function, def->color_function); + strcpy(opt->color_lineno, def->color_lineno); + strcpy(opt->color_match, def->color_match); + strcpy(opt->color_selected, def->color_selected); + strcpy(opt->color_sep, def->color_sep); +} + +static int grep_cmd_config(const char *var, const char *value, void *cb) +{ + int st = grep_config(var, value, cb); + if (git_color_default_config(var, value, cb) < 0) + st = -1; + return st; +} + static void *lock_and_read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size) { void *data; @@ -839,27 +911,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix) if (argc == 2 && !strcmp(argv[1], "-h")) usage_with_options(grep_usage, options); - memset(&opt, 0, sizeof(opt)); - opt.prefix = prefix; - opt.prefix_length = (prefix && *prefix) ? strlen(prefix) : 0; - opt.relative = 1; - opt.pathname = 1; - opt.pattern_tail = &opt.pattern_list; - opt.header_tail = &opt.header_list; - opt.regflags = REG_NEWLINE; - opt.max_depth = -1; - opt.pattern_type_option = GREP_PATTERN_TYPE_UNSPECIFIED; - opt.extended_regexp_option = 0; - - strcpy(opt.color_context, ""); - strcpy(opt.color_filename, ""); - strcpy(opt.color_function, ""); - strcpy(opt.color_lineno, ""); - strcpy(opt.color_match, GIT_COLOR_BOLD_RED); - strcpy(opt.color_selected, ""); - strcpy(opt.color_sep, GIT_COLOR_CYAN); - opt.color = -1; - git_config(grep_config, &opt); + init_grep_defaults(); + git_config(grep_cmd_config, NULL); + grep_init(&opt, prefix); /* * If there is no -- then the paths must exist in the working From 7687a0541e0a6d86c5005d84057321368181c1b5 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 9 Oct 2012 16:17:50 -0700 Subject: [PATCH 2/7] grep: move the configuration parsing logic to grep.[ch] The configuration handling is a library-ish part of this program, that is not specific to "git grep" command. It should be reusable by "log" and others. Signed-off-by: Junio C Hamano --- builtin/grep.c | 131 ------------------------------------------------- grep.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++ grep.h | 4 ++ 3 files changed, 134 insertions(+), 131 deletions(-) diff --git a/builtin/grep.c b/builtin/grep.c index 83232c93e2..b63a9f8368 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -261,21 +261,6 @@ static int wait_all(void) } #endif -static int parse_pattern_type_arg(const char *opt, const char *arg) -{ - if (!strcmp(arg, "default")) - return GREP_PATTERN_TYPE_UNSPECIFIED; - else if (!strcmp(arg, "basic")) - return GREP_PATTERN_TYPE_BRE; - else if (!strcmp(arg, "extended")) - return GREP_PATTERN_TYPE_ERE; - else if (!strcmp(arg, "fixed")) - return GREP_PATTERN_TYPE_FIXED; - else if (!strcmp(arg, "perl")) - return GREP_PATTERN_TYPE_PCRE; - die("bad %s argument: %s", opt, arg); -} - static void grep_pattern_type_options(const int pattern_type, struct grep_opt *opt) { switch (pattern_type) { @@ -308,122 +293,6 @@ static void grep_pattern_type_options(const int pattern_type, struct grep_opt *o } } -static struct grep_opt grep_defaults; - -/* - * Initialize the grep_defaults template with hardcoded defaults. - * We could let the compiler do this, but without C99 initializers - * the code gets unwieldy and unreadable, so... - */ -static void init_grep_defaults(void) -{ - struct grep_opt *opt = &grep_defaults; - - memset(opt, 0, sizeof(*opt)); - opt->relative = 1; - opt->pathname = 1; - opt->regflags = REG_NEWLINE; - opt->max_depth = -1; - opt->pattern_type_option = GREP_PATTERN_TYPE_UNSPECIFIED; - opt->extended_regexp_option = 0; - strcpy(opt->color_context, ""); - strcpy(opt->color_filename, ""); - strcpy(opt->color_function, ""); - strcpy(opt->color_lineno, ""); - strcpy(opt->color_match, GIT_COLOR_BOLD_RED); - strcpy(opt->color_selected, ""); - strcpy(opt->color_sep, GIT_COLOR_CYAN); - opt->color = -1; -} - -/* - * Read the configuration file once and store it in - * the grep_defaults template. - */ -static int grep_config(const char *var, const char *value, void *cb) -{ - struct grep_opt *opt = &grep_defaults; - char *color = NULL; - - if (userdiff_config(var, value) < 0) - return -1; - - if (!strcmp(var, "grep.extendedregexp")) { - if (git_config_bool(var, value)) - opt->extended_regexp_option = 1; - else - opt->extended_regexp_option = 0; - return 0; - } - - if (!strcmp(var, "grep.patterntype")) { - opt->pattern_type_option = parse_pattern_type_arg(var, value); - return 0; - } - - if (!strcmp(var, "grep.linenumber")) { - opt->linenum = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "color.grep")) - opt->color = git_config_colorbool(var, value); - else if (!strcmp(var, "color.grep.context")) - color = opt->color_context; - else if (!strcmp(var, "color.grep.filename")) - color = opt->color_filename; - else if (!strcmp(var, "color.grep.function")) - color = opt->color_function; - else if (!strcmp(var, "color.grep.linenumber")) - color = opt->color_lineno; - else if (!strcmp(var, "color.grep.match")) - color = opt->color_match; - else if (!strcmp(var, "color.grep.selected")) - color = opt->color_selected; - else if (!strcmp(var, "color.grep.separator")) - color = opt->color_sep; - - if (color) { - if (!value) - return config_error_nonbool(var); - color_parse(value, var, color); - } - return 0; -} - -/* - * Initialize one instance of grep_opt and copy the - * default values from the template we read the configuration - * information in an earlier call to git_config(grep_config). - */ -static void grep_init(struct grep_opt *opt, const char *prefix) -{ - struct grep_opt *def = &grep_defaults; - - memset(opt, 0, sizeof(*opt)); - opt->prefix = prefix; - opt->prefix_length = (prefix && *prefix) ? strlen(prefix) : 0; - opt->pattern_tail = &opt->pattern_list; - opt->header_tail = &opt->header_list; - - opt->color = def->color; - opt->extended_regexp_option = def->extended_regexp_option; - opt->pattern_type_option = def->pattern_type_option; - opt->linenum = def->linenum; - opt->max_depth = def->max_depth; - opt->pathname = def->pathname; - opt->regflags = def->regflags; - opt->relative = def->relative; - - strcpy(opt->color_context, def->color_context); - strcpy(opt->color_filename, def->color_filename); - strcpy(opt->color_function, def->color_function); - strcpy(opt->color_lineno, def->color_lineno); - strcpy(opt->color_match, def->color_match); - strcpy(opt->color_selected, def->color_selected); - strcpy(opt->color_sep, def->color_sep); -} - static int grep_cmd_config(const char *var, const char *value, void *cb) { int st = grep_config(var, value, cb); diff --git a/grep.c b/grep.c index edc7776677..621e6ec22e 100644 --- a/grep.c +++ b/grep.c @@ -6,6 +6,136 @@ static int grep_source_load(struct grep_source *gs); static int grep_source_is_binary(struct grep_source *gs); +static struct grep_opt grep_defaults; + +/* + * Initialize the grep_defaults template with hardcoded defaults. + * We could let the compiler do this, but without C99 initializers + * the code gets unwieldy and unreadable, so... + */ +void init_grep_defaults(void) +{ + struct grep_opt *opt = &grep_defaults; + + memset(opt, 0, sizeof(*opt)); + opt->relative = 1; + opt->pathname = 1; + opt->regflags = REG_NEWLINE; + opt->max_depth = -1; + opt->pattern_type_option = GREP_PATTERN_TYPE_UNSPECIFIED; + opt->extended_regexp_option = 0; + strcpy(opt->color_context, ""); + strcpy(opt->color_filename, ""); + strcpy(opt->color_function, ""); + strcpy(opt->color_lineno, ""); + strcpy(opt->color_match, GIT_COLOR_BOLD_RED); + strcpy(opt->color_selected, ""); + strcpy(opt->color_sep, GIT_COLOR_CYAN); + opt->color = -1; +} + +static int parse_pattern_type_arg(const char *opt, const char *arg) +{ + if (!strcmp(arg, "default")) + return GREP_PATTERN_TYPE_UNSPECIFIED; + else if (!strcmp(arg, "basic")) + return GREP_PATTERN_TYPE_BRE; + else if (!strcmp(arg, "extended")) + return GREP_PATTERN_TYPE_ERE; + else if (!strcmp(arg, "fixed")) + return GREP_PATTERN_TYPE_FIXED; + else if (!strcmp(arg, "perl")) + return GREP_PATTERN_TYPE_PCRE; + die("bad %s argument: %s", opt, arg); +} + +/* + * Read the configuration file once and store it in + * the grep_defaults template. + */ +int grep_config(const char *var, const char *value, void *cb) +{ + struct grep_opt *opt = &grep_defaults; + char *color = NULL; + + if (userdiff_config(var, value) < 0) + return -1; + + if (!strcmp(var, "grep.extendedregexp")) { + if (git_config_bool(var, value)) + opt->extended_regexp_option = 1; + else + opt->extended_regexp_option = 0; + return 0; + } + + if (!strcmp(var, "grep.patterntype")) { + opt->pattern_type_option = parse_pattern_type_arg(var, value); + return 0; + } + + if (!strcmp(var, "grep.linenumber")) { + opt->linenum = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "color.grep")) + opt->color = git_config_colorbool(var, value); + else if (!strcmp(var, "color.grep.context")) + color = opt->color_context; + else if (!strcmp(var, "color.grep.filename")) + color = opt->color_filename; + else if (!strcmp(var, "color.grep.function")) + color = opt->color_function; + else if (!strcmp(var, "color.grep.linenumber")) + color = opt->color_lineno; + else if (!strcmp(var, "color.grep.match")) + color = opt->color_match; + else if (!strcmp(var, "color.grep.selected")) + color = opt->color_selected; + else if (!strcmp(var, "color.grep.separator")) + color = opt->color_sep; + + if (color) { + if (!value) + return config_error_nonbool(var); + color_parse(value, var, color); + } + return 0; +} + +/* + * Initialize one instance of grep_opt and copy the + * default values from the template we read the configuration + * information in an earlier call to git_config(grep_config). + */ +void grep_init(struct grep_opt *opt, const char *prefix) +{ + struct grep_opt *def = &grep_defaults; + + memset(opt, 0, sizeof(*opt)); + opt->prefix = prefix; + opt->prefix_length = (prefix && *prefix) ? strlen(prefix) : 0; + opt->pattern_tail = &opt->pattern_list; + opt->header_tail = &opt->header_list; + + opt->color = def->color; + opt->extended_regexp_option = def->extended_regexp_option; + opt->pattern_type_option = def->pattern_type_option; + opt->linenum = def->linenum; + opt->max_depth = def->max_depth; + opt->pathname = def->pathname; + opt->regflags = def->regflags; + opt->relative = def->relative; + + strcpy(opt->color_context, def->color_context); + strcpy(opt->color_filename, def->color_filename); + strcpy(opt->color_function, def->color_function); + strcpy(opt->color_lineno, def->color_lineno); + strcpy(opt->color_match, def->color_match); + strcpy(opt->color_selected, def->color_selected); + strcpy(opt->color_sep, def->color_sep); +} static struct grep_pat *create_grep_pat(const char *pat, size_t patlen, const char *origin, int no, diff --git a/grep.h b/grep.h index c256ac6e15..9aa1cc7e13 100644 --- a/grep.h +++ b/grep.h @@ -138,6 +138,10 @@ struct grep_opt { void *output_priv; }; +extern void init_grep_defaults(void); +extern int grep_config(const char *var, const char *value, void *); +extern void grep_init(struct grep_opt *, const char *prefix); + extern void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen, const char *origin, int no, enum grep_pat_token t); extern void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t); extern void append_header_grep_pattern(struct grep_opt *, enum grep_header_field, const char *); From c5c31d3381d11903c01d51aff4437fe9f76d0268 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 3 Oct 2012 14:47:48 -0700 Subject: [PATCH 3/7] grep: move pattern-type bits support to top-level grep.[ch] Switching between -E/-G/-P/-F correctly needs a lot more than just flipping opt->regflags bit these days, and we have a nice helper function buried in builtin/grep.c for the sole use of "git grep". Extract it so that "log --grep" family can also use it. Signed-off-by: Junio C Hamano --- builtin/grep.c | 40 +--------------------------------------- grep.c | 42 ++++++++++++++++++++++++++++++++++++++++++ grep.h | 2 ++ 3 files changed, 45 insertions(+), 39 deletions(-) diff --git a/builtin/grep.c b/builtin/grep.c index b63a9f8368..c296e6f99e 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -261,38 +261,6 @@ static int wait_all(void) } #endif -static void grep_pattern_type_options(const int pattern_type, struct grep_opt *opt) -{ - switch (pattern_type) { - case GREP_PATTERN_TYPE_UNSPECIFIED: - /* fall through */ - - case GREP_PATTERN_TYPE_BRE: - opt->fixed = 0; - opt->pcre = 0; - opt->regflags &= ~REG_EXTENDED; - break; - - case GREP_PATTERN_TYPE_ERE: - opt->fixed = 0; - opt->pcre = 0; - opt->regflags |= REG_EXTENDED; - break; - - case GREP_PATTERN_TYPE_FIXED: - opt->fixed = 1; - opt->pcre = 0; - opt->regflags &= ~REG_EXTENDED; - break; - - case GREP_PATTERN_TYPE_PCRE: - opt->fixed = 0; - opt->pcre = 1; - opt->regflags &= ~REG_EXTENDED; - break; - } -} - static int grep_cmd_config(const char *var, const char *value, void *cb) { int st = grep_config(var, value, cb); @@ -798,13 +766,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_STOP_AT_NON_OPTION | PARSE_OPT_NO_INTERNAL_HELP); - - if (pattern_type_arg != GREP_PATTERN_TYPE_UNSPECIFIED) - grep_pattern_type_options(pattern_type_arg, &opt); - else if (opt.pattern_type_option != GREP_PATTERN_TYPE_UNSPECIFIED) - grep_pattern_type_options(opt.pattern_type_option, &opt); - else if (opt.extended_regexp_option) - grep_pattern_type_options(GREP_PATTERN_TYPE_ERE, &opt); + grep_commit_pattern_type(pattern_type_arg, &opt); if (use_index && !startup_info->have_repository) /* die the same way as if we did it at the beginning */ diff --git a/grep.c b/grep.c index 621e6ec22e..279a55933c 100644 --- a/grep.c +++ b/grep.c @@ -137,6 +137,48 @@ void grep_init(struct grep_opt *opt, const char *prefix) strcpy(opt->color_sep, def->color_sep); } +void grep_commit_pattern_type(enum grep_pattern_type pattern_type, struct grep_opt *opt) +{ + if (pattern_type != GREP_PATTERN_TYPE_UNSPECIFIED) + grep_set_pattern_type_option(pattern_type, opt); + else if (opt->pattern_type_option != GREP_PATTERN_TYPE_UNSPECIFIED) + grep_set_pattern_type_option(opt->pattern_type_option, opt); + else if (opt->extended_regexp_option) + grep_set_pattern_type_option(GREP_PATTERN_TYPE_ERE, opt); +} + +void grep_set_pattern_type_option(enum grep_pattern_type pattern_type, struct grep_opt *opt) +{ + switch (pattern_type) { + case GREP_PATTERN_TYPE_UNSPECIFIED: + /* fall through */ + + case GREP_PATTERN_TYPE_BRE: + opt->fixed = 0; + opt->pcre = 0; + opt->regflags &= ~REG_EXTENDED; + break; + + case GREP_PATTERN_TYPE_ERE: + opt->fixed = 0; + opt->pcre = 0; + opt->regflags |= REG_EXTENDED; + break; + + case GREP_PATTERN_TYPE_FIXED: + opt->fixed = 1; + opt->pcre = 0; + opt->regflags &= ~REG_EXTENDED; + break; + + case GREP_PATTERN_TYPE_PCRE: + opt->fixed = 0; + opt->pcre = 1; + opt->regflags &= ~REG_EXTENDED; + break; + } +} + static struct grep_pat *create_grep_pat(const char *pat, size_t patlen, const char *origin, int no, enum grep_pat_token t, diff --git a/grep.h b/grep.h index 9aa1cc7e13..701c78459f 100644 --- a/grep.h +++ b/grep.h @@ -141,6 +141,8 @@ struct grep_opt { extern void init_grep_defaults(void); extern int grep_config(const char *var, const char *value, void *); extern void grep_init(struct grep_opt *, const char *prefix); +void grep_set_pattern_type_option(enum grep_pattern_type, struct grep_opt *opt); +void grep_commit_pattern_type(enum grep_pattern_type, struct grep_opt *opt); extern void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen, const char *origin, int no, enum grep_pat_token t); extern void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t); From 918d4e1c907983d26b0c4d82d7f7abff4dbec4e5 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 9 Oct 2012 16:40:03 -0700 Subject: [PATCH 4/7] revisions: initialize revs->grep_filter using grep_init() Instead of using the hand-rolled initialization sequence, use grep_init() to populate the necessary bits. This opens the door to allow the calling commands to optionally read grep.* configuration variables via git_config() if they want to. Signed-off-by: Junio C Hamano --- grep.c | 5 +++++ revision.c | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/grep.c b/grep.c index 279a55933c..a947a68a7f 100644 --- a/grep.c +++ b/grep.c @@ -16,6 +16,11 @@ static struct grep_opt grep_defaults; void init_grep_defaults(void) { struct grep_opt *opt = &grep_defaults; + static int run_once; + + if (run_once) + return; + run_once++; memset(opt, 0, sizeof(*opt)); opt->relative = 1; diff --git a/revision.c b/revision.c index a09e60bedb..a4a931426f 100644 --- a/revision.c +++ b/revision.c @@ -1048,9 +1048,9 @@ void init_revisions(struct rev_info *revs, const char *prefix) revs->commit_format = CMIT_FMT_DEFAULT; + init_grep_defaults(); + grep_init(&revs->grep_filter, prefix); revs->grep_filter.status_only = 1; - revs->grep_filter.pattern_tail = &(revs->grep_filter.pattern_list); - revs->grep_filter.header_tail = &(revs->grep_filter.header_list); revs->grep_filter.regflags = REG_NEWLINE; diff_setup(&revs->diffopt); @@ -1893,6 +1893,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s revs->diffopt.abbrev = revs->abbrev; diff_setup_done(&revs->diffopt); + grep_commit_pattern_type(GREP_PATTERN_TYPE_UNSPECIFIED, + &revs->grep_filter); compile_grep_patterns(&revs->grep_filter); if (revs->reverse && revs->reflog_info) From 34a4ae55b260bbd1520d6a7c6718b4de2d5c7632 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 3 Oct 2012 14:50:51 -0700 Subject: [PATCH 5/7] log --grep: use the same helper to set -E/-F options as "git grep" The command line option parser for "git log -F -E --grep=''" did not flip the "fixed" bit, violating the general "last option wins" principle among conflicting options. Signed-off-by: Junio C Hamano --- revision.c | 4 ++-- t/t4202-log.sh | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/revision.c b/revision.c index a4a931426f..68545c8015 100644 --- a/revision.c +++ b/revision.c @@ -1604,12 +1604,12 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg } else if (!strcmp(arg, "--grep-debug")) { revs->grep_filter.debug = 1; } else if (!strcmp(arg, "--extended-regexp") || !strcmp(arg, "-E")) { - revs->grep_filter.regflags |= REG_EXTENDED; + grep_set_pattern_type_option(GREP_PATTERN_TYPE_ERE, &revs->grep_filter); } else if (!strcmp(arg, "--regexp-ignore-case") || !strcmp(arg, "-i")) { revs->grep_filter.regflags |= REG_ICASE; DIFF_OPT_SET(&revs->diffopt, PICKAXE_IGNORE_CASE); } else if (!strcmp(arg, "--fixed-strings") || !strcmp(arg, "-F")) { - revs->grep_filter.fixed = 1; + grep_set_pattern_type_option(GREP_PATTERN_TYPE_FIXED, &revs->grep_filter); } else if (!strcmp(arg, "--all-match")) { revs->grep_filter.all_match = 1; } else if ((argcount = parse_long_opt("encoding", argv, &optarg))) { diff --git a/t/t4202-log.sh b/t/t4202-log.sh index 924ba536ca..e6537abe1d 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -230,6 +230,12 @@ test_expect_success 'log --grep -i' ' test_cmp expect actual ' +test_expect_success 'log -F -E --grep= uses ere' ' + echo second >expect && + git log -1 --pretty="tformat:%s" -F -E --grep=s.c.nd >actual && + test_cmp expect actual +' + cat > expect < Date: Wed, 3 Oct 2012 15:01:34 -0700 Subject: [PATCH 6/7] log --grep: accept --basic-regexp and --perl-regexp When we added the "--perl-regexp" option (or "-P") to "git grep", we should have done the same for the commands in the "git log" family, but somehow we forgot to do so. This corrects it, but we will reserve the short-and-sweet "-P" option for something else for now. Also introduce the "--basic-regexp" option for completeness, so that the "last one wins" principle can be used to defeat an earlier -E option, e.g. "git log -E --basic-regexp --grep=''". Note that it cannot have the short "-G" option as the option is to grep in the patch text in the context of "log" family. Signed-off-by: Junio C Hamano --- Documentation/rev-list-options.txt | 10 ++++++++++ revision.c | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index ee497430cb..1ec14a068e 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -79,6 +79,11 @@ if it is part of the log message. Match the regexp limiting patterns without regard to letters case. +--basic-regexp:: + + Consider the limiting patterns to be basic regular expressions; + this is the default. + -E:: --extended-regexp:: @@ -91,6 +96,11 @@ if it is part of the log message. Consider the limiting patterns to be fixed strings (don't interpret pattern as a regular expression). +--perl-regexp:: + + Consider the limiting patterns to be Perl-compatible regexp. + Requires libpcre to be compiled in. + --remove-empty:: Stop when a given path disappears from the tree. diff --git a/revision.c b/revision.c index 68545c8015..d7d621cdbf 100644 --- a/revision.c +++ b/revision.c @@ -1603,6 +1603,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg return argcount; } else if (!strcmp(arg, "--grep-debug")) { revs->grep_filter.debug = 1; + } else if (!strcmp(arg, "--basic-regexp")) { + grep_set_pattern_type_option(GREP_PATTERN_TYPE_BRE, &revs->grep_filter); } else if (!strcmp(arg, "--extended-regexp") || !strcmp(arg, "-E")) { grep_set_pattern_type_option(GREP_PATTERN_TYPE_ERE, &revs->grep_filter); } else if (!strcmp(arg, "--regexp-ignore-case") || !strcmp(arg, "-i")) { @@ -1610,6 +1612,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg DIFF_OPT_SET(&revs->diffopt, PICKAXE_IGNORE_CASE); } else if (!strcmp(arg, "--fixed-strings") || !strcmp(arg, "-F")) { grep_set_pattern_type_option(GREP_PATTERN_TYPE_FIXED, &revs->grep_filter); + } else if (!strcmp(arg, "--perl-regexp")) { + grep_set_pattern_type_option(GREP_PATTERN_TYPE_PCRE, &revs->grep_filter); } else if (!strcmp(arg, "--all-match")) { revs->grep_filter.all_match = 1; } else if ((argcount = parse_long_opt("encoding", argv, &optarg))) { From 0657bcbf6f0830bc4ce25d05060706f35f1d4eb7 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 9 Oct 2012 16:49:57 -0700 Subject: [PATCH 7/7] log: honor grep.* configuration Now the grep_config() callback is reusable from other configuration callbacks, call it from git_log_config() so that grep.patterntype and friends can be used with the commands in the "git log" family. Signed-off-by: Junio C Hamano --- builtin/log.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/builtin/log.c b/builtin/log.c index 09cf43e6d4..e7b7db1cac 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -351,7 +351,8 @@ static int git_log_config(const char *var, const char *value, void *cb) } if (!prefixcmp(var, "color.decorate.")) return parse_decorate_color_config(var, 15, value); - + if (grep_config(var, value, cb) < 0) + return -1; return git_diff_ui_config(var, value, cb); } @@ -360,6 +361,7 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix) struct rev_info rev; struct setup_revision_opt opt; + init_grep_defaults(); git_config(git_log_config, NULL); init_revisions(&rev, prefix); @@ -450,6 +452,7 @@ int cmd_show(int argc, const char **argv, const char *prefix) struct pathspec match_all; int i, count, ret = 0; + init_grep_defaults(); git_config(git_log_config, NULL); init_pathspec(&match_all, NULL); @@ -530,6 +533,7 @@ int cmd_log_reflog(int argc, const char **argv, const char *prefix) struct rev_info rev; struct setup_revision_opt opt; + init_grep_defaults(); git_config(git_log_config, NULL); init_revisions(&rev, prefix); @@ -552,6 +556,7 @@ int cmd_log(int argc, const char **argv, const char *prefix) struct rev_info rev; struct setup_revision_opt opt; + init_grep_defaults(); git_config(git_log_config, NULL); init_revisions(&rev, prefix); @@ -1121,6 +1126,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) extra_hdr.strdup_strings = 1; extra_to.strdup_strings = 1; extra_cc.strdup_strings = 1; + init_grep_defaults(); git_config(git_format_config, NULL); init_revisions(&rev, prefix); rev.commit_format = CMIT_FMT_EMAIL;