Re: [PATCH] revision: add --reflog-message=<pattern> to grep reflog messages

5 messages, 2 authors, 2016-06-15 · open the first message on its own page

Re: [PATCH] revision: add --reflog-message=<pattern> to grep reflog messages

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:54:52

Nguyen Thai Ngoc Duy [off-list ref] writes:
On Wed, Sep 26, 2012 at 9:07 PM, Junio C Hamano [off-list ref] wrote:
quoted
Nguyễn Thái Ngọc Duy  [off-list ref] writes:
quoted
Both "git log" and "git reflog show" recognize this option.

Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
How well does it interact with --grep and/or --all-match?
Good point. It currently works like and operator. But people might
expect to combine them in different ways.
The current commit_match() runs grep_buffer() on commit->buffer.  It
probably makes sense to instead notice from opt that we are running
log with "-g", prepare a temporary strbuf and add in the reflog
message to the string in commit->buffer, and run grep_buffer() on
that temporary strbuf on it.

I personally think it is sufficient ot just reuse --grep on
concatenation of commit->buffer with "Reflog message: checkout:
moving from as/check-ignore to pu".

If you really want to go fancier, you could add --grep-reflog option
that behaves like the existing --author and --committer options to
add "header match" elements to the grep expression, splice a fake
"reflog " header to the string copied from commit->buffer, e.g.
prepare something like this in your temporary strbuf:

    tree b4429f218782165faf101ccb0f4ba1cdd6d1d349
    parent de5cd03876e546d6d264ab28a01daa978f3eae78
    parent b378e5a25658e07e6d0c0f4db79e87cb21de5489
    author Junio C Hamano [off-list ref] 1348616180 -0700
    committer Junio C Hamano [off-list ref] 1348616180 -0700
    reflog checkout: moving from as/check-ignore to pu

    Merge branch 'jk/lua-hackery' into pu

    * jk/lua-hackery:
      Minimum compilation fixup
      Makefile: make "lua" a bit more configurable
      add a "lua" pretty format
      add basic lua infrastructure
      pretty: make some commit-parsing helpers more public

that way, you can take advantage of the existing logic used for the
author/committer match that matches only in the commit object
header.

Again, I personally doubt the fancier option is worth it, but the
starting point may look something like this.

 revision.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)
diff --git c/revision.c w/revision.c
index ae12e11..b0f4d5b 100644
--- c/revision.c
+++ w/revision.c
@@ -2212,8 +2212,20 @@ static int commit_match(struct commit *commit, struct rev_info *opt)
 {
 	if (!opt->grep_filter.pattern_list && !opt->grep_filter.header_list)
 		return 1;
-	return grep_buffer(&opt->grep_filter,
-			   commit->buffer, strlen(commit->buffer));
+
+	if (opt->reflog_info) {
+		int retval;
+		struct strbuf buf = STRBUF_INIT;
+		strbuf_addf(&buf, "reflog %s\n", opt->reflog_info->message);
+		strbuf_addstr(&buf, commit->buffer);
+		retval = grep_buffer(&opt->grep_filter,
+				     buf.buf, buf.len);
+		strbuf_release(&buf);
+		return retval;
+	} else {
+		return grep_buffer(&opt->grep_filter,
+				   commit->buffer, strlen(commit->buffer));
+	}
 }
 
 static inline int want_ancestry(struct rev_info *revs)

[PATCH] revision: add --reflog-message to grep reflog messages

