Skip to content

Commit fa11d7c

Browse files
committed
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
2 parents 5ce993a + 38cfe91 commit fa11d7c

File tree

5 files changed

+105
-5
lines changed

5 files changed

+105
-5
lines changed

Documentation/rev-list-options.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,24 @@ endif::git-rev-list[]
5151
commits whose author matches any of the given patterns are
5252
chosen (similarly for multiple `--committer=<pattern>`).
5353

54+
--grep-reflog=<pattern>::
55+
56+
Limit the commits output to ones with reflog entries that
57+
match the specified pattern (regular expression). With
58+
more than one `--grep-reflog`, commits whose reflog message
59+
matches any of the given patterns are chosen. It is an
60+
error to use this option unless `--walk-reflogs` is in use.
61+
5462
--grep=<pattern>::
5563

5664
Limit the commits output to ones with log message that
5765
matches the specified pattern (regular expression). With
5866
more than one `--grep=<pattern>`, commits whose message
5967
matches any of the given patterns are chosen (but see
6068
`--all-match`).
69+
+
70+
When `--show-notes` is in effect, the message from the notes as
71+
if it is part of the log message.
6172

6273
--all-match::
6374
Limit the commits output to ones that match all given --grep,

grep.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ void append_header_grep_pattern(struct grep_opt *opt,
6464
{
6565
struct grep_pat *p = create_grep_pat(pat, strlen(pat), "header", 0,
6666
GREP_PATTERN_HEAD, field);
67+
if (field == GREP_HEADER_REFLOG)
68+
opt->use_reflog_filter = 1;
6769
do_append_grep_pat(&opt->header_tail, p);
6870
}
6971

@@ -697,6 +699,7 @@ static struct {
697699
} header_field[] = {
698700
{ "author ", 7 },
699701
{ "committer ", 10 },
702+
{ "reflog ", 7 },
700703
};
701704

702705
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,
720723
if (strncmp(bol, field, len))
721724
return 0;
722725
bol += len;
723-
saved_ch = strip_timestamp(bol, &eol);
726+
switch (p->field) {
727+
case GREP_HEADER_AUTHOR:
728+
case GREP_HEADER_COMMITTER:
729+
saved_ch = strip_timestamp(bol, &eol);
730+
break;
731+
default:
732+
break;
733+
}
724734
}
725735

726736
again:

