Merge branch 'ab/grep-patterntype'
Some code clean-up in the "git grep" machinery. * ab/grep-patterntype: grep: simplify config parsing and option parsing grep.c: do "if (bool && memchr())" not "if (memchr() && bool)" grep.h: make "grep_opt.pattern_type_option" use its enum grep API: call grep_config() after grep_init() grep.c: don't pass along NULL callback value built-ins: trust the "prefix" from run_builtin() grep tests: add missing "grep.patternType" config tests grep tests: create a helper function for "BRE" or "ERE" log tests: check if grep_config() is called by "log"-like cmds grep.h: remove unused "regex_t regexp" from grep_opt
This commit is contained in:
commit
5b84280c65
@ -26,6 +26,8 @@
|
|||||||
#include "object-store.h"
|
#include "object-store.h"
|
||||||
#include "packfile.h"
|
#include "packfile.h"
|
||||||
|
|
||||||
|
static const char *grep_prefix;
|
||||||
|
|
||||||
static char const * const grep_usage[] = {
|
static char const * const grep_usage[] = {
|
||||||
N_("git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"),
|
N_("git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"),
|
||||||
NULL
|
NULL
|
||||||
@ -284,7 +286,7 @@ static int wait_all(void)
|
|||||||
static int grep_cmd_config(const char *var, const char *value, void *cb)
|
static int grep_cmd_config(const char *var, const char *value, void *cb)
|
||||||
{
|
{
|
||||||
int st = grep_config(var, value, cb);
|
int st = grep_config(var, value, cb);
|
||||||
if (git_color_default_config(var, value, cb) < 0)
|
if (git_color_default_config(var, value, NULL) < 0)
|
||||||
st = -1;
|
st = -1;
|
||||||
|
|
||||||
if (!strcmp(var, "grep.threads")) {
|
if (!strcmp(var, "grep.threads")) {
|
||||||
@ -315,11 +317,11 @@ static void grep_source_name(struct grep_opt *opt, const char *filename,
|
|||||||
strbuf_reset(out);
|
strbuf_reset(out);
|
||||||
|
|
||||||
if (opt->null_following_name) {
|
if (opt->null_following_name) {
|
||||||
if (opt->relative && opt->prefix_length) {
|
if (opt->relative && grep_prefix) {
|
||||||
struct strbuf rel_buf = STRBUF_INIT;
|
struct strbuf rel_buf = STRBUF_INIT;
|
||||||
const char *rel_name =
|
const char *rel_name =
|
||||||
relative_path(filename + tree_name_len,
|
relative_path(filename + tree_name_len,
|
||||||
opt->prefix, &rel_buf);
|
grep_prefix, &rel_buf);
|
||||||
|
|
||||||
if (tree_name_len)
|
if (tree_name_len)
|
||||||
strbuf_add(out, filename, tree_name_len);
|
strbuf_add(out, filename, tree_name_len);
|
||||||
@ -332,8 +334,8 @@ static void grep_source_name(struct grep_opt *opt, const char *filename,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt->relative && opt->prefix_length)
|
if (opt->relative && grep_prefix)
|
||||||
quote_path(filename + tree_name_len, opt->prefix, out, 0);
|
quote_path(filename + tree_name_len, grep_prefix, out, 0);
|
||||||
else
|
else
|
||||||
quote_c_style(filename + tree_name_len, out, NULL, 0);
|
quote_c_style(filename + tree_name_len, out, NULL, 0);
|
||||||
|
|
||||||
@ -843,7 +845,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||||||
int i;
|
int i;
|
||||||
int dummy;
|
int dummy;
|
||||||
int use_index = 1;
|
int use_index = 1;
|
||||||
int pattern_type_arg = GREP_PATTERN_TYPE_UNSPECIFIED;
|
|
||||||
int allow_revs;
|
int allow_revs;
|
||||||
|
|
||||||
struct option options[] = {
|
struct option options[] = {
|
||||||
@ -877,16 +878,16 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||||||
N_("descend at most <depth> levels"), PARSE_OPT_NONEG,
|
N_("descend at most <depth> levels"), PARSE_OPT_NONEG,
|
||||||
NULL, 1 },
|
NULL, 1 },
|
||||||
OPT_GROUP(""),
|
OPT_GROUP(""),
|
||||||
OPT_SET_INT('E', "extended-regexp", &pattern_type_arg,
|
OPT_SET_INT('E', "extended-regexp", &opt.pattern_type_option,
|
||||||
N_("use extended POSIX regular expressions"),
|
N_("use extended POSIX regular expressions"),
|
||||||
GREP_PATTERN_TYPE_ERE),
|
GREP_PATTERN_TYPE_ERE),
|
||||||
OPT_SET_INT('G', "basic-regexp", &pattern_type_arg,
|
OPT_SET_INT('G', "basic-regexp", &opt.pattern_type_option,
|
||||||
N_("use basic POSIX regular expressions (default)"),
|
N_("use basic POSIX regular expressions (default)"),
|
||||||
GREP_PATTERN_TYPE_BRE),
|
GREP_PATTERN_TYPE_BRE),
|
||||||
OPT_SET_INT('F', "fixed-strings", &pattern_type_arg,
|
OPT_SET_INT('F', "fixed-strings", &opt.pattern_type_option,
|
||||||
N_("interpret patterns as fixed strings"),
|
N_("interpret patterns as fixed strings"),
|
||||||
GREP_PATTERN_TYPE_FIXED),
|
GREP_PATTERN_TYPE_FIXED),
|
||||||
OPT_SET_INT('P', "perl-regexp", &pattern_type_arg,
|
OPT_SET_INT('P', "perl-regexp", &opt.pattern_type_option,
|
||||||
N_("use Perl-compatible regular expressions"),
|
N_("use Perl-compatible regular expressions"),
|
||||||
GREP_PATTERN_TYPE_PCRE),
|
GREP_PATTERN_TYPE_PCRE),
|
||||||
OPT_GROUP(""),
|
OPT_GROUP(""),
|
||||||
@ -962,9 +963,10 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||||||
PARSE_OPT_NOCOMPLETE),
|
PARSE_OPT_NOCOMPLETE),
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
|
grep_prefix = prefix;
|
||||||
|
|
||||||
git_config(grep_cmd_config, NULL);
|
grep_init(&opt, the_repository);
|
||||||
grep_init(&opt, the_repository, prefix);
|
git_config(grep_cmd_config, &opt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is no -- then the paths must exist in the working
|
* If there is no -- then the paths must exist in the working
|
||||||
@ -979,7 +981,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||||||
argc = parse_options(argc, argv, prefix, options, grep_usage,
|
argc = parse_options(argc, argv, prefix, options, grep_usage,
|
||||||
PARSE_OPT_KEEP_DASHDASH |
|
PARSE_OPT_KEEP_DASHDASH |
|
||||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||||
grep_commit_pattern_type(pattern_type_arg, &opt);
|
|
||||||
|
|
||||||
if (use_index && !startup_info->have_repository) {
|
if (use_index && !startup_info->have_repository) {
|
||||||
int fallback = 0;
|
int fallback = 0;
|
||||||
|
@ -533,8 +533,6 @@ static int git_log_config(const char *var, const char *value, void *cb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grep_config(var, value, cb) < 0)
|
|
||||||
return -1;
|
|
||||||
if (git_gpg_config(var, value, cb) < 0)
|
if (git_gpg_config(var, value, cb) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
return git_diff_ui_config(var, value, cb);
|
return git_diff_ui_config(var, value, cb);
|
||||||
@ -549,6 +547,8 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix)
|
|||||||
git_config(git_log_config, NULL);
|
git_config(git_log_config, NULL);
|
||||||
|
|
||||||
repo_init_revisions(the_repository, &rev, prefix);
|
repo_init_revisions(the_repository, &rev, prefix);
|
||||||
|
git_config(grep_config, &rev.grep_filter);
|
||||||
|
|
||||||
rev.diff = 1;
|
rev.diff = 1;
|
||||||
rev.simplify_history = 0;
|
rev.simplify_history = 0;
|
||||||
memset(&opt, 0, sizeof(opt));
|
memset(&opt, 0, sizeof(opt));
|
||||||
@ -663,6 +663,8 @@ int cmd_show(int argc, const char **argv, const char *prefix)
|
|||||||
|
|
||||||
memset(&match_all, 0, sizeof(match_all));
|
memset(&match_all, 0, sizeof(match_all));
|
||||||
repo_init_revisions(the_repository, &rev, prefix);
|
repo_init_revisions(the_repository, &rev, prefix);
|
||||||
|
git_config(grep_config, &rev.grep_filter);
|
||||||
|
|
||||||
rev.diff = 1;
|
rev.diff = 1;
|
||||||
rev.always_show_header = 1;
|
rev.always_show_header = 1;
|
||||||
rev.no_walk = 1;
|
rev.no_walk = 1;
|
||||||
@ -746,6 +748,8 @@ int cmd_log_reflog(int argc, const char **argv, const char *prefix)
|
|||||||
|
|
||||||
repo_init_revisions(the_repository, &rev, prefix);
|
repo_init_revisions(the_repository, &rev, prefix);
|
||||||
init_reflog_walk(&rev.reflog_info);
|
init_reflog_walk(&rev.reflog_info);
|
||||||
|
git_config(grep_config, &rev.grep_filter);
|
||||||
|
|
||||||
rev.verbose_header = 1;
|
rev.verbose_header = 1;
|
||||||
memset(&opt, 0, sizeof(opt));
|
memset(&opt, 0, sizeof(opt));
|
||||||
opt.def = "HEAD";
|
opt.def = "HEAD";
|
||||||
@ -779,6 +783,8 @@ int cmd_log(int argc, const char **argv, const char *prefix)
|
|||||||
git_config(git_log_config, NULL);
|
git_config(git_log_config, NULL);
|
||||||
|
|
||||||
repo_init_revisions(the_repository, &rev, prefix);
|
repo_init_revisions(the_repository, &rev, prefix);
|
||||||
|
git_config(grep_config, &rev.grep_filter);
|
||||||
|
|
||||||
rev.always_show_header = 1;
|
rev.always_show_header = 1;
|
||||||
memset(&opt, 0, sizeof(opt));
|
memset(&opt, 0, sizeof(opt));
|
||||||
opt.def = "HEAD";
|
opt.def = "HEAD";
|
||||||
@ -1861,10 +1867,13 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||||||
extra_hdr.strdup_strings = 1;
|
extra_hdr.strdup_strings = 1;
|
||||||
extra_to.strdup_strings = 1;
|
extra_to.strdup_strings = 1;
|
||||||
extra_cc.strdup_strings = 1;
|
extra_cc.strdup_strings = 1;
|
||||||
|
|
||||||
init_log_defaults();
|
init_log_defaults();
|
||||||
init_display_notes(¬es_opt);
|
init_display_notes(¬es_opt);
|
||||||
git_config(git_format_config, NULL);
|
git_config(git_format_config, NULL);
|
||||||
repo_init_revisions(the_repository, &rev, prefix);
|
repo_init_revisions(the_repository, &rev, prefix);
|
||||||
|
git_config(grep_config, &rev.grep_filter);
|
||||||
|
|
||||||
rev.show_notes = show_notes;
|
rev.show_notes = show_notes;
|
||||||
memcpy(&rev.notes_opt, ¬es_opt, sizeof(notes_opt));
|
memcpy(&rev.notes_opt, ¬es_opt, sizeof(notes_opt));
|
||||||
rev.commit_format = CMIT_FMT_EMAIL;
|
rev.commit_format = CMIT_FMT_EMAIL;
|
||||||
|
@ -150,7 +150,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
|
|||||||
|
|
||||||
git_config(git_default_config, NULL);
|
git_config(git_default_config, NULL);
|
||||||
ls_tree_prefix = prefix;
|
ls_tree_prefix = prefix;
|
||||||
if (prefix && *prefix)
|
if (prefix)
|
||||||
chomp_prefix = strlen(prefix);
|
chomp_prefix = strlen(prefix);
|
||||||
|
|
||||||
argc = parse_options(argc, argv, prefix, ls_tree_options,
|
argc = parse_options(argc, argv, prefix, ls_tree_options,
|
||||||
|
1
git.c
1
git.c
@ -436,6 +436,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
|
|||||||
} else {
|
} else {
|
||||||
prefix = NULL;
|
prefix = NULL;
|
||||||
}
|
}
|
||||||
|
assert(!prefix || *prefix);
|
||||||
precompose_argv_prefix(argc, argv, NULL);
|
precompose_argv_prefix(argc, argv, NULL);
|
||||||
if (use_pager == -1 && run_setup &&
|
if (use_pager == -1 && run_setup &&
|
||||||
!(p->option & DELAY_PAGER_CONFIG))
|
!(p->option & DELAY_PAGER_CONFIG))
|
||||||
|
113
grep.c
113
grep.c
@ -19,27 +19,6 @@ static void std_output(struct grep_opt *opt, const void *buf, size_t size)
|
|||||||
fwrite(buf, size, 1, stdout);
|
fwrite(buf, size, 1, stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct grep_opt grep_defaults = {
|
|
||||||
.relative = 1,
|
|
||||||
.pathname = 1,
|
|
||||||
.max_depth = -1,
|
|
||||||
.pattern_type_option = GREP_PATTERN_TYPE_UNSPECIFIED,
|
|
||||||
.colors = {
|
|
||||||
[GREP_COLOR_CONTEXT] = "",
|
|
||||||
[GREP_COLOR_FILENAME] = GIT_COLOR_MAGENTA,
|
|
||||||
[GREP_COLOR_FUNCTION] = "",
|
|
||||||
[GREP_COLOR_LINENO] = GIT_COLOR_GREEN,
|
|
||||||
[GREP_COLOR_COLUMNNO] = GIT_COLOR_GREEN,
|
|
||||||
[GREP_COLOR_MATCH_CONTEXT] = GIT_COLOR_BOLD_RED,
|
|
||||||
[GREP_COLOR_MATCH_SELECTED] = GIT_COLOR_BOLD_RED,
|
|
||||||
[GREP_COLOR_SELECTED] = "",
|
|
||||||
[GREP_COLOR_SEP] = GIT_COLOR_CYAN,
|
|
||||||
},
|
|
||||||
.only_matching = 0,
|
|
||||||
.color = -1,
|
|
||||||
.output = std_output,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *color_grep_slots[] = {
|
static const char *color_grep_slots[] = {
|
||||||
[GREP_COLOR_CONTEXT] = "context",
|
[GREP_COLOR_CONTEXT] = "context",
|
||||||
[GREP_COLOR_FILENAME] = "filename",
|
[GREP_COLOR_FILENAME] = "filename",
|
||||||
@ -75,20 +54,12 @@ define_list_config_array_extra(color_grep_slots, {"match"});
|
|||||||
*/
|
*/
|
||||||
int grep_config(const char *var, const char *value, void *cb)
|
int grep_config(const char *var, const char *value, void *cb)
|
||||||
{
|
{
|
||||||
struct grep_opt *opt = &grep_defaults;
|
struct grep_opt *opt = cb;
|
||||||
const char *slot;
|
const char *slot;
|
||||||
|
|
||||||
if (userdiff_config(var, value) < 0)
|
if (userdiff_config(var, value) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/*
|
|
||||||
* The instance of grep_opt that we set up here is copied by
|
|
||||||
* grep_init() to be used by each individual invocation.
|
|
||||||
* When populating a new field of this structure here, be
|
|
||||||
* sure to think about ownership -- e.g., you might need to
|
|
||||||
* override the shallow copy in grep_init() with a deep copy.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!strcmp(var, "grep.extendedregexp")) {
|
if (!strcmp(var, "grep.extendedregexp")) {
|
||||||
opt->extended_regexp_option = git_config_bool(var, value);
|
opt->extended_regexp_option = git_config_bool(var, value);
|
||||||
return 0;
|
return 0;
|
||||||
@ -134,78 +105,16 @@ int grep_config(const char *var, const char *value, void *cb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void grep_init(struct grep_opt *opt, struct repository *repo)
|
||||||
* 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, struct repository *repo, const char *prefix)
|
|
||||||
{
|
{
|
||||||
*opt = grep_defaults;
|
struct grep_opt blank = GREP_OPT_INIT;
|
||||||
|
memcpy(opt, &blank, sizeof(*opt));
|
||||||
|
|
||||||
opt->repo = repo;
|
opt->repo = repo;
|
||||||
opt->prefix = prefix;
|
|
||||||
opt->prefix_length = (prefix && *prefix) ? strlen(prefix) : 0;
|
|
||||||
opt->pattern_tail = &opt->pattern_list;
|
opt->pattern_tail = &opt->pattern_list;
|
||||||
opt->header_tail = &opt->header_list;
|
opt->header_tail = &opt->header_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void grep_set_pattern_type_option(enum grep_pattern_type pattern_type, struct grep_opt *opt)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* When committing to the pattern type by setting the relevant
|
|
||||||
* fields in grep_opt it's generally not necessary to zero out
|
|
||||||
* the fields we're not choosing, since they won't have been
|
|
||||||
* set by anything. The extended_regexp_option field is the
|
|
||||||
* only exception to this.
|
|
||||||
*
|
|
||||||
* This is because in the process of parsing grep.patternType
|
|
||||||
* & grep.extendedRegexp we set opt->pattern_type_option and
|
|
||||||
* opt->extended_regexp_option, respectively. We then
|
|
||||||
* internally use opt->extended_regexp_option to see if we're
|
|
||||||
* compiling an ERE. It must be unset if that's not actually
|
|
||||||
* the case.
|
|
||||||
*/
|
|
||||||
if (pattern_type != GREP_PATTERN_TYPE_ERE &&
|
|
||||||
opt->extended_regexp_option)
|
|
||||||
opt->extended_regexp_option = 0;
|
|
||||||
|
|
||||||
switch (pattern_type) {
|
|
||||||
case GREP_PATTERN_TYPE_UNSPECIFIED:
|
|
||||||
/* fall through */
|
|
||||||
|
|
||||||
case GREP_PATTERN_TYPE_BRE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GREP_PATTERN_TYPE_ERE:
|
|
||||||
opt->extended_regexp_option = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GREP_PATTERN_TYPE_FIXED:
|
|
||||||
opt->fixed = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GREP_PATTERN_TYPE_PCRE:
|
|
||||||
opt->pcre2 = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
/*
|
|
||||||
* This branch *must* happen after setting from the
|
|
||||||
* opt->pattern_type_option above, we don't want
|
|
||||||
* grep.extendedRegexp to override grep.patternType!
|
|
||||||
*/
|
|
||||||
grep_set_pattern_type_option(GREP_PATTERN_TYPE_ERE, opt);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct grep_pat *create_grep_pat(const char *pat, size_t patlen,
|
static struct grep_pat *create_grep_pat(const char *pat, size_t patlen,
|
||||||
const char *origin, int no,
|
const char *origin, int no,
|
||||||
enum grep_pat_token t,
|
enum grep_pat_token t,
|
||||||
@ -523,11 +432,17 @@ static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
|
|||||||
int err;
|
int err;
|
||||||
int regflags = REG_NEWLINE;
|
int regflags = REG_NEWLINE;
|
||||||
|
|
||||||
|
if (opt->pattern_type_option == GREP_PATTERN_TYPE_UNSPECIFIED)
|
||||||
|
opt->pattern_type_option = (opt->extended_regexp_option
|
||||||
|
? GREP_PATTERN_TYPE_ERE
|
||||||
|
: GREP_PATTERN_TYPE_BRE);
|
||||||
|
|
||||||
p->word_regexp = opt->word_regexp;
|
p->word_regexp = opt->word_regexp;
|
||||||
p->ignore_case = opt->ignore_case;
|
p->ignore_case = opt->ignore_case;
|
||||||
p->fixed = opt->fixed;
|
p->fixed = opt->pattern_type_option == GREP_PATTERN_TYPE_FIXED;
|
||||||
|
|
||||||
if (memchr(p->pattern, 0, p->patternlen) && !opt->pcre2)
|
if (opt->pattern_type_option != GREP_PATTERN_TYPE_PCRE &&
|
||||||
|
memchr(p->pattern, 0, p->patternlen))
|
||||||
die(_("given pattern contains NULL byte (via -f <file>). This is only supported with -P under PCRE v2"));
|
die(_("given pattern contains NULL byte (via -f <file>). This is only supported with -P under PCRE v2"));
|
||||||
|
|
||||||
p->is_fixed = is_fixed(p->pattern, p->patternlen);
|
p->is_fixed = is_fixed(p->pattern, p->patternlen);
|
||||||
@ -578,14 +493,14 @@ static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt->pcre2) {
|
if (opt->pattern_type_option == GREP_PATTERN_TYPE_PCRE) {
|
||||||
compile_pcre2_pattern(p, opt);
|
compile_pcre2_pattern(p, opt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->ignore_case)
|
if (p->ignore_case)
|
||||||
regflags |= REG_ICASE;
|
regflags |= REG_ICASE;
|
||||||
if (opt->extended_regexp_option)
|
if (opt->pattern_type_option == GREP_PATTERN_TYPE_ERE)
|
||||||
regflags |= REG_EXTENDED;
|
regflags |= REG_EXTENDED;
|
||||||
err = regcomp(&p->regexp, p->pattern, regflags);
|
err = regcomp(&p->regexp, p->pattern, regflags);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
31
grep.h
31
grep.h
@ -134,9 +134,6 @@ struct grep_opt {
|
|||||||
*/
|
*/
|
||||||
struct repository *repo;
|
struct repository *repo;
|
||||||
|
|
||||||
const char *prefix;
|
|
||||||
int prefix_length;
|
|
||||||
regex_t regexp;
|
|
||||||
int linenum;
|
int linenum;
|
||||||
int columnnum;
|
int columnnum;
|
||||||
int invert;
|
int invert;
|
||||||
@ -146,7 +143,6 @@ struct grep_opt {
|
|||||||
int unmatch_name_only;
|
int unmatch_name_only;
|
||||||
int count;
|
int count;
|
||||||
int word_regexp;
|
int word_regexp;
|
||||||
int fixed;
|
|
||||||
int all_match;
|
int all_match;
|
||||||
int no_body_match;
|
int no_body_match;
|
||||||
int body_hit;
|
int body_hit;
|
||||||
@ -157,7 +153,6 @@ struct grep_opt {
|
|||||||
int allow_textconv;
|
int allow_textconv;
|
||||||
int extended;
|
int extended;
|
||||||
int use_reflog_filter;
|
int use_reflog_filter;
|
||||||
int pcre2;
|
|
||||||
int relative;
|
int relative;
|
||||||
int pathname;
|
int pathname;
|
||||||
int null_following_name;
|
int null_following_name;
|
||||||
@ -167,7 +162,7 @@ struct grep_opt {
|
|||||||
int funcname;
|
int funcname;
|
||||||
int funcbody;
|
int funcbody;
|
||||||
int extended_regexp_option;
|
int extended_regexp_option;
|
||||||
int pattern_type_option;
|
enum grep_pattern_type pattern_type_option;
|
||||||
int ignore_locale;
|
int ignore_locale;
|
||||||
char colors[NR_GREP_COLORS][COLOR_MAXLEN];
|
char colors[NR_GREP_COLORS][COLOR_MAXLEN];
|
||||||
unsigned pre_context;
|
unsigned pre_context;
|
||||||
@ -182,9 +177,29 @@ struct grep_opt {
|
|||||||
void *output_priv;
|
void *output_priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define GREP_OPT_INIT { \
|
||||||
|
.relative = 1, \
|
||||||
|
.pathname = 1, \
|
||||||
|
.max_depth = -1, \
|
||||||
|
.pattern_type_option = GREP_PATTERN_TYPE_UNSPECIFIED, \
|
||||||
|
.colors = { \
|
||||||
|
[GREP_COLOR_CONTEXT] = "", \
|
||||||
|
[GREP_COLOR_FILENAME] = GIT_COLOR_MAGENTA, \
|
||||||
|
[GREP_COLOR_FUNCTION] = "", \
|
||||||
|
[GREP_COLOR_LINENO] = GIT_COLOR_GREEN, \
|
||||||
|
[GREP_COLOR_COLUMNNO] = GIT_COLOR_GREEN, \
|
||||||
|
[GREP_COLOR_MATCH_CONTEXT] = GIT_COLOR_BOLD_RED, \
|
||||||
|
[GREP_COLOR_MATCH_SELECTED] = GIT_COLOR_BOLD_RED, \
|
||||||
|
[GREP_COLOR_SELECTED] = "", \
|
||||||
|
[GREP_COLOR_SEP] = GIT_COLOR_CYAN, \
|
||||||
|
}, \
|
||||||
|
.only_matching = 0, \
|
||||||
|
.color = -1, \
|
||||||
|
.output = std_output, \
|
||||||
|
}
|
||||||
|
|
||||||
int grep_config(const char *var, const char *value, void *);
|
int grep_config(const char *var, const char *value, void *);
|
||||||
void grep_init(struct grep_opt *, struct repository *repo, const char *prefix);
|
void grep_init(struct grep_opt *, struct repository *repo);
|
||||||
void grep_commit_pattern_type(enum grep_pattern_type, struct grep_opt *opt);
|
|
||||||
|
|
||||||
void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen, const char *origin, int no, enum grep_pat_token t);
|
void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen, const char *origin, int no, enum grep_pat_token t);
|
||||||
void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t);
|
void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t);
|
||||||
|
@ -1846,7 +1846,7 @@ void repo_init_revisions(struct repository *r,
|
|||||||
revs->commit_format = CMIT_FMT_DEFAULT;
|
revs->commit_format = CMIT_FMT_DEFAULT;
|
||||||
revs->expand_tabs_in_log_default = 8;
|
revs->expand_tabs_in_log_default = 8;
|
||||||
|
|
||||||
grep_init(&revs->grep_filter, revs->repo, prefix);
|
grep_init(&revs->grep_filter, revs->repo);
|
||||||
revs->grep_filter.status_only = 1;
|
revs->grep_filter.status_only = 1;
|
||||||
|
|
||||||
repo_diff_setup(revs->repo, &revs->diffopt);
|
repo_diff_setup(revs->repo, &revs->diffopt);
|
||||||
@ -2882,8 +2882,6 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
|
|||||||
|
|
||||||
diff_setup_done(&revs->diffopt);
|
diff_setup_done(&revs->diffopt);
|
||||||
|
|
||||||
grep_commit_pattern_type(GREP_PATTERN_TYPE_UNSPECIFIED,
|
|
||||||
&revs->grep_filter);
|
|
||||||
if (!is_encoding_utf8(get_log_output_encoding()))
|
if (!is_encoding_utf8(get_log_output_encoding()))
|
||||||
revs->grep_filter.ignore_locale = 1;
|
revs->grep_filter.ignore_locale = 1;
|
||||||
compile_grep_patterns(&revs->grep_filter);
|
compile_grep_patterns(&revs->grep_filter);
|
||||||
|
@ -462,6 +462,30 @@ test_expect_success !FAIL_PREREQS 'log with various grep.patternType configurati
|
|||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
|
for cmd in show whatchanged reflog format-patch
|
||||||
|
do
|
||||||
|
case "$cmd" in
|
||||||
|
format-patch) myarg="HEAD~.." ;;
|
||||||
|
*) myarg= ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
test_expect_success "$cmd: understands grep.patternType, like 'log'" '
|
||||||
|
git init "pattern-type-$cmd" &&
|
||||||
|
(
|
||||||
|
cd "pattern-type-$cmd" &&
|
||||||
|
test_commit 1 file A &&
|
||||||
|
test_commit "(1|2)" file B 2 &&
|
||||||
|
|
||||||
|
git -c grep.patternType=fixed $cmd --grep="..." $myarg >actual &&
|
||||||
|
test_must_be_empty actual &&
|
||||||
|
|
||||||
|
git -c grep.patternType=basic $cmd --grep="..." $myarg >actual &&
|
||||||
|
test_file_not_empty actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
done
|
||||||
|
test_done
|
||||||
|
|
||||||
test_expect_success 'log --author' '
|
test_expect_success 'log --author' '
|
||||||
cat >expect <<-\EOF &&
|
cat >expect <<-\EOF &&
|
||||||
Author: <BOLD;RED>A U<RESET> Thor <author@example.com>
|
Author: <BOLD;RED>A U<RESET> Thor <author@example.com>
|
||||||
|
176
t/t7810-grep.sh
176
t/t7810-grep.sh
@ -98,6 +98,37 @@ test_expect_success 'grep should not segfault with a bad input' '
|
|||||||
|
|
||||||
test_invalid_grep_expression --and -e A
|
test_invalid_grep_expression --and -e A
|
||||||
|
|
||||||
|
test_pattern_type () {
|
||||||
|
H=$1 &&
|
||||||
|
HC=$2 &&
|
||||||
|
L=$3 &&
|
||||||
|
type=$4 &&
|
||||||
|
shift 4 &&
|
||||||
|
|
||||||
|
expected_str= &&
|
||||||
|
case "$type" in
|
||||||
|
BRE)
|
||||||
|
expected_str="${HC}ab:a+bc"
|
||||||
|
;;
|
||||||
|
ERE)
|
||||||
|
expected_str="${HC}ab:abc"
|
||||||
|
;;
|
||||||
|
FIX)
|
||||||
|
expected_str="${HC}ab:a+b*c"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
BUG "unknown pattern type '$type'"
|
||||||
|
;;
|
||||||
|
esac &&
|
||||||
|
config_str="$@" &&
|
||||||
|
|
||||||
|
test_expect_success "grep $L with '$config_str' interpreted as $type" '
|
||||||
|
echo $expected_str >expected &&
|
||||||
|
git $config_str grep "a+b*c" $H ab >actual &&
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
}
|
||||||
|
|
||||||
for H in HEAD ''
|
for H in HEAD ''
|
||||||
do
|
do
|
||||||
case "$H" in
|
case "$H" in
|
||||||
@ -393,35 +424,13 @@ do
|
|||||||
git grep --no-recursive -n -e vvv $H -- t . >actual &&
|
git grep --no-recursive -n -e vvv $H -- t . >actual &&
|
||||||
test_cmp expected actual
|
test_cmp expected actual
|
||||||
'
|
'
|
||||||
test_expect_success "grep $L with grep.extendedRegexp=false" '
|
|
||||||
echo "${HC}ab:a+bc" >expected &&
|
|
||||||
git -c grep.extendedRegexp=false grep "a+b*c" $H ab >actual &&
|
|
||||||
test_cmp expected actual
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success "grep $L with grep.extendedRegexp=true" '
|
|
||||||
echo "${HC}ab:abc" >expected &&
|
|
||||||
git -c grep.extendedRegexp=true grep "a+b*c" $H ab >actual &&
|
|
||||||
test_cmp expected actual
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success "grep $L with grep.patterntype=basic" '
|
test_pattern_type "$H" "$HC" "$L" BRE -c grep.extendedRegexp=false
|
||||||
echo "${HC}ab:a+bc" >expected &&
|
test_pattern_type "$H" "$HC" "$L" ERE -c grep.extendedRegexp=true
|
||||||
git -c grep.patterntype=basic grep "a+b*c" $H ab >actual &&
|
test_pattern_type "$H" "$HC" "$L" BRE -c grep.patternType=basic
|
||||||
test_cmp expected actual
|
test_pattern_type "$H" "$HC" "$L" ERE -c grep.patternType=extended
|
||||||
'
|
test_pattern_type "$H" "$HC" "$L" FIX -c grep.patternType=fixed
|
||||||
|
|
||||||
test_expect_success "grep $L with grep.patterntype=extended" '
|
|
||||||
echo "${HC}ab:abc" >expected &&
|
|
||||||
git -c grep.patterntype=extended grep "a+b*c" $H ab >actual &&
|
|
||||||
test_cmp expected actual
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success "grep $L with grep.patterntype=fixed" '
|
|
||||||
echo "${HC}ab:a+b*c" >expected &&
|
|
||||||
git -c grep.patterntype=fixed grep "a+b*c" $H ab >actual &&
|
|
||||||
test_cmp expected actual
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success PCRE "grep $L with grep.patterntype=perl" '
|
test_expect_success PCRE "grep $L with grep.patterntype=perl" '
|
||||||
echo "${HC}ab:a+b*c" >expected &&
|
echo "${HC}ab:a+b*c" >expected &&
|
||||||
@ -433,59 +442,76 @@ do
|
|||||||
test_must_fail git -c grep.patterntype=perl grep "foo.*bar"
|
test_must_fail git -c grep.patterntype=perl grep "foo.*bar"
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success "grep $L with grep.patternType=default and grep.extendedRegexp=true" '
|
test_pattern_type "$H" "$HC" "$L" ERE \
|
||||||
echo "${HC}ab:abc" >expected &&
|
-c grep.patternType=default \
|
||||||
git \
|
-c grep.extendedRegexp=true
|
||||||
-c grep.patternType=default \
|
test_pattern_type "$H" "$HC" "$L" ERE \
|
||||||
-c grep.extendedRegexp=true \
|
-c grep.extendedRegexp=true \
|
||||||
grep "a+b*c" $H ab >actual &&
|
-c grep.patternType=default
|
||||||
test_cmp expected actual
|
test_pattern_type "$H" "$HC" "$L" ERE \
|
||||||
'
|
-c grep.patternType=extended \
|
||||||
|
-c grep.extendedRegexp=false
|
||||||
|
test_pattern_type "$H" "$HC" "$L" BRE \
|
||||||
|
-c grep.patternType=basic \
|
||||||
|
-c grep.extendedRegexp=true
|
||||||
|
test_pattern_type "$H" "$HC" "$L" ERE \
|
||||||
|
-c grep.extendedRegexp=false \
|
||||||
|
-c grep.patternType=extended
|
||||||
|
test_pattern_type "$H" "$HC" "$L" BRE \
|
||||||
|
-c grep.extendedRegexp=true \
|
||||||
|
-c grep.patternType=basic
|
||||||
|
|
||||||
test_expect_success "grep $L with grep.extendedRegexp=true and grep.patternType=default" '
|
# grep.extendedRegexp is last-one-wins
|
||||||
echo "${HC}ab:abc" >expected &&
|
test_pattern_type "$H" "$HC" "$L" BRE \
|
||||||
git \
|
-c grep.extendedRegexp=true \
|
||||||
-c grep.extendedRegexp=true \
|
-c grep.extendedRegexp=false
|
||||||
-c grep.patternType=default \
|
|
||||||
grep "a+b*c" $H ab >actual &&
|
|
||||||
test_cmp expected actual
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success "grep $L with grep.patternType=extended and grep.extendedRegexp=false" '
|
# grep.patternType=basic pays no attention to grep.extendedRegexp
|
||||||
echo "${HC}ab:abc" >expected &&
|
test_pattern_type "$H" "$HC" "$L" BRE \
|
||||||
git \
|
-c grep.extendedRegexp=true \
|
||||||
-c grep.patternType=extended \
|
-c grep.patternType=basic \
|
||||||
-c grep.extendedRegexp=false \
|
-c grep.extendedRegexp=false
|
||||||
grep "a+b*c" $H ab >actual &&
|
|
||||||
test_cmp expected actual
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success "grep $L with grep.patternType=basic and grep.extendedRegexp=true" '
|
# grep.patternType=extended pays no attention to grep.extendedRegexp
|
||||||
echo "${HC}ab:a+bc" >expected &&
|
test_pattern_type "$H" "$HC" "$L" ERE \
|
||||||
git \
|
-c grep.extendedRegexp=true \
|
||||||
-c grep.patternType=basic \
|
-c grep.patternType=extended \
|
||||||
-c grep.extendedRegexp=true \
|
-c grep.extendedRegexp=false
|
||||||
grep "a+b*c" $H ab >actual &&
|
|
||||||
test_cmp expected actual
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success "grep $L with grep.extendedRegexp=false and grep.patternType=extended" '
|
# grep.extendedRegexp is used with a last-one-wins grep.patternType=default
|
||||||
echo "${HC}ab:abc" >expected &&
|
test_pattern_type "$H" "$HC" "$L" ERE \
|
||||||
git \
|
-c grep.patternType=fixed \
|
||||||
-c grep.extendedRegexp=false \
|
-c grep.extendedRegexp=true \
|
||||||
-c grep.patternType=extended \
|
-c grep.patternType=default
|
||||||
grep "a+b*c" $H ab >actual &&
|
|
||||||
test_cmp expected actual
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success "grep $L with grep.extendedRegexp=true and grep.patternType=basic" '
|
# grep.extendedRegexp is used with earlier grep.patternType=default
|
||||||
echo "${HC}ab:a+bc" >expected &&
|
test_pattern_type "$H" "$HC" "$L" ERE \
|
||||||
git \
|
-c grep.extendedRegexp=false \
|
||||||
-c grep.extendedRegexp=true \
|
-c grep.patternType=default \
|
||||||
-c grep.patternType=basic \
|
-c grep.extendedRegexp=true
|
||||||
grep "a+b*c" $H ab >actual &&
|
|
||||||
test_cmp expected actual
|
# grep.extendedRegexp is used with a last-one-loses grep.patternType=default
|
||||||
'
|
test_pattern_type "$H" "$HC" "$L" ERE \
|
||||||
|
-c grep.extendedRegexp=false \
|
||||||
|
-c grep.extendedRegexp=true \
|
||||||
|
-c grep.patternType=default
|
||||||
|
|
||||||
|
# grep.extendedRegexp and grep.patternType are both last-one-wins independently
|
||||||
|
test_pattern_type "$H" "$HC" "$L" BRE \
|
||||||
|
-c grep.patternType=default \
|
||||||
|
-c grep.extendedRegexp=true \
|
||||||
|
-c grep.patternType=basic
|
||||||
|
|
||||||
|
# grep.patternType=extended and grep.patternType=default
|
||||||
|
test_pattern_type "$H" "$HC" "$L" BRE \
|
||||||
|
-c grep.patternType=extended \
|
||||||
|
-c grep.patternType=default
|
||||||
|
|
||||||
|
# grep.patternType=[extended -> default -> fixed] (BRE)" '
|
||||||
|
test_pattern_type "$H" "$HC" "$L" FIX \
|
||||||
|
-c grep.patternType=extended \
|
||||||
|
-c grep.patternType=default \
|
||||||
|
-c grep.patternType=fixed
|
||||||
|
|
||||||
test_expect_success "grep --count $L" '
|
test_expect_success "grep --count $L" '
|
||||||
echo ${HC}ab:3 >expected &&
|
echo ${HC}ab:3 >expected &&
|
||||||
|
Loading…
Reference in New Issue
Block a user