Skip to content

Commit 2179870

Browse files
trastgitster
authored andcommitted
combined diff: correctly handle truncated file
Consider an evil merge of two commits A and B, both of which have a file 'foo', but the merge result does not have that file. The combined-diff code learned in 4462731 (combine-diff: do not punt on removed or added files., 2006-02-06) to concisely show only the removal, since that is the evil part and the previous contents are presumably uninteresting. However, to diagnose an empty merge result, it overloaded the variable that holds the file's length. This means that the check also triggers for truncated files. Consequently, such files were not shown in the diff at all despite the merge being clearly evil. Fix this by adding a new variable that distinguishes whether the file was deleted (which is the case 4462731 handled) or truncated. In the truncated case, we show the full combined diff again, which is rather spammy but at least does not hide the evilness. Reported-by: David Martínez Martí <[email protected]> Signed-off-by: Thomas Rast <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent fff0d0a commit 2179870

File tree

2 files changed

+16
-6
lines changed

2 files changed

+16
-6
lines changed

combine-diff.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ static void consume_line(void *state_, char *line, unsigned long len)
204204
static void combine_diff(const unsigned char *parent, unsigned int mode,
205205
mmfile_t *result_file,
206206
struct sline *sline, unsigned int cnt, int n,
207-
int num_parent)
207+
int num_parent, int result_deleted)
208208
{
209209
unsigned int p_lno, lno;
210210
unsigned long nmask = (1UL << n);
@@ -215,7 +215,7 @@ static void combine_diff(const unsigned char *parent, unsigned int mode,
215215
struct combine_diff_state state;
216216
unsigned long sz;
217217

218-
if (!cnt)
218+
if (result_deleted)
219219
return; /* result deleted */
220220

221221
parent_file.ptr = grab_blob(parent, mode, &sz);
@@ -517,7 +517,7 @@ static void show_line_to_eol(const char *line, int len, const char *reset)
517517
}
518518

519519
static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
520-
int use_color)
520+
int use_color, int result_deleted)
521521
{
522522
unsigned long mark = (1UL<<num_parent);
523523
unsigned long no_pre_delete = (2UL<<num_parent);
@@ -530,7 +530,7 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
530530
const char *c_plain = diff_get_color(use_color, DIFF_PLAIN);
531531
const char *c_reset = diff_get_color(use_color, DIFF_RESET);
532532

533-
if (!cnt)
533+
if (result_deleted)
534534
return; /* result deleted */
535535

536536
while (1) {
@@ -687,6 +687,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
687687
{
688688
struct diff_options *opt = &rev->diffopt;
689689
unsigned long result_size, cnt, lno;
690+
int result_deleted = 0;
690691
char *result, *cp;
691692
struct sline *sline; /* survived lines */
692693
int mode_differs = 0;
@@ -767,6 +768,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
767768
}
768769
else {
769770
deleted_file:
771+
result_deleted = 1;
770772
result_size = 0;
771773
elem->mode = 0;
772774
result = xcalloc(1, 1);
@@ -823,7 +825,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
823825
combine_diff(elem->parent[i].sha1,
824826
elem->parent[i].mode,
825827
&result_file, sline,
826-
cnt, i, num_parent);
828+
cnt, i, num_parent, result_deleted);
827829
if (elem->parent[i].mode != elem->mode)
828830
mode_differs = 1;
829831
}
@@ -889,7 +891,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
889891
dump_quoted_path("+++ ", b_prefix, elem->path,
890892
c_meta, c_reset);
891893
dump_sline(sline, cnt, num_parent,
892-
DIFF_OPT_TST(opt, COLOR_DIFF));
894+
DIFF_OPT_TST(opt, COLOR_DIFF), result_deleted);
893895
}
894896
free(result);
895897

t/t4038-diff-combined.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,12 @@ test_expect_success 'check combined output (2)' '
8181
verify_helper sidesansone
8282
'
8383

84+
test_expect_success 'diagnose truncated file' '
85+
>file &&
86+
git add file &&
87+
git commit --amend -C HEAD &&
88+
git show >out &&
89+
grep "diff --cc file" out
90+
'
91+
8492
test_done

0 commit comments

Comments
 (0)