grep.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,12 @@ enum grep_context {
2929

3030
enum grep_header_field {
3131
GREP_HEADER_AUTHOR = 0,
32-
GREP_HEADER_COMMITTER
32+
GREP_HEADER_COMMITTER,
33+
GREP_HEADER_REFLOG,
34+
35+
/* Must be at the end of the enum */
36+
GREP_HEADER_FIELD_MAX
3337
};
34-
#define GREP_HEADER_FIELD_MAX (GREP_HEADER_COMMITTER + 1)
3538

3639
struct grep_pat {
3740
struct grep_pat *next;
@@ -104,6 +107,7 @@ struct grep_opt {
104107
#define GREP_BINARY_TEXT 2
105108
int binary;
106109
int extended;
110+
int use_reflog_filter;
107111
int pcre;
108112
int relative;
109113
int pathname;

revision.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,6 +1595,9 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
15951595
} else if ((argcount = parse_long_opt("committer", argv, &optarg))) {
15961596
add_header_grep(revs, GREP_HEADER_COMMITTER, optarg);
15971597
return argcount;
1598+
} else if ((argcount = parse_long_opt("grep-reflog", argv, &optarg))) {
1599+
add_header_grep(revs, GREP_HEADER_REFLOG, optarg);
1600+
return argcount;
15981601
} else if ((argcount = parse_long_opt("grep", argv, &optarg))) {
15991602
add_message_grep(revs, optarg);
16001603
return argcount;
@@ -1905,6 +1908,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
19051908

19061909
if (revs->reflog_info && revs->graph)
19071910
die("cannot combine --walk-reflogs with --graph");
1911+
if (!revs->reflog_info && revs->grep_filter.use_reflog_filter)
1912+
die("cannot use --grep-reflog without --walk-reflogs");
19081913

19091914
return left;
19101915
}
@@ -2210,10 +2215,38 @@ static int rewrite_parents(struct rev_info *revs, struct commit *commit)
22102215

22112216
static int commit_match(struct commit *commit, struct rev_info *opt)
22122217
{
2218+
int retval;
2219+
struct strbuf buf = STRBUF_INIT;
22132220
if (!opt->grep_filter.pattern_list && !opt->grep_filter.header_list)
22142221
return 1;
2215-
return grep_buffer(&opt->grep_filter,
2216-
commit->buffer, strlen(commit->buffer));
2222+
2223+
/* Prepend "fake" headers as needed */
2224+
if (opt->grep_filter.use_reflog_filter) {
2225+
strbuf_addstr(&buf, "reflog ");
2226+
get_reflog_message(&buf, opt->reflog_info);
2227+
strbuf_addch(&buf, '\n');
2228+
}
2229+
2230+
/* Copy the commit to temporary if we are using "fake" headers */
2231+
if (buf.len)
2232+
strbuf_addstr(&buf, commit->buffer);
2233+
2234+
/* Append "fake" message parts as needed */
2235+
if (opt->show_notes) {
2236+
if (!buf.len)
2237+
strbuf_addstr(&buf, commit->buffer);
2238+
format_display_notes(commit->object.sha1, &buf,
2239+
get_log_output_encoding(), 0);
2240+
}
2241+
2242+
/* Find either in the commit object, or in the temporary */
2243+
if (buf.len)
2244+
retval = grep_buffer(&opt->grep_filter, buf.buf, buf.len);
2245+
else
2246+
retval = grep_buffer(&opt->grep_filter,
2247+
commit->buffer, strlen(commit->buffer));
2248+
strbuf_release(&buf);
2249+
return retval;
22172250
}
22182251

22192252
static inline int want_ancestry(struct rev_info *revs)

t/t7810-grep.sh

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,36 @@ test_expect_success 'log grep (6)' '
546546
test_cmp expect actual
547547
'
548548

549+
test_expect_success 'log grep (7)' '
550+
git log -g --grep-reflog="commit: third" --pretty=tformat:%s >actual &&
551+
echo third >expect &&
552+
test_cmp expect actual
553+
'
554+
555+
test_expect_success 'log grep (8)' '
556+
git log -g --grep-reflog="commit: third" --grep-reflog="commit: second" --pretty=tformat:%s >actual &&
557+
{
558+
echo third && echo second
559+
} >expect &&
560+
test_cmp expect actual
561+
'
562+
563+
test_expect_success 'log grep (9)' '
564+
git log -g --grep-reflog="commit: third" --author="Thor" --pretty=tformat:%s >actual &&
565+
echo third >expect &&
566+
test_cmp expect actual
567+
'
568+
569+
test_expect_success 'log grep (9)' '
570+
git log -g --grep-reflog="commit: third" --author="non-existant" --pretty=tformat:%s >actual &&
571+
: >expect &&
572+
test_cmp expect actual
573+
'
574+
575+
test_expect_success 'log --grep-reflog can only be used under -g' '
576+
test_must_fail git log --grep-reflog="commit: third"
577+
'
578+
549579
test_expect_success 'log with multiple --grep uses union' '
550580
git log --grep=i --grep=r --format=%s >actual &&
551581
{
@@ -628,6 +658,18 @@ test_expect_success 'log --all-match --grep --grep --author takes intersection'
628658
test_cmp expect actual
629659
'
630660

661+
test_expect_success 'log --author does not search in timestamp' '
662+
: >expect &&
663+
git log --author="$GIT_AUTHOR_DATE" >actual &&
664+
test_cmp expect actual
665+
'
666+
667+
test_expect_success 'log --committer does not search in timestamp' '
668+
: >expect &&
669+
git log --committer="$GIT_COMMITTER_DATE" >actual &&
670+
test_cmp expect actual
671+
'
672+
631673
test_expect_success 'grep with CE_VALID file' '
632674
git update-index --assume-unchanged t/t &&
633675
rm t/t &&

0 commit comments

Comments
 (0)