mirror of
https://github.com/git/git.git
synced 2024-06-09 15:16:11 +02:00
Merge branch 'rs/log-invert-grep-with-headers'
"git log --invert-grep --author=<name>" used to exclude commits written by the given author, but now "--invert-grep" only affects the matches made by the "--grep=<pattern>" option. * rs/log-invert-grep-with-headers: log: let --invert-grep only invert --grep
This commit is contained in:
commit
2043ce828e
22
grep.c
22
grep.c
|
@ -699,6 +699,14 @@ static struct grep_expr *compile_pattern_expr(struct grep_pat **list)
|
|||
return compile_pattern_or(list);
|
||||
}
|
||||
|
||||
static struct grep_expr *grep_not_expr(struct grep_expr *expr)
|
||||
{
|
||||
struct grep_expr *z = xcalloc(1, sizeof(*z));
|
||||
z->node = GREP_NODE_NOT;
|
||||
z->u.unary = expr;
|
||||
return z;
|
||||
}
|
||||
|
||||
static struct grep_expr *grep_true_expr(void)
|
||||
{
|
||||
struct grep_expr *z = xcalloc(1, sizeof(*z));
|
||||
|
@ -797,7 +805,7 @@ void compile_grep_patterns(struct grep_opt *opt)
|
|||
}
|
||||
}
|
||||
|
||||
if (opt->all_match || header_expr)
|
||||
if (opt->all_match || opt->no_body_match || header_expr)
|
||||
opt->extended = 1;
|
||||
else if (!opt->extended)
|
||||
return;
|
||||
|
@ -808,6 +816,9 @@ void compile_grep_patterns(struct grep_opt *opt)
|
|||
if (p)
|
||||
die("incomplete pattern expression: %s", p->pattern);
|
||||
|
||||
if (opt->no_body_match && opt->pattern_expression)
|
||||
opt->pattern_expression = grep_not_expr(opt->pattern_expression);
|
||||
|
||||
if (!header_expr)
|
||||
return;
|
||||
|
||||
|
@ -1057,6 +1068,8 @@ static int match_expr_eval(struct grep_opt *opt, struct grep_expr *x,
|
|||
if (h && (*col < 0 || tmp.rm_so < *col))
|
||||
*col = tmp.rm_so;
|
||||
}
|
||||
if (x->u.atom->token == GREP_PATTERN_BODY)
|
||||
opt->body_hit |= h;
|
||||
break;
|
||||
case GREP_NODE_NOT:
|
||||
/*
|
||||
|
@ -1825,16 +1838,19 @@ int grep_source(struct grep_opt *opt, struct grep_source *gs)
|
|||
* we do not have to do the two-pass grep when we do not check
|
||||
* buffer-wide "all-match".
|
||||
*/
|
||||
if (!opt->all_match)
|
||||
if (!opt->all_match && !opt->no_body_match)
|
||||
return grep_source_1(opt, gs, 0);
|
||||
|
||||
/* Otherwise the toplevel "or" terms hit a bit differently.
|
||||
* We first clear hit markers from them.
|
||||
*/
|
||||
clr_hit_marker(opt->pattern_expression);
|
||||
opt->body_hit = 0;
|
||||
grep_source_1(opt, gs, 1);
|
||||
|
||||
if (!chk_hit_marker(opt->pattern_expression))
|
||||
if (opt->all_match && !chk_hit_marker(opt->pattern_expression))
|
||||
return 0;
|
||||
if (opt->no_body_match && opt->body_hit)
|
||||
return 0;
|
||||
|
||||
return grep_source_1(opt, gs, 0);
|
||||
|
|
2
grep.h
2
grep.h
|
@ -148,6 +148,8 @@ struct grep_opt {
|
|||
int word_regexp;
|
||||
int fixed;
|
||||
int all_match;
|
||||
int no_body_match;
|
||||
int body_hit;
|
||||
#define GREP_BINARY_DEFAULT 0
|
||||
#define GREP_BINARY_NOMATCH 1
|
||||
#define GREP_BINARY_TEXT 2
|
||||
|
|
|
@ -2498,7 +2498,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
|
|||
} else if (!strcmp(arg, "--all-match")) {
|
||||
revs->grep_filter.all_match = 1;
|
||||
} else if (!strcmp(arg, "--invert-grep")) {
|
||||
revs->invert_grep = 1;
|
||||
revs->grep_filter.no_body_match = 1;
|
||||
} else if ((argcount = parse_long_opt("encoding", argv, &optarg))) {
|
||||
if (strcmp(optarg, "none"))
|
||||
git_log_output_encoding = xstrdup(optarg);
|
||||
|
@ -3783,7 +3783,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt)
|
|||
(char *)message, strlen(message));
|
||||
strbuf_release(&buf);
|
||||
unuse_commit_buffer(commit, message);
|
||||
return opt->invert_grep ? !retval : retval;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static inline int want_ancestry(const struct rev_info *revs)
|
||||
|
|
|
@ -246,8 +246,6 @@ struct rev_info {
|
|||
|
||||
/* Filter by commit log message */
|
||||
struct grep_opt grep_filter;
|
||||
/* Negate the match of grep_filter */
|
||||
int invert_grep;
|
||||
|
||||
/* Display history graph */
|
||||
struct git_graph *graph;
|
||||
|
|
|
@ -2090,4 +2090,23 @@ test_expect_success 'log --end-of-options' '
|
|||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'set up commits with different authors' '
|
||||
git checkout --orphan authors &&
|
||||
test_commit --author "Jim <jim@example.com>" jim_1 &&
|
||||
test_commit --author "Val <val@example.com>" val_1 &&
|
||||
test_commit --author "Val <val@example.com>" val_2 &&
|
||||
test_commit --author "Jim <jim@example.com>" jim_2 &&
|
||||
test_commit --author "Val <val@example.com>" val_3 &&
|
||||
test_commit --author "Jim <jim@example.com>" jim_3
|
||||
'
|
||||
|
||||
test_expect_success 'log --invert-grep --grep --author' '
|
||||
cat >expect <<-\EOF &&
|
||||
val_3
|
||||
val_1
|
||||
EOF
|
||||
git log --format=%s --author=Val --grep 2 --invert-grep >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_done
|
||||
|
|
Loading…
Reference in New Issue