revision: add --grep-reflog to filter commits by reflog messages

Similar to --author/--committer which filters commits by author and committer header fields. --grep-reflog adds a fake "reflog" header to commit and a grep filter to search on that line. All rules to --author/--committer apply except no timestamp stripping. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Sep 29, 2012 at 11:41 UTC 72fd13f71c18b438ca3e482c126bcbcaa2dac650
5 files changed +54 -2
Documentation/rev-list-options.txt
+8
@@ -51,6 +51,14 @@ endif::git-rev-list[]
51 commits whose author matches any of the given patterns are
52 chosen (similarly for multiple `--committer=<pattern>`).
53
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. Ignored unless
60 + `--walk-reflogs` is given.
61 +
62 --grep=<pattern>::
63
64 Limit the commits output to ones with log message that
grep.c
+1
@@ -697,6 +697,7 @@ static struct {
697 } header_field[] = {
698 { "author ", 7 },
699 { "committer ", 10 },
700 + { "reflog ", 7 },
701 };
702
703 static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
grep.h
+1
@@ -30,6 +30,7 @@ enum grep_context {
30 enum grep_header_field {
31 GREP_HEADER_AUTHOR = 0,
32 GREP_HEADER_COMMITTER,
33 + GREP_HEADER_REFLOG,
34
35 /* Must be at the end of the enum */
36 GREP_HEADER_FIELD_MAX
revision.c
+18 -2
@@ -1595,6 +1595,9 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
1595 } else if ((argcount = parse_long_opt("committer", argv, &optarg))) {
1596 add_header_grep(revs, GREP_HEADER_COMMITTER, optarg);
1597 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;
1601 } else if ((argcount = parse_long_opt("grep", argv, &optarg))) {
1602 add_message_grep(revs, optarg);
1603 return argcount;
@@ -2210,10 +2213,23 @@ static int rewrite_parents(struct rev_info *revs, struct commit *commit)
2213
2214 static int commit_match(struct commit *commit, struct rev_info *opt)
2215 {
2216 + int retval;
2217 + struct strbuf buf = STRBUF_INIT;
2218 if (!opt->grep_filter.pattern_list && !opt->grep_filter.header_list)
2219 return 1;
2215 - return grep_buffer(&opt->grep_filter,
2216 - commit->buffer, strlen(commit->buffer));
2220 + if (opt->reflog_info) {
2221 + strbuf_addstr(&buf, "reflog ");
2222 + get_reflog_message(&buf, opt->reflog_info);
2223 + strbuf_addch(&buf, '\n');
2224 + strbuf_addstr(&buf, commit->buffer);
2225 + }
2226 + if (buf.len)
2227 + retval = grep_buffer(&opt->grep_filter, buf.buf, buf.len);
2228 + else
2229 + retval = grep_buffer(&opt->grep_filter,
2230 + commit->buffer, strlen(commit->buffer));
2231 + strbuf_release(&buf);
2232 + return retval;
2233 }
2234
2235 static inline int want_ancestry(struct rev_info *revs)
t/t7810-grep.sh
+26
@@ -546,6 +546,32 @@ test_expect_success 'log grep (6)' '
546 test_cmp expect actual
547 '
548
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 with multiple --grep uses union' '
576 git log --grep=i --grep=r --format=%s >actual &&
577 {