git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Jeff King <peff@peff.net>
Cc: git@vger.kernel.org
Subject: Re: [PATCH 3/3] diffcore-pickaxe: unify setup and teardown code between log -S/-G
Date: Fri, 05 Apr 2013 09:44:52 -0700	[thread overview]
Message-ID: <7vr4ipc4fv.fsf@alter.siamese.dyndns.org> (raw)
In-Reply-To: <20130405054524.GB12705@sigill.intra.peff.net> (Jeff King's message of "Fri, 5 Apr 2013 01:45:24 -0400")

Jeff King <peff@peff.net> writes:

> I didn't actually test that patch beyond compilation (but it's
> _obviously_ correct, right?), and I'm about to go to bed. Do you want to
> take care of adapting your commit message to it?

The code looks obviously correct, yes.

We might have to revisit the "Is unmerged?" thing, Cf. d7c9bf22351e
(diffcore-rename: don't consider unmerged path as source,
2011-03-23), but that is an unlikely corner case, especially for
these options (-S/-G).

-- >8 --
From: Jeff King <peff@peff.net>
Date: Fri, 5 Apr 2013 01:28:10 -0400
Subject: [PATCH] diffcore-pickaxe: unify code for log -S/-G

The logic flow of has_changes() used for "log -S" and diff_grep()
used for "log -G" are essentially the same.  See if we have both
sides that could be different in any interesting way, slurp the
contents in core, possibly after applying textconv, inspect the
contents, clean-up and report the result.  The only difference
between the two is how "inspect" step works.

Unify this codeflow in a helper, pickaxe_match(), which takes a
callback function that implements the specific "inspect" step.

After removing the common scaffolding code from the existing
has_changes() and diff_grep(), they each becomes such a callback
function suitable for passing to pickaxe_match().

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 diffcore-pickaxe.c | 118 ++++++++++++++++++++++-------------------------------
 1 file changed, 49 insertions(+), 69 deletions(-)

diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
index cadb071..63722f8 100644
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c
@@ -8,7 +8,12 @@
 #include "xdiff-interface.h"
 #include "kwset.h"
 
-typedef int (*pickaxe_fn)(struct diff_filepair *p, struct diff_options *o, regex_t *regexp, kwset_t kws);
+typedef int (*pickaxe_fn)(mmfile_t *one, mmfile_t *two,
+			  struct diff_options *o,
+			  regex_t *regexp, kwset_t kws);
+
+static int pickaxe_match(struct diff_filepair *p, struct diff_options *o,
+			 regex_t *regexp, kwset_t kws, pickaxe_fn fn);
 
 static void pickaxe(struct diff_queue_struct *q, struct diff_options *o,
 		    regex_t *regexp, kwset_t kws, pickaxe_fn fn)