From: Nguyễn Thái Ngọc Duy <hidden>
Date: 2016-06-15 22:54:52

Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
 On Thu, Sep 27, 2012 at 2:28 AM, Junio C Hamano [off-list ref] wrote:
 > The current commit_match() runs grep_buffer() on commit->buffer.  It
 > probably makes sense to instead notice from opt that we are running
 > log with "-g", prepare a temporary strbuf and add in the reflog
 > message to the string in commit->buffer, and run grep_buffer() on
 > that temporary strbuf on it.

 Yeah. I was starting to think that way too, otherwise combining grep
 options would be a mess. I was hoping by injecting a fake reflog
 header, we could simplify reflog exceptions in pretty.c. But it
 was not that easy.

 > I personally think it is sufficient ot just reuse --grep on
 > concatenation of commit->buffer with "Reflog message: checkout:
 > moving from as/check-ignore to pu".

 --grep only reads the commit body. So either we append reflog
 message to commit body, or we put it in the header and add a new
 option for it. I don't like appending things to the commit body as
 --grep may hit reflog message while users do not mean so.

 > If you really want to go fancier, you could add --grep-reflog option
 > that behaves like the existing --author and --committer options to
 > add "header match" elements to the grep expression, splice a fake
 > "reflog " header to the string copied from commit->buffer

 Inserting at the beginning of the commit like your demo patch works
 just fine and is simpler. I'm tempted to take the undocumented option
 name --reflog for this purpose. But it's probably not worth the risk.

 Documentation/rev-list-options.txt |  5 +++++
 grep.c                             |  1 +
 grep.h                             |  5 +++--
 revision.c                         | 19 +++++++++++++++++--
 t/t7810-grep.sh                    |  6 ++++++
 5 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index 1fc2a18..aeaa58c 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -51,6 +51,11 @@ endif::git-rev-list[]
 	commits whose author matches any of the given patterns are
 	chosen (similarly for multiple `--committer=<pattern>`).
 
+--reflog-message=<pattern>::
+	Limit the commits output to ones with reflog entries that
+	match the specified pattern (regular expression). Ignored unless
+	--walk-reflogs is given.
+
 --grep=<pattern>::
 
 	Limit the commits output to ones with log message that
diff --git a/grep.c b/grep.c
index 898be6e..72ac1bf 100644
--- a/grep.c
+++ b/grep.c
@@ -697,6 +697,7 @@ static struct {
 } header_field[] = {
 	{ "author ", 7 },
 	{ "committer ", 10 },
+	{ "reflog ", 7 },
 };
 
 static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
