Skip to content

Commit

Permalink
combined diff: correctly handle truncated file
Browse files Browse the repository at this point in the history
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í <desarrollo@gestiweb.com>
Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Thomas Rast authored and Junio C Hamano committed Apr 17, 2010
1 parent fff0d0a commit 2179870
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 6 deletions.
14 changes: 8 additions & 6 deletions combine-diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ static void consume_line(void *state_, char *line, unsigned long len)
static void combine_diff(const unsigned char *parent, unsigned int mode,
mmfile_t *result_file,
struct sline *sline, unsigned int cnt, int n,
int num_parent)
int num_parent, int result_deleted)
{
unsigned int p_lno, lno;
unsigned long nmask = (1UL << n);
Expand All @@ -215,7 +215,7 @@ static void combine_diff(const unsigned char *parent, unsigned int mode,
struct combine_diff_state state;
unsigned long sz;

if (!cnt)
if (result_deleted)
return; /* result deleted */

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

static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
int use_color)
int use_color, int result_deleted)
{
unsigned long mark = (1UL<<num_parent);
unsigned long no_pre_delete = (2UL<<num_parent);
Expand All @@ -530,7 +530,7 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
const char *c_plain = diff_get_color(use_color, DIFF_PLAIN);
const char *c_reset = diff_get_color(use_color, DIFF_RESET);

if (!cnt)
if (result_deleted)
return; /* result deleted */

while (1) {
Expand Down Expand Up @@ -687,6 +687,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
{
struct diff_options *opt = &rev->diffopt;
unsigned long result_size, cnt, lno;
int result_deleted = 0;
char *result, *cp;
struct sline *sline; /* survived lines */
int mode_differs = 0;
Expand Down Expand Up @@ -767,6 +768,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
}
else {
deleted_file:
result_deleted = 1;
result_size = 0;
elem->mode = 0;
result = xcalloc(1, 1);
Expand Down Expand Up @@ -823,7 +825,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
combine_diff(elem->parent[i].sha1,
elem->parent[i].mode,
&result_file, sline,
cnt, i, num_parent);
cnt, i, num_parent, result_deleted);
if (elem->parent[i].mode != elem->mode)
mode_differs = 1;
}
Expand Down Expand Up @@ -889,7 +891,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
dump_quoted_path("+++ ", b_prefix, elem->path,
c_meta, c_reset);
dump_sline(sline, cnt, num_parent,
DIFF_OPT_TST(opt, COLOR_DIFF));
DIFF_OPT_TST(opt, COLOR_DIFF), result_deleted);
}
free(result);

Expand Down
8 changes: 8 additions & 0 deletions t/t4038-diff-combined.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,12 @@ test_expect_success 'check combined output (2)' '
verify_helper sidesansone
'

test_expect_success 'diagnose truncated file' '
>file &&
git add file &&
git commit --amend -C HEAD &&
git show >out &&
grep "diff --cc file" out
'

test_done

0 comments on commit 2179870

Please sign in to comment.