pickaxe -G: terminate early on matching lines
Solve a long-standing item for "git log -Grx" of us e.g. finding "+
str" in the diff context and noting that we had a "hit", but xdiff
diligently continuing to generate and spew the rest of the diff at
us. This makes use of a new "early return" xdiff interface added by
preceding commits.
The TODO item (or, the NEEDSWORK comment) has been there since "git
log -G" was implemented. See f506b8e8b5
(git log/diff: add -G<regexp>
that greps in the patch text, 2010-08-23).
But now with the support added in the preceding changes to the
xdiff-interface we can return early. Let's assert the behavior of that
new early-return xdiff-interface by having a BUG() call here to die if
it ever starts handing us needless work again.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
parent
9e20442298
commit
fa59e7beb2
|
@ -27,13 +27,12 @@ static int diffgrep_consume(void *priv, char *line, unsigned long len)
|
|||
if (line[0] != '+' && line[0] != '-')
|
||||
return 0;
|
||||
if (data->hit)
|
||||
/*
|
||||
* NEEDSWORK: we should have a way to terminate the
|
||||
* caller early.
|
||||
*/
|
||||
return 0;
|
||||
data->hit = !regexec_buf(data->regexp, line + 1, len - 1, 1,
|
||||
®match, 0);
|
||||
BUG("Already matched in diffgrep_consume! Broken xdiff_emit_line_fn?");
|
||||
if (!regexec_buf(data->regexp, line + 1, len - 1, 1,
|
||||
®match, 0)) {
|
||||
data->hit = 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -45,6 +44,7 @@ static int diff_grep(mmfile_t *one, mmfile_t *two,
|
|||
struct diffgrep_cb ecbdata;
|
||||
xpparam_t xpp;
|
||||
xdemitconf_t xecfg;
|
||||
int ret;
|
||||
|
||||
if (!one)
|
||||
return !regexec_buf(regexp, two->ptr, two->size,
|
||||
|
@ -63,10 +63,18 @@ static int diff_grep(mmfile_t *one, mmfile_t *two,
|
|||
ecbdata.hit = 0;
|
||||
xecfg.ctxlen = o->context;
|
||||
xecfg.interhunkctxlen = o->interhunkcontext;
|
||||
if (xdi_diff_outf(one, two, discard_hunk_line, diffgrep_consume,
|
||||
&ecbdata, &xpp, &xecfg))
|
||||
return 0;
|
||||
return ecbdata.hit;
|
||||
|
||||
/*
|
||||
* An xdiff error might be our "data->hit" from above. See the
|
||||
* comment for xdiff_emit_line_fn in xdiff-interface.h
|
||||
*/
|
||||
ret = xdi_diff_outf(one, two, discard_hunk_line, diffgrep_consume,
|
||||
&ecbdata, &xpp, &xecfg);
|
||||
if (ecbdata.hit)
|
||||
return 1;
|
||||
if (ret)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int contains(mmfile_t *mf, regex_t *regexp, kwset_t kws,
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
* doing so will currently make your early return indistinguishable
|
||||
* from an error internal to xdiff, xdiff itself will see that
|
||||
* non-zero return and translate it to -1.
|
||||
*
|
||||
* See "diff_grep" in diffcore-pickaxe.c for a trick to work around
|
||||
* this, i.e. using the "consume_callback_data" to note the desired
|
||||
* early return.
|
||||
*/
|
||||
typedef int (*xdiff_emit_line_fn)(void *, char *, unsigned long);
|
||||
typedef void (*xdiff_emit_hunk_fn)(void *data,
|
||||
|
|
Loading…
Reference in New Issue