diff --git a/grep.h b/grep.h
index 8a28a67..1416ad7 100644
--- a/grep.h
+++ b/grep.h
@@ -29,9 +29,10 @@ enum grep_context {
 
 enum grep_header_field {
 	GREP_HEADER_AUTHOR = 0,
-	GREP_HEADER_COMMITTER
+	GREP_HEADER_COMMITTER,
+	GREP_HEADER_REFLOG,
+	GREP_HEADER_FIELD_MAX
 };
-#define GREP_HEADER_FIELD_MAX (GREP_HEADER_COMMITTER + 1)
 
 struct grep_pat {
 	struct grep_pat *next;
diff --git a/revision.c b/revision.c
index ae12e11..837051c 100644
--- a/revision.c
+++ b/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))) {
 		add_header_grep(revs, GREP_HEADER_COMMITTER, optarg);
 		return argcount;
+	} else if ((argcount = parse_long_opt("reflog-message", argv, &optarg))) {
+		add_header_grep(revs, GREP_HEADER_REFLOG, optarg);
+		return argcount;
 	} else if ((argcount = parse_long_opt("grep", argv, &optarg))) {
 		add_message_grep(revs, optarg);
 		return argcount;
@@ -2212,8 +2215,20 @@ static int commit_match(struct commit *commit, struct rev_info *opt)
 {
 	if (!opt->grep_filter.pattern_list && !opt->grep_filter.header_list)
 		return 1;
-	return grep_buffer(&opt->grep_filter,
-			   commit->buffer, strlen(commit->buffer));
+	if (opt->reflog_info) {
+		int retval;
+		struct strbuf buf = STRBUF_INIT;
+		strbuf_addstr(&buf, "reflog ");
+		get_reflog_message(&buf, opt->reflog_info);
+		strbuf_addch(&buf, '\n');
+		strbuf_addstr(&buf, commit->buffer);
+		retval = grep_buffer(&opt->grep_filter, buf.buf, buf.len);
+		strbuf_release(&buf);
+		return retval;
+	} else {
+		return grep_buffer(&opt->grep_filter,
+				   commit->buffer, strlen(commit->buffer));
+	}
 }
 
 static inline int want_ancestry(struct rev_info *revs)
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 91db352..a0f519e 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -546,6 +546,12 @@ test_expect_success 'log grep (6)' '
 	test_cmp expect actual
 '
 
+test_expect_success 'log grep (7)' '
+	git log -g --reflog-message="commit: third" --pretty=tformat:%s >actual &&
+	echo third >expect &&
+	test_cmp expect actual
+'
+
 test_expect_success 'log with multiple --grep uses union' '
 	git log --grep=i --grep=r --format=%s >actual &&
 	{
-- 
1.7.12.1.406.g6ab07c4

[PATCH 1/3] grep: generalize header grep code to accept arbitrary headers

From: Nguyễn Thái Ngọc Duy <hidden>
Date: 2016-06-15 22:54:53

Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
 On Fri, Sep 28, 2012 at 12:09 AM, Junio C Hamano [off-list ref] wrote:
 >>  enum grep_header_field {
 >>       GREP_HEADER_AUTHOR = 0,
 >> -     GREP_HEADER_COMMITTER
 >> +     GREP_HEADER_COMMITTER,
 >> +     GREP_HEADER_REFLOG,
 >> +     GREP_HEADER_FIELD_MAX
 >>  };
 >> -#define GREP_HEADER_FIELD_MAX (GREP_HEADER_COMMITTER + 1)
 >
 > Please add comment to ensure that FIELD_MAX stays at the end; if you
 > ensure that, the result is much better than the original "we know
 > committer is at the end so add one".

 It's probably even better to remove the enum. Say one day I got drunk
 and decided to add --grep-encoding. This patch makes sure that I could
 submit such a patch even in drunk state.

 grep.c     | 76 +++++++++++++++++++++++++++++++++-----------------------------
 grep.h     | 11 +++------
 revision.c |  8 +++----
 3 files changed, 47 insertions(+), 48 deletions(-)
diff --git a/grep.c b/grep.c
index 898be6e..0c72262 100644
--- a/grep.c
+++ b/grep.c
@@ -10,7 +10,7 @@ static int grep_source_is_binary(struct grep_source *gs);
 static struct grep_pat *create_grep_pat(const char *pat, size_t patlen,
 					const char *origin, int no,
 					enum grep_pat_token t,
-					enum grep_header_field field)
+					const char *header, size_t header_len)
 {
 	struct grep_pat *p = xcalloc(1, sizeof(*p));
 	p->pattern = xmemdupz(pat, patlen);
@@ -18,7 +18,8 @@ static struct grep_pat *create_grep_pat(const char *pat, size_t patlen,
 	p->origin = origin;
 	p->no = no;
 	p->token = t;
-	p->field = field;
+	p->header = header;
+	p->header_len = header_len;
 	return p;
 }
 
@@ -45,7 +46,8 @@ static void do_append_grep_pat(struct grep_pat ***tail, struct grep_pat *p)
 			if (!nl)
 				break;
 			new_pat = create_grep_pat(nl + 1, len - 1, p->origin,
-						  p->no, p->token, p->field);
+						  p->no, p->token,
+						  p->header, p->header_len);
 			new_pat->next = p->next;
 			if (!p->next)
 				*tail = &new_pat->next;
@@ -59,11 +61,13 @@ static void do_append_grep_pat(struct grep_pat ***tail, struct grep_pat *p)
 	}
 }
 
+/* header must not be freed while grep is running */
 void append_header_grep_pattern(struct grep_opt *opt,
-				enum grep_header_field field, const char *pat)
+				const char *header, const char *pat)
 {
 	struct grep_pat *p = create_grep_pat(pat, strlen(pat), "header", 0,
-					     GREP_PATTERN_HEAD, field);
+					     GREP_PATTERN_HEAD,
+					     header, strlen(header));
 	do_append_grep_pat(&opt->header_tail, p);
 }
 
@@ -76,7 +80,7 @@ void append_grep_pattern(struct grep_opt *opt, const char *pat,
 void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen,
 		     const char *origin, int no, enum grep_pat_token t)
 {
-	struct grep_pat *p = create_grep_pat(pat, patlen, origin, no, t, 0);
+	struct grep_pat *p = create_grep_pat(pat, patlen, origin, no, t, NULL, 0);
 	do_append_grep_pat(&opt->pattern_tail, p);
 }
 
@@ -92,7 +96,7 @@ struct grep_opt *grep_opt_dup(const struct grep_opt *opt)
 	for(pat = opt->pattern_list; pat != NULL; pat = pat->next)
 	{
 		if(pat->token == GREP_PATTERN_HEAD)
-			append_header_grep_pattern(ret, pat->field,
+			append_header_grep_pattern(ret, pat->header,
 						   pat->pattern);
 		else
 			append_grep_pat(ret, pat->pattern, pat->patternlen,
@@ -359,7 +363,7 @@ static void dump_grep_pat(struct grep_pat *p)
 	switch (p->token) {
 	default: break;
 	case GREP_PATTERN_HEAD:
-		fprintf(stderr, "<head %d>", p->field); break;
+		fprintf(stderr, "<head %s>", p->header); break;
 	case GREP_PATTERN_BODY:
 		fprintf(stderr, "<body>"); break;
 	}
@@ -436,9 +440,10 @@ static struct grep_expr *grep_or_expr(struct grep_expr *left, struct grep_expr *
 static struct grep_expr *prep_header_patterns(struct grep_opt *opt)
 {
 	struct grep_pat *p;
-	struct grep_expr *header_expr;
-	struct grep_expr *(header_group[GREP_HEADER_FIELD_MAX]);
-	enum grep_header_field fld;
+	struct grep_expr *header_expr = NULL;
+	struct grep_expr **header_group;
+	struct string_list header = STRING_LIST_INIT_NODUP;
+	int fld;
 
 	if (!opt->header_list)
 		return NULL;
@@ -446,37 +451,45 @@ static struct grep_expr *prep_header_patterns(struct grep_opt *opt)
 	for (p = opt->header_list; p; p = p->next) {
 		if (p->token != GREP_PATTERN_HEAD)
 			die("bug: a non-header pattern in grep header list.");
-		if (p->field < 0 || GREP_HEADER_FIELD_MAX <= p->field)
-			die("bug: unknown header field %d", p->field);
+		if (!p->header || !p->header_len)
+			die("bug: unknown header field");
 		compile_regexp(p, opt);
+		string_list_append(&header, p->header);
 	}
 
-	for (fld = 0; fld < GREP_HEADER_FIELD_MAX; fld++)
-		header_group[fld] = NULL;
+	sort_string_list(&header);
+	string_list_remove_duplicates(&header, 0);
+	header_group = xmalloc(sizeof(*header_group) * header.nr);
+	memset(header_group, 0, sizeof(*header_group) * header.nr);
 
 	for (p = opt->header_list; p; p = p->next) {
 		struct grep_expr *h;
 		struct grep_pat *pp = p;
+		struct string_list_item *item;
 
 		h = compile_pattern_atom(&pp);
 		if (!h || pp != p->next)
 			die("bug: malformed header expr");
-		if (!header_group[p->field]) {
-			header_group[p->field] = h;
+		item = string_list_lookup(&header, p->header);
+		if (!item)
+			die("bug: malformed header expr");
+		fld = item - header.items;
+		if (!header_group[fld]) {
+			header_group[fld] = h;
 			continue;
 		}
-		header_group[p->field] = grep_or_expr(h, header_group[p->field]);
+		header_group[fld] = grep_or_expr(h, header_group[fld]);
 	}
 
-	header_expr = NULL;
-
-	for (fld = 0; fld < GREP_HEADER_FIELD_MAX; fld++) {
-		if (!header_group[fld])
-			continue;
+	for (fld = 0; fld < header.nr; fld++) {
 		if (!header_expr)
 			header_expr = grep_true_expr();
 		header_expr = grep_or_expr(header_group[fld], header_expr);
 	}
+
+	string_list_clear(&header, 0);
+	free(header_group);
+
 	return header_expr;
 }
 
@@ -691,14 +704,6 @@ static int strip_timestamp(char *bol, char **eol_p)
 	return 0;
 }
 
-static struct {
-	const char *field;
-	size_t len;
-} header_field[] = {
-	{ "author ", 7 },
-	{ "committer ", 10 },
-};
-
 static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
 			     enum grep_context ctx,
 			     regmatch_t *pmatch, int eflags)
@@ -714,12 +719,11 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
 	if (p->token == GREP_PATTERN_HEAD) {
 		const char *field;
 		size_t len;
-		assert(p->field < ARRAY_SIZE(header_field));
-		field = header_field[p->field].field;
-		len = header_field[p->field].len;
-		if (strncmp(bol, field, len))
+		field = p->header;
+		len = p->header_len;
+		if (strncmp(bol, field, len) || bol[len] != ' ')
 			return 0;
-		bol += len;
+		bol += len + 1;
 		saved_ch = strip_timestamp(bol, &eol);
 	}
 
diff --git a/grep.h b/grep.h
index 8a28a67..bc00f2a 100644
--- a/grep.h
+++ b/grep.h
@@ -27,12 +27,6 @@ enum grep_context {
 	GREP_CONTEXT_BODY
 };
 
-enum grep_header_field {
-	GREP_HEADER_AUTHOR = 0,
-	GREP_HEADER_COMMITTER
-};
-#define GREP_HEADER_FIELD_MAX (GREP_HEADER_COMMITTER + 1)
-
 struct grep_pat {
 	struct grep_pat *next;
 	const char *origin;
@@ -40,7 +34,8 @@ struct grep_pat {
 	enum grep_pat_token token;
 	char *pattern;
 	size_t patternlen;
-	enum grep_header_field field;
+	const char *header;
+	size_t header_len;
 	regex_t regexp;
 	pcre *pcre_regexp;
 	pcre_extra *pcre_extra_info;
@@ -136,7 +131,7 @@ struct grep_opt {
 
 extern void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen, const char *origin, int no, enum grep_pat_token t);
 extern void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t);
-extern void append_header_grep_pattern(struct grep_opt *, enum grep_header_field, const char *);
+extern void append_header_grep_pattern(struct grep_opt *, const char *, const char *);
 extern void compile_grep_patterns(struct grep_opt *opt);
 extern void free_grep_patterns(struct grep_opt *opt);
 extern int grep_buffer(struct grep_opt *opt, char *buf, unsigned long size);
diff --git a/revision.c b/revision.c
index ae12e11..f7cf385 100644
--- a/revision.c
+++ b/revision.c
@@ -1288,9 +1288,9 @@ static void add_grep(struct rev_info *revs, const char *ptn, enum grep_pat_token
 	append_grep_pattern(&revs->grep_filter, ptn, "command line", 0, what);
 }
 
-static void add_header_grep(struct rev_info *revs, enum grep_header_field field, const char *pattern)
+static void add_header_grep(struct rev_info *revs, const char *header, const char *pattern)
 {
-	append_header_grep_pattern(&revs->grep_filter, field, pattern);
+	append_header_grep_pattern(&revs->grep_filter, header, pattern);
 }
 
 static void add_message_grep(struct rev_info *revs, const char *pattern)
@@ -1590,10 +1590,10 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
 	 * Grepping the commit log
 	 */
 	else if ((argcount = parse_long_opt("author", argv, &optarg))) {
-		add_header_grep(revs, GREP_HEADER_AUTHOR, optarg);
+		add_header_grep(revs, "author", optarg);
 		return argcount;
 	} else if ((argcount = parse_long_opt("committer", argv, &optarg))) {
-		add_header_grep(revs, GREP_HEADER_COMMITTER, optarg);
+		add_header_grep(revs, "committer", optarg);
 		return argcount;
 	} else if ((argcount = parse_long_opt("grep", argv, &optarg))) {
 		add_message_grep(revs, optarg);
-- 
1.7.12.1.405.gb727dc9

[PATCH 2/3] revision: add --grep-reflog to filter commits by reflog messages

From: Nguyễn Thái Ngọc Duy <hidden>
Date: 2016-06-15 22:54:53

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.

Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
 On Fri, Sep 28, 2012 at 12:09 AM, Junio C Hamano [off-list ref]
 wrote:
 > I am debating myself if it is sane for this option to have no hint
 > that it is about "limiting" in its name.  "--author/--committer"
 > don't and it is clear from the context of the command that they are
 > not about setting author/committer, so "--reflog-message" may be
 > interpreted the same, perhaps.
 >
 > The entry in the context above talks about multiple occurrence of
 > that option. Shouldn't this new one also say what happens when it
 > is
 > given twice?

 Fixed.

 > I think I wrote prep_header_patterns() and compile_grep_patterns()
 > carefully enough not to assume the headers are only the author and
 > committer names, so the various combinations i.e. all-match,
 > author(s), committer(s), grep(s), and reflog-message(s), should
 > work
 > out of the box, but have you actually tested them?

 I did not. I do now, tests are also added.

 On Fri, Sep 28, 2012 at 12:28 AM, Jeff King [off-list ref] wrote:
 > I also found the name confusing on first-read. While "--author" is
 > an
 > example in one direction, the fact that "--grep" is not called
 > "--body"
 > is a counter-example.
 >
 > I'd much rather see it as "--grep-reflog" or something. You could
 > also
 > do "--grep-reflog-message", which would match a later
 > "--grep-reflog-author", but I am not sure anybody would want the
 > latter,
 > and it makes the current name a lot longer.

 Changed it to --grep-reflog. I was tempted to add --grep-* but I
 can't error out if user gives an invalid header. So --grep-reflog
 only for now.

 Documentation/rev-list-options.txt |  8 ++++++++
 revision.c                         | 20 ++++++++++++++++++--
 t/t7810-grep.sh                    | 26 ++++++++++++++++++++++++++
 3 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index 1fc2a18..aa7cd9d 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -51,6 +51,14 @@ endif::git-rev-list[]
 	commits whose author matches any of the given patterns are
 	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. Ignored unless
+	`--walk-reflogs` is given.
+
 --grep=<pattern>::
 
 	Limit the commits output to ones with log message that
diff --git a/revision.c b/revision.c
index f7cf385..cfa0e2e 100644
--- a/revision.c
+++ b/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))) {
 		add_header_grep(revs, "committer", optarg);
 		return argcount;
+	} else if ((argcount = parse_long_opt("grep-reflog", argv, &optarg))) {
+		add_header_grep(revs, "reflog", optarg);
+		return argcount;
 	} else if ((argcount = parse_long_opt("grep", argv, &optarg))) {
 		add_message_grep(revs, optarg);
 		return argcount;
@@ -2210,10 +2213,23 @@ static int rewrite_parents(struct rev_info *revs, struct commit *commit)
 
 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)
 		return 1;
-	return grep_buffer(&opt->grep_filter,
-			   commit->buffer, strlen(commit->buffer));
+	if (opt->reflog_info) {
+		strbuf_addstr(&buf, "reflog ");
+		get_reflog_message(&buf, opt->reflog_info);
+		strbuf_addch(&buf, '\n');
+		strbuf_addstr(&buf, commit->buffer);
+	}
+	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)
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 91db352..f42a605 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -546,6 +546,32 @@ test_expect_success 'log grep (6)' '
 	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 with multiple --grep uses union' '
 	git log --grep=i --grep=r --format=%s >actual &&
 	{
-- 
1.7.12.1.405.gb727dc9

[PATCH 3/3] revision: make --grep search in notes too if shown

From: Nguyễn Thái Ngọc Duy <hidden>
Date: 2016-06-15 22:54:53

Notes are shown after commit body. From user perspective it looks
pretty much like commit body and they may assume --grep would search
in that part too. Make it so.

Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
 On Fri, Sep 28, 2012 at 1:16 AM, Junio C Hamano [off-list ref]
 wrote:
 > The output from "log --show-notes", on the other hand, is even more
 > conflated and a casual user would view it as part of the message,
 > so
 > I would imagine that if we ever do the extention to cover notes
 > data, the normal "--grep" should apply to it.

 Something like this?

 revision.c | 6 ++++++
 1 file changed, 6 insertions(+)
diff --git a/revision.c b/revision.c
index cfa0e2e..febb4d7 100644
--- a/revision.c
+++ b/revision.c
@@ -2223,6 +2223,12 @@ static int commit_match(struct commit *commit, struct rev_info *opt)
 		strbuf_addch(&buf, '\n');
 		strbuf_addstr(&buf, commit->buffer);
 	}
+	if (opt->show_notes) {
+		if (!buf.len)
+			strbuf_addstr(&buf, commit->buffer);
+		format_display_notes(commit->object.sha1, &buf,
+				     get_log_output_encoding(), 0);
+	}
 	if (buf.len)
 		retval = grep_buffer(&opt->grep_filter, buf.buf, buf.len);
 	else
-- 
1.7.12.1.405.gb727dc9
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help