xdiff: fix merging of appended hunk with -W

When -W is given we search the lines between the end of the current context and the next change for a function line. If there is none then we merge those two hunks as they must be part of the same function. If the next change is an appended chunk we abort the search early in get_func_line(), however, because its line number is out of range. Fix that by searching from the end of the pre-image in that case instead. Reported-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>

René Scharfe committed Jun 9, 2016 at 23:54 UTC 6f8d9bccb2c3694c62d14225976689c1e8c50fa5
2 files changed +25 -2
t/t4051-diff-function-context.sh
+23 -1
@@ -64,7 +64,13 @@ test_expect_success 'setup' '
64
65 grep -v "Begin of second part" <file.c >file.c.new &&
66 mv file.c.new file.c &&
67 - commit_and_tag long_common_tail file.c
67 + commit_and_tag long_common_tail file.c &&
68 +
69 + git checkout initial &&
70 + grep -v "delete me from hello" <file.c >file.c.new &&
71 + mv file.c.new file.c &&
72 + cat "$dir/appended1.c" >>file.c &&
73 + commit_and_tag changed_hello_appended file.c
74 '
75
76 check_diff changed_hello 'changed function'
@@ -157,4 +163,20 @@ test_expect_success ' context does not include preceding empty lines' '
163 test "$(first_context_line <long_common_tail.diff.diff)" != " "
164 '
165
166 +check_diff changed_hello_appended 'changed function plus appended function'
167 +
168 +test_expect_success ' context includes begin' '
169 + grep "^ .*Begin of hello" changed_hello_appended.diff &&
170 + grep "^[+].*Begin of first part" changed_hello_appended.diff
171 +'
172 +
173 +test_expect_success ' context includes end' '
174 + grep "^ .*End of hello" changed_hello_appended.diff &&
175 + grep "^[+].*End of first part" changed_hello_appended.diff
176 +'
177 +
178 +test_expect_success ' context does not include other functions' '
179 + test $(grep -c "^[ +-].*Begin" changed_hello_appended.diff) -le 2
180 +'
181 +
182 test_done
xdiff/xemit.c
+2 -1
@@ -246,7 +246,8 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
246 * its new end.
247 */
248 if (xche->next) {
249 - long l = xche->next->i1;
249 + long l = XDL_MIN(xche->next->i1,
250 + xe->xdf1.nrec - 1);
251 if (l <= e1 ||
252 get_func_line(xe, xecfg, NULL, l, e1) < 0) {
253 xche = xche->next;