Browse Source

xdiff: handle appended chunks better with -W

If lines are added at the end of a file, diff -W shows the whole file.
That's because get_func_line() only considers the pre-image and gives up
if it sees a record index beyond its end.

Consider the post-image as well to see if the added lines already make
up a full function.  If it doesn't then search for the previous function
line by starting from the bottom of the pre-image, thereby avoiding to
confuse get_func_line().

Reuse the existing label called "again", as it's exactly where we need
to jump to when we're done handling the pre-context, but rename it to
"post_context_calculation" in order to document its new purpose better.

Reported-by: Junio C Hamano <gitster@pobox.com>
Initial-patch-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
René Scharfe 9 years ago committed by Junio C Hamano
parent
commit
6d5badb238
  1. 2
      t/t4051-diff-function-context.sh
  2. 27
      xdiff/xemit.c

2
t/t4051-diff-function-context.sh

@ -131,7 +131,7 @@ test_expect_success ' context includes end' ' @@ -131,7 +131,7 @@ test_expect_success ' context includes end' '
grep "^[+].*End of second part" extended.diff
'

test_expect_failure ' context does not include other functions' '
test_expect_success ' context does not include other functions' '
test $(grep -c "^[ +-].*Begin" extended.diff) -le 2
'


27
xdiff/xemit.c

@ -171,7 +171,28 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, @@ -171,7 +171,28 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
s2 = XDL_MAX(xch->i2 - xecfg->ctxlen, 0);

if (xecfg->flags & XDL_EMIT_FUNCCONTEXT) {
long fs1 = get_func_line(xe, xecfg, NULL, xch->i1, -1);
long fs1, i1 = xch->i1;

/* Appended chunk? */
if (i1 >= xe->xdf1.nrec) {
char dummy[1];

/*
* We don't need additional context if
* a whole function was added.
*/
if (match_func_rec(&xe->xdf2, xecfg, xch->i2,
dummy, sizeof(dummy)) >= 0)
goto post_context_calculation;

/*
* Otherwise get more context from the
* pre-image.
*/
i1 = xe->xdf1.nrec - 1;
}

fs1 = get_func_line(xe, xecfg, NULL, i1, -1);
if (fs1 < 0)
fs1 = 0;
if (fs1 < s1) {
@ -180,7 +201,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, @@ -180,7 +201,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
}
}

again:
post_context_calculation:
lctx = xecfg->ctxlen;
lctx = XDL_MIN(lctx, xe->xdf1.nrec - (xche->i1 + xche->chg1));
lctx = XDL_MIN(lctx, xe->xdf2.nrec - (xche->i2 + xche->chg2));
@ -209,7 +230,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, @@ -209,7 +230,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
if (l <= e1 ||
get_func_line(xe, xecfg, NULL, l, e1) < 0) {
xche = xche->next;
goto again;
goto post_context_calculation;
}
}
}

Loading…
Cancel
Save