@@ -22,7 +27,7 @@ static void pickaxe(struct diff_queue_struct *q, struct diff_options *o,
 		/* Showing the whole changeset if needle exists */
 		for (i = 0; i < q->nr; i++) {
 			struct diff_filepair *p = q->queue[i];
-			if (fn(p, o, regexp, kws))
+			if (pickaxe_match(p, o, regexp, kws, fn))
 				return; /* do not munge the queue */
 		}
 
@@ -37,7 +42,7 @@ static void pickaxe(struct diff_queue_struct *q, struct diff_options *o,
 		/* Showing only the filepairs that has the needle */
 		for (i = 0; i < q->nr; i++) {
 			struct diff_filepair *p = q->queue[i];
-			if (fn(p, o, regexp, kws))
+			if (pickaxe_match(p, o, regexp, kws, fn))
 				diff_q(&outq, p);
 			else
 				diff_free_filepair(p);
@@ -74,64 +79,33 @@ static void diffgrep_consume(void *priv, char *line, unsigned long len)
 	line[len] = hold;
 }
 
-static int diff_grep(struct diff_filepair *p, struct diff_options *o,
+static int diff_grep(mmfile_t *one, mmfile_t *two,
+		     struct diff_options *o,
 		     regex_t *regexp, kwset_t kws)
 {
 	regmatch_t regmatch;
-	struct userdiff_driver *textconv_one = NULL;
-	struct userdiff_driver *textconv_two = NULL;
-	mmfile_t mf1, mf2;
-	int hit;
+	struct diffgrep_cb ecbdata;
+	xpparam_t xpp;
+	xdemitconf_t xecfg;
 
-	if (!o->pickaxe[0])
-		return 0;
+	if (!one)
+		return !regexec(regexp, two->ptr, 1, &regmatch, 0);
+	if (!two)
+		return !regexec(regexp, one->ptr, 1, &regmatch, 0);
 
-	if (DIFF_OPT_TST(o, ALLOW_TEXTCONV)) {
-		textconv_one = get_textconv(p->one);
-		textconv_two = get_textconv(p->two);
-	}
-
-	if (textconv_one == textconv_two && diff_unmodified_pair(p))
-		return 0;
-
-	mf1.size = fill_textconv(textconv_one, p->one, &mf1.ptr);
-	mf2.size = fill_textconv(textconv_two, p->two, &mf2.ptr);
-
-	if (!DIFF_FILE_VALID(p->one)) {
-		if (!DIFF_FILE_VALID(p->two))
-			hit = 0; /* ignore unmerged */
-		else
-			/* created "two" -- does it have what we are looking for? */
-			hit = !regexec(regexp, mf2.ptr, 1, &regmatch, 0);
-	} else if (!DIFF_FILE_VALID(p->two)) {
-		/* removed "one" -- did it have what we are looking for? */
-		hit = !regexec(regexp, mf1.ptr, 1, &regmatch, 0);
-	} else {
-		/*
-		 * We have both sides; need to run textual diff and see if
-		 * the pattern appears on added/deleted lines.
-		 */
-		struct diffgrep_cb ecbdata;
-		xpparam_t xpp;
-		xdemitconf_t xecfg;
-
-		memset(&xpp, 0, sizeof(xpp));
-		memset(&xecfg, 0, sizeof(xecfg));
-		ecbdata.regexp = regexp;
-		ecbdata.hit = 0;
-		xecfg.ctxlen = o->context;
-		xecfg.interhunkctxlen = o->interhunkcontext;
-		xdi_diff_outf(&mf1, &mf2, diffgrep_consume, &ecbdata,
-			      &xpp, &xecfg);
-		hit = ecbdata.hit;
-	}
-	if (textconv_one)
-		free(mf1.ptr);
-	if (textconv_two)
-		free(mf2.ptr);
-	diff_free_filespec_data(p->one);
-	diff_free_filespec_data(p->two);
-	return hit;
+	/*
+	 * We have both sides; need to run textual diff and see if
+	 * the pattern appears on added/deleted lines.
+	 */
+	memset(&xpp, 0, sizeof(xpp));
+	memset(&xecfg, 0, sizeof(xecfg));
+	ecbdata.regexp = regexp;
+	ecbdata.hit = 0;
+	xecfg.ctxlen = o->context;
+	xecfg.interhunkctxlen = o->interhunkcontext;
+	xdi_diff_outf(one, two, diffgrep_consume, &ecbdata,
+		      &xpp, &xecfg);
+	return ecbdata.hit;
 }
 
 static void diffcore_pickaxe_grep(struct diff_options *o)
@@ -198,9 +172,20 @@ static unsigned int contains(mmfile_t *mf, struct diff_options *o,
 	return cnt;
 }
 
-static int has_changes(struct diff_filepair *p, struct diff_options *o,
+static int has_changes(mmfile_t *one, mmfile_t *two,
+		       struct diff_options *o,
 		       regex_t *regexp, kwset_t kws)
 {
+	if (!one)
+		return contains(two, o, regexp, kws) != 0;
+	if (!two)
+		return contains(one, o, regexp, kws) != 0;
+	return contains(one, o, regexp, kws) != contains(two, o, regexp, kws);
+}
+
+static int pickaxe_match(struct diff_filepair *p, struct diff_options *o,
+			 regex_t *regexp, kwset_t kws, pickaxe_fn fn)
+{
 	struct userdiff_driver *textconv_one = NULL;
 	struct userdiff_driver *textconv_two = NULL;
 	mmfile_t mf1, mf2;
@@ -209,6 +194,10 @@ static int has_changes(struct diff_filepair *p, struct diff_options *o,
 	if (!o->pickaxe[0])
 		return 0;
 
+	/* ignore unmerged */
+	if (!DIFF_FILE_VALID(p->one) && !DIFF_FILE_VALID(p->two))
+		return 0;
+
 	if (DIFF_OPT_TST(o, ALLOW_TEXTCONV)) {
 		textconv_one = get_textconv(p->one);
 		textconv_two = get_textconv(p->two);
@@ -227,18 +216,9 @@ static int has_changes(struct diff_filepair *p, struct diff_options *o,
 	mf1.size = fill_textconv(textconv_one, p->one, &mf1.ptr);
 	mf2.size = fill_textconv(textconv_two, p->two, &mf2.ptr);
 
-	if (!DIFF_FILE_VALID(p->one)) {
-		if (!DIFF_FILE_VALID(p->two))
-			ret = 0; /* ignore unmerged */
-		else
-			/* created */
-			ret = contains(&mf2, o, regexp, kws) != 0;
-	}
-	else if (!DIFF_FILE_VALID(p->two)) /* removed */
-		ret = contains(&mf1, o, regexp, kws) != 0;
-	else
-		ret = contains(&mf1, o, regexp, kws) !=
-		      contains(&mf2, o, regexp, kws);
+	ret = fn(DIFF_FILE_VALID(p->one) ? &mf1 : NULL,
+		 DIFF_FILE_VALID(p->two) ? &mf2 : NULL,
+		 o, regexp, kws);
 
 	if (textconv_one)
 		free(mf1.ptr);
-- 
1.8.2-667-gbdcd2ef

  reply	other threads:[~2013-04-06 16:51 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-04  8:34 [BUG] git log -S not respecting --no-textconv Matthieu Moy
2013-04-04 16:03 ` [PATCH 1/2] diffcore-pickaxe: respect --no-textconv Simon Ruderich
2013-04-04 17:03   ` Matthieu Moy
2013-04-04 17:43   ` Jeff King
2013-04-04 17:45   ` Junio C Hamano
2013-04-04 17:51     ` Jeff King
2013-04-04 18:10       ` Junio C Hamano
2013-04-04 20:20         ` [PATCH v2 1/3] diffcore-pickaxe: remove unnecessary call to get_textconv() Simon Ruderich
2013-04-04 20:48           ` Junio C Hamano
2013-04-04 21:10             ` Junio C Hamano
2013-04-04 21:11             ` Jeff King
2013-04-04 22:51               ` Junio C Hamano
2013-04-05 13:20             ` Simon Ruderich
2013-04-04 20:21         ` [PATCH v2 2/3] diffcore-pickaxe: remove fill_one() Simon Ruderich
2013-04-05  0:08           ` Jeff King
2013-04-05  4:43             ` Junio C Hamano
2013-04-05  4:45               ` [PATCH 1/3] diffcore-pickaxe: port optimization from has_changes() to diff_grep() Junio C Hamano
2013-04-05  4:45                 ` [PATCH 2/3] diffcore-pickaxe: fix leaks in "log -S<block>" and "log -G<pattern>" Junio C Hamano
2013-04-05  4:45                 ` [PATCH 3/3] diffcore-pickaxe: unify setup and teardown code between log -S/-G Junio C Hamano
2013-04-05  5:28                   ` Jeff King
2013-04-05  5:43                     ` Junio C Hamano
2013-04-05  5:45                       ` Jeff King
2013-04-05 16:44                         ` Junio C Hamano [this message]
2013-04-04 20:21         ` [PATCH v2 3/3] diffcore-pickaxe: respect --no-textconv Simon Ruderich
2013-04-05  7:40           ` Matthieu Moy
2013-04-05 13:16             ` [PATCH v3 " Simon Ruderich
2013-04-05 17:31               ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7vr4ipc4fv.fsf@alter.siamese.dyndns.org \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=peff@peff.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).