Skip to content

Commit 6d5badb

Browse files
rscharfegitster
authored andcommitted
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 <[email protected]> Initial-patch-by: Junio C Hamano <[email protected]> Signed-off-by: Rene Scharfe <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent ff2981f commit 6d5badb

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

t/t4051-diff-function-context.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ test_expect_success ' context includes end' '
131131
grep "^[+].*End of second part" extended.diff
132132
'
133133

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

xdiff/xemit.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,28 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
171171
s2 = XDL_MAX(xch->i2 - xecfg->ctxlen, 0);
172172

173173
if (xecfg->flags & XDL_EMIT_FUNCCONTEXT) {
174-
long fs1 = get_func_line(xe, xecfg, NULL, xch->i1, -1);
174+
long fs1, i1 = xch->i1;
175+
176+
/* Appended chunk? */
177+
if (i1 >= xe->xdf1.nrec) {
178+
char dummy[1];
179+
180+
/*
181+
* We don't need additional context if
182+
* a whole function was added.
183+
*/
184+
if (match_func_rec(&xe->xdf2, xecfg, xch->i2,
185+
dummy, sizeof(dummy)) >= 0)
186+
goto post_context_calculation;
187+
188+
/*
189+
* Otherwise get more context from the
190+
* pre-image.
191+
*/
192+
i1 = xe->xdf1.nrec - 1;
193+
}
194+
195+
fs1 = get_func_line(xe, xecfg, NULL, i1, -1);
175196
if (fs1 < 0)
176197
fs1 = 0;
177198
if (fs1 < s1) {
@@ -180,7 +201,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
180201
}
181202
}
182203

183-
again:
204+
post_context_calculation:
184205
lctx = xecfg->ctxlen;
185206
lctx = XDL_MIN(lctx, xe->xdf1.nrec - (xche->i1 + xche->chg1));
186207
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,
209230
if (l <= e1 ||
210231
get_func_line(xe, xecfg, NULL, l, e1) < 0) {
211232
xche = xche->next;
212-
goto again;
233+
goto post_context_calculation;
213234
}
214235
}
215236
}

0 commit comments

Comments
 (0)