Merge branch 'nd/grep-reflog'
Teach the commands from the "log" family the "--grep-reflog" option to limit output by string that appears in the reflog entry when the "--walk-reflogs" option is in effect. * nd/grep-reflog: revision: make --grep search in notes too if shown log --grep-reflog: reject the option without -g revision: add --grep-reflog to filter commits by reflog messages grep: prepare for new header field filter
This commit is contained in:
commit
fa11d7c879
@ -51,6 +51,14 @@ endif::git-rev-list[]
|
|||||||
commits whose author matches any of the given patterns are
|
commits whose author matches any of the given patterns are
|
||||||
chosen (similarly for multiple `--committer=<pattern>`).
|
chosen (similarly for multiple `--committer=<pattern>`).
|
||||||
|
|
||||||
|
--grep-reflog=<pattern>::
|
||||||
|
|
||||||
|
Limit the commits output to ones with reflog entries that
|
||||||
|
match the specified pattern (regular expression). With
|
||||||
|
more than one `--grep-reflog`, commits whose reflog message
|
||||||
|
matches any of the given patterns are chosen. It is an
|
||||||
|
error to use this option unless `--walk-reflogs` is in use.
|
||||||
|
|
||||||
--grep=<pattern>::
|
--grep=<pattern>::
|
||||||
|
|
||||||
Limit the commits output to ones with log message that
|
Limit the commits output to ones with log message that
|
||||||
@ -58,6 +66,9 @@ endif::git-rev-list[]
|
|||||||
more than one `--grep=<pattern>`, commits whose message
|
more than one `--grep=<pattern>`, commits whose message
|
||||||
matches any of the given patterns are chosen (but see
|
matches any of the given patterns are chosen (but see
|
||||||
`--all-match`).
|
`--all-match`).
|
||||||
|
+
|
||||||
|
When `--show-notes` is in effect, the message from the notes as
|
||||||
|
if it is part of the log message.
|
||||||
|
|
||||||
--all-match::
|
--all-match::
|
||||||
Limit the commits output to ones that match all given --grep,
|
Limit the commits output to ones that match all given --grep,
|
||||||
|
12
grep.c
12
grep.c
@ -64,6 +64,8 @@ void append_header_grep_pattern(struct grep_opt *opt,
|
|||||||
{
|
{
|
||||||
struct grep_pat *p = create_grep_pat(pat, strlen(pat), "header", 0,
|
struct grep_pat *p = create_grep_pat(pat, strlen(pat), "header", 0,
|
||||||
GREP_PATTERN_HEAD, field);
|
GREP_PATTERN_HEAD, field);
|
||||||
|
if (field == GREP_HEADER_REFLOG)
|
||||||
|
opt->use_reflog_filter = 1;
|
||||||
do_append_grep_pat(&opt->header_tail, p);
|
do_append_grep_pat(&opt->header_tail, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -697,6 +699,7 @@ static struct {
|
|||||||
} header_field[] = {
|
} header_field[] = {
|
||||||
{ "author ", 7 },
|
{ "author ", 7 },
|
||||||
{ "committer ", 10 },
|
{ "committer ", 10 },
|
||||||
|
{ "reflog ", 7 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
|
static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
|
||||||
@ -720,7 +723,14 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
|
|||||||
if (strncmp(bol, field, len))
|
if (strncmp(bol, field, len))
|
||||||
return 0;
|
return 0;
|
||||||
bol += len;
|
bol += len;
|
||||||
saved_ch = strip_timestamp(bol, &eol);
|
switch (p->field) {
|
||||||
|
case GREP_HEADER_AUTHOR:
|
||||||
|
case GREP_HEADER_COMMITTER:
|
||||||
|
saved_ch = strip_timestamp(bol, &eol);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
again:
|
again:
|
||||||
|
8
grep.h
8
grep.h
@ -29,9 +29,12 @@ enum grep_context {
|
|||||||
|
|
||||||
enum grep_header_field {
|
enum grep_header_field {
|
||||||
GREP_HEADER_AUTHOR = 0,
|
GREP_HEADER_AUTHOR = 0,
|
||||||
GREP_HEADER_COMMITTER
|
GREP_HEADER_COMMITTER,
|
||||||
|
GREP_HEADER_REFLOG,
|
||||||
|
|
||||||
|
/* Must be at the end of the enum */
|
||||||
|
GREP_HEADER_FIELD_MAX
|
||||||
};
|
};
|
||||||
#define GREP_HEADER_FIELD_MAX (GREP_HEADER_COMMITTER + 1)
|
|
||||||
|
|
||||||
struct grep_pat {
|
struct grep_pat {
|
||||||
struct grep_pat *next;
|
struct grep_pat *next;
|
||||||
@ -104,6 +107,7 @@ struct grep_opt {
|
|||||||
#define GREP_BINARY_TEXT 2
|
#define GREP_BINARY_TEXT 2
|
||||||
int binary;
|
int binary;
|
||||||
int extended;
|
int extended;
|
||||||
|
int use_reflog_filter;
|
||||||
int pcre;
|
int pcre;
|
||||||
int relative;
|
int relative;
|
||||||
int pathname;
|
int pathname;
|
||||||
|
37
revision.c
37
revision.c
@ -1595,6 +1595,9 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
|
|||||||
} else if ((argcount = parse_long_opt("committer", argv, &optarg))) {
|
} else if ((argcount = parse_long_opt("committer", argv, &optarg))) {
|
||||||
add_header_grep(revs, GREP_HEADER_COMMITTER, optarg);
|
add_header_grep(revs, GREP_HEADER_COMMITTER, optarg);
|
||||||
return argcount;
|
return argcount;
|
||||||
|
} else if ((argcount = parse_long_opt("grep-reflog", argv, &optarg))) {
|
||||||
|
add_header_grep(revs, GREP_HEADER_REFLOG, optarg);
|
||||||
|
return argcount;
|
||||||
} else if ((argcount = parse_long_opt("grep", argv, &optarg))) {
|
} else if ((argcount = parse_long_opt("grep", argv, &optarg))) {
|
||||||
add_message_grep(revs, optarg);
|
add_message_grep(revs, optarg);
|
||||||
return argcount;
|
return argcount;
|
||||||
@ -1905,6 +1908,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
|
|||||||
|
|
||||||
if (revs->reflog_info && revs->graph)
|
if (revs->reflog_info && revs->graph)
|
||||||
die("cannot combine --walk-reflogs with --graph");
|
die("cannot combine --walk-reflogs with --graph");
|
||||||
|
if (!revs->reflog_info && revs->grep_filter.use_reflog_filter)
|
||||||
|
die("cannot use --grep-reflog without --walk-reflogs");
|
||||||
|
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
@ -2210,10 +2215,38 @@ 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)
|
||||||
{
|
{
|
||||||
|
int retval;
|
||||||
|
struct strbuf buf = STRBUF_INIT;
|
||||||
if (!opt->grep_filter.pattern_list && !opt->grep_filter.header_list)
|
if (!opt->grep_filter.pattern_list && !opt->grep_filter.header_list)
|
||||||
return 1;
|
return 1;
|
||||||
return grep_buffer(&opt->grep_filter,
|
|
||||||
commit->buffer, strlen(commit->buffer));
|
/* Prepend "fake" headers as needed */
|
||||||
|
if (opt->grep_filter.use_reflog_filter) {
|
||||||
|
strbuf_addstr(&buf, "reflog ");
|
||||||
|
get_reflog_message(&buf, opt->reflog_info);
|
||||||
|
strbuf_addch(&buf, '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the commit to temporary if we are using "fake" headers */
|
||||||
|
if (buf.len)
|
||||||
|
strbuf_addstr(&buf, commit->buffer);
|
||||||
|
|
||||||
|
/* Append "fake" message parts as needed */
|
||||||
|
if (opt->show_notes) {
|
||||||
|
if (!buf.len)
|
||||||
|
strbuf_addstr(&buf, commit->buffer);
|
||||||
|
format_display_notes(commit->object.sha1, &buf,
|
||||||
|
get_log_output_encoding(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find either in the commit object, or in the temporary */
|
||||||
|
if (buf.len)
|
||||||
|
retval = grep_buffer(&opt->grep_filter, buf.buf, buf.len);
|
||||||
|
else
|
||||||
|
retval = grep_buffer(&opt->grep_filter,
|
||||||
|
commit->buffer, strlen(commit->buffer));
|
||||||
|
strbuf_release(&buf);
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int want_ancestry(struct rev_info *revs)
|
static inline int want_ancestry(struct rev_info *revs)
|
||||||
|
@ -546,6 +546,36 @@ test_expect_success 'log grep (6)' '
|
|||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'log grep (7)' '
|
||||||
|
git log -g --grep-reflog="commit: third" --pretty=tformat:%s >actual &&
|
||||||
|
echo third >expect &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'log grep (8)' '
|
||||||
|
git log -g --grep-reflog="commit: third" --grep-reflog="commit: second" --pretty=tformat:%s >actual &&
|
||||||
|
{
|
||||||
|
echo third && echo second
|
||||||
|
} >expect &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'log grep (9)' '
|
||||||
|
git log -g --grep-reflog="commit: third" --author="Thor" --pretty=tformat:%s >actual &&
|
||||||
|
echo third >expect &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'log grep (9)' '
|
||||||
|
git log -g --grep-reflog="commit: third" --author="non-existant" --pretty=tformat:%s >actual &&
|
||||||
|
: >expect &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'log --grep-reflog can only be used under -g' '
|
||||||
|
test_must_fail git log --grep-reflog="commit: third"
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'log with multiple --grep uses union' '
|
test_expect_success 'log with multiple --grep uses union' '
|
||||||
git log --grep=i --grep=r --format=%s >actual &&
|
git log --grep=i --grep=r --format=%s >actual &&
|
||||||
{
|
{
|
||||||
@ -628,6 +658,18 @@ test_expect_success 'log --all-match --grep --grep --author takes intersection'
|
|||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'log --author does not search in timestamp' '
|
||||||
|
: >expect &&
|
||||||
|
git log --author="$GIT_AUTHOR_DATE" >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'log --committer does not search in timestamp' '
|
||||||
|
: >expect &&
|
||||||
|
git log --committer="$GIT_COMMITTER_DATE" >actual &&
|
||||||
|
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