Merge branch 'jc/grep-author-all-match-implicit' into maint
* jc/grep-author-all-match-implicit: "log --author=me --grep=it" should find intersection, not union
This commit is contained in:
commit
1f54d693fd
@ -844,6 +844,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||||||
opt.relative = 1;
|
opt.relative = 1;
|
||||||
opt.pathname = 1;
|
opt.pathname = 1;
|
||||||
opt.pattern_tail = &opt.pattern_list;
|
opt.pattern_tail = &opt.pattern_list;
|
||||||
|
opt.header_tail = &opt.header_list;
|
||||||
opt.regflags = REG_NEWLINE;
|
opt.regflags = REG_NEWLINE;
|
||||||
opt.max_depth = -1;
|
opt.max_depth = -1;
|
||||||
|
|
||||||
|
@ -371,8 +371,9 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
|
|||||||
revs.diff)
|
revs.diff)
|
||||||
usage(rev_list_usage);
|
usage(rev_list_usage);
|
||||||
|
|
||||||
save_commit_buffer = revs.verbose_header ||
|
save_commit_buffer = (revs.verbose_header ||
|
||||||
revs.grep_filter.pattern_list;
|
revs.grep_filter.pattern_list ||
|
||||||
|
revs.grep_filter.header_list);
|
||||||
if (bisect_list)
|
if (bisect_list)
|
||||||
revs.limited = 1;
|
revs.limited = 1;
|
||||||
|
|
||||||
|
44
grep.c
44
grep.c
@ -11,8 +11,8 @@ void append_header_grep_pattern(struct grep_opt *opt, enum grep_header_field fie
|
|||||||
p->no = 0;
|
p->no = 0;
|
||||||
p->token = GREP_PATTERN_HEAD;
|
p->token = GREP_PATTERN_HEAD;
|
||||||
p->field = field;
|
p->field = field;
|
||||||
*opt->pattern_tail = p;
|
*opt->header_tail = p;
|
||||||
opt->pattern_tail = &p->next;
|
opt->header_tail = &p->next;
|
||||||
p->next = NULL;
|
p->next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,9 +184,26 @@ static struct grep_expr *compile_pattern_expr(struct grep_pat **list)
|
|||||||
void compile_grep_patterns(struct grep_opt *opt)
|
void compile_grep_patterns(struct grep_opt *opt)
|
||||||
{
|
{
|
||||||
struct grep_pat *p;
|
struct grep_pat *p;
|
||||||
|
struct grep_expr *header_expr = NULL;
|
||||||
|
|
||||||
if (opt->all_match)
|
if (opt->header_list) {
|
||||||
opt->extended = 1;
|
p = opt->header_list;
|
||||||
|
header_expr = compile_pattern_expr(&p);
|
||||||
|
if (p)
|
||||||
|
die("incomplete pattern expression: %s", p->pattern);
|
||||||
|
for (p = opt->header_list; p; p = p->next) {
|
||||||
|
switch (p->token) {
|
||||||
|
case GREP_PATTERN: /* atom */
|
||||||
|
case GREP_PATTERN_HEAD:
|
||||||
|
case GREP_PATTERN_BODY:
|
||||||
|
compile_regexp(p, opt);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
opt->extended = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (p = opt->pattern_list; p; p = p->next) {
|
for (p = opt->pattern_list; p; p = p->next) {
|
||||||
switch (p->token) {
|
switch (p->token) {
|
||||||
@ -201,7 +218,9 @@ void compile_grep_patterns(struct grep_opt *opt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!opt->extended)
|
if (opt->all_match || header_expr)
|
||||||
|
opt->extended = 1;
|
||||||
|
else if (!opt->extended)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Then bundle them up in an expression.
|
/* Then bundle them up in an expression.
|
||||||
@ -212,6 +231,21 @@ void compile_grep_patterns(struct grep_opt *opt)
|
|||||||
opt->pattern_expression = compile_pattern_expr(&p);
|
opt->pattern_expression = compile_pattern_expr(&p);
|
||||||
if (p)
|
if (p)
|
||||||
die("incomplete pattern expression: %s", p->pattern);
|
die("incomplete pattern expression: %s", p->pattern);
|
||||||
|
|
||||||
|
if (!header_expr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (opt->pattern_expression) {
|
||||||
|
struct grep_expr *z;
|
||||||
|
z = xcalloc(1, sizeof(*z));
|
||||||
|
z->node = GREP_NODE_OR;
|
||||||
|
z->u.binary.left = opt->pattern_expression;
|
||||||
|
z->u.binary.right = header_expr;
|
||||||
|
opt->pattern_expression = z;
|
||||||
|
} else {
|
||||||
|
opt->pattern_expression = header_expr;
|
||||||
|
}
|
||||||
|
opt->all_match = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_pattern_expr(struct grep_expr *x)
|
static void free_pattern_expr(struct grep_expr *x)
|
||||||
|
2
grep.h
2
grep.h
@ -59,6 +59,8 @@ struct grep_expr {
|
|||||||
struct grep_opt {
|
struct grep_opt {
|
||||||
struct grep_pat *pattern_list;
|
struct grep_pat *pattern_list;
|
||||||
struct grep_pat **pattern_tail;
|
struct grep_pat **pattern_tail;
|
||||||
|
struct grep_pat *header_list;
|
||||||
|
struct grep_pat **header_tail;
|
||||||
struct grep_expr *pattern_expression;
|
struct grep_expr *pattern_expression;
|
||||||
const char *prefix;
|
const char *prefix;
|
||||||
int prefix_length;
|
int prefix_length;
|
||||||
|
@ -826,6 +826,7 @@ void init_revisions(struct rev_info *revs, const char *prefix)
|
|||||||
|
|
||||||
revs->grep_filter.status_only = 1;
|
revs->grep_filter.status_only = 1;
|
||||||
revs->grep_filter.pattern_tail = &(revs->grep_filter.pattern_list);
|
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;
|
revs->grep_filter.regflags = REG_NEWLINE;
|
||||||
|
|
||||||
diff_setup(&revs->diffopt);
|
diff_setup(&revs->diffopt);
|
||||||
@ -1804,7 +1805,7 @@ static int rewrite_parents(struct rev_info *revs, struct commit *commit)
|
|||||||
|
|
||||||
static int commit_match(struct commit *commit, struct rev_info *opt)
|
static int commit_match(struct commit *commit, struct rev_info *opt)
|
||||||
{
|
{
|
||||||
if (!opt->grep_filter.pattern_list)
|
if (!opt->grep_filter.pattern_list && !opt->grep_filter.header_list)
|
||||||
return 1;
|
return 1;
|
||||||
return grep_buffer(&opt->grep_filter,
|
return grep_buffer(&opt->grep_filter,
|
||||||
NULL, /* we say nothing, not even filename */
|
NULL, /* we say nothing, not even filename */
|
||||||
|
@ -353,7 +353,7 @@ test_expect_success 'log grep (4)' '
|
|||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'log grep (5)' '
|
test_expect_success 'log grep (5)' '
|
||||||
git log --author=Thor -F --grep=Thu --pretty=tformat:%s >actual &&
|
git log --author=Thor -F --pretty=tformat:%s >actual &&
|
||||||
( echo third ; echo initial ) >expect &&
|
( echo third ; echo initial ) >expect &&
|
||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
@ -364,6 +364,14 @@ test_expect_success 'log grep (6)' '
|
|||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'log --grep --author implicitly uses all-match' '
|
||||||
|
# grep matches initial and second but not third
|
||||||
|
# author matches only initial and third
|
||||||
|
git log --author="A U Thor" --grep=s --grep=l --format=%s >actual &&
|
||||||
|
echo initial >expect &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'grep with CE_VALID file' '
|
test_expect_success 'grep with CE_VALID file' '
|
||||||
git update-index --assume-unchanged t/t &&
|
git update-index --assume-unchanged t/t &&
|
||||||
rm t/t &&
|
rm t/t &&
|
||||||
|
Loading…
Reference in New Issue
Block a user