Skip to content

Commit 2043ce8

Browse files
committed
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
2 parents 2a6c7f9 + 794c000 commit 2043ce8

File tree

5 files changed

+42
-7
lines changed

5 files changed

+42
-7
lines changed

grep.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,14 @@ static struct grep_expr *compile_pattern_expr(struct grep_pat **list)
699699
return compile_pattern_or(list);
700700
}
701701

702+
static struct grep_expr *grep_not_expr(struct grep_expr *expr)
703+
{
704+
struct grep_expr *z = xcalloc(1, sizeof(*z));
705+
z->node = GREP_NODE_NOT;
706+
z->u.unary = expr;
707+
return z;
708+
}
709+
702710
static struct grep_expr *grep_true_expr(void)
703711
{
704712
struct grep_expr *z = xcalloc(1, sizeof(*z));
@@ -797,7 +805,7 @@ void compile_grep_patterns(struct grep_opt *opt)
797805
}
798806
}
799807

800-
if (opt->all_match || header_expr)
808+
if (opt->all_match || opt->no_body_match || header_expr)
801809
opt->extended = 1;
802810
else if (!opt->extended)
803811
return;
@@ -808,6 +816,9 @@ void compile_grep_patterns(struct grep_opt *opt)
808816
if (p)
809817
die("incomplete pattern expression: %s", p->pattern);
810818

819+
if (opt->no_body_match && opt->pattern_expression)
820+
opt->pattern_expression = grep_not_expr(opt->pattern_expression);
821+
811822
if (!header_expr)
812823
return;
813824

@@ -1057,6 +1068,8 @@ static int match_expr_eval(struct grep_opt *opt, struct grep_expr *x,
10571068
if (h && (*col < 0 || tmp.rm_so < *col))
10581069
*col = tmp.rm_so;
10591070
}
1071+
if (x->u.atom->token == GREP_PATTERN_BODY)
1072+
opt->body_hit |= h;
10601073
break;
10611074
case GREP_NODE_NOT:
10621075
/*
@@ -1825,16 +1838,19 @@ int grep_source(struct grep_opt *opt, struct grep_source *gs)
18251838
* we do not have to do the two-pass grep when we do not check
18261839
* buffer-wide "all-match".
18271840
*/
1828-
if (!opt->all_match)
1841+
if (!opt->all_match && !opt->no_body_match)
18291842
return grep_source_1(opt, gs, 0);
18301843

18311844
/* Otherwise the toplevel "or" terms hit a bit differently.
18321845
* We first clear hit markers from them.
18331846
*/
18341847
clr_hit_marker(opt->pattern_expression);
1848+
opt->body_hit = 0;
18351849
grep_source_1(opt, gs, 1);
18361850

1837-
if (!chk_hit_marker(opt->pattern_expression))
1851+
if (opt->all_match && !chk_hit_marker(opt->pattern_expression))
1852+
return 0;
1853+
if (opt->no_body_match && opt->body_hit)
18381854
return 0;
18391855

18401856
return grep_source_1(opt, gs, 0);

grep.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ struct grep_opt {
148148
int word_regexp;
149149
int fixed;
150150
int all_match;
151+
int no_body_match;
152+
int body_hit;
151153
#define GREP_BINARY_DEFAULT 0
152154
#define GREP_BINARY_NOMATCH 1
153155
#define GREP_BINARY_TEXT 2

revision.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2498,7 +2498,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
24982498
} else if (!strcmp(arg, "--all-match")) {
24992499
revs->grep_filter.all_match = 1;
25002500
} else if (!strcmp(arg, "--invert-grep")) {
2501-
revs->invert_grep = 1;
2501+
revs->grep_filter.no_body_match = 1;
25022502
} else if ((argcount = parse_long_opt("encoding", argv, &optarg))) {
25032503
if (strcmp(optarg, "none"))
25042504
git_log_output_encoding = xstrdup(optarg);
@@ -3783,7 +3783,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt)
37833783
(char *)message, strlen(message));
37843784
strbuf_release(&buf);
37853785
unuse_commit_buffer(commit, message);
3786-
return opt->invert_grep ? !retval : retval;
3786+
return retval;
37873787
}
37883788

37893789
static inline int want_ancestry(const struct rev_info *revs)

revision.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,6 @@ struct rev_info {
246246

247247
/* Filter by commit log message */
248248
struct grep_opt grep_filter;
249-
/* Negate the match of grep_filter */
250-
int invert_grep;
251249

252250
/* Display history graph */
253251
struct git_graph *graph;

t/t4202-log.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2090,4 +2090,23 @@ test_expect_success 'log --end-of-options' '
20902090
test_cmp expect actual
20912091
'
20922092

2093+
test_expect_success 'set up commits with different authors' '
2094+
git checkout --orphan authors &&
2095+
test_commit --author "Jim <[email protected]>" jim_1 &&
2096+
test_commit --author "Val <[email protected]>" val_1 &&
2097+
test_commit --author "Val <[email protected]>" val_2 &&
2098+
test_commit --author "Jim <[email protected]>" jim_2 &&
2099+
test_commit --author "Val <[email protected]>" val_3 &&
2100+
test_commit --author "Jim <[email protected]>" jim_3
2101+
'
2102+
2103+
test_expect_success 'log --invert-grep --grep --author' '
2104+
cat >expect <<-\EOF &&
2105+
val_3
2106+
val_1
2107+
EOF
2108+
git log --format=%s --author=Val --grep 2 --invert-grep >actual &&
2109+
test_cmp expect actual
2110+
'
2111+
20932112
test_done

0 commit comments

Comments
 (0)