Skip to content

Commit ded0abc

Browse files
peffgitster
authored andcommitted
diff: handle diffstat of rewritten binary files
The logic in builtin_diffstat assumes that a complete_rewrite pair should have its lines counted. This is nonsensical for binary files and leads to confusing things like: $ git diff --stat --summary HEAD^ HEAD foo.rand | Bin 4096 -> 4096 bytes 1 files changed, 0 insertions(+), 0 deletions(-) $ git diff --stat --summary -B HEAD^ HEAD foo.rand | 34 +++++++++++++++------------------- 1 files changed, 15 insertions(+), 19 deletions(-) rewrite foo.rand (100%) So let's reorder the function to handle binary files first (which from diffstat's perspective look like complete rewrites anyway), then rewrites, then actual diffstats. There are two bonus prizes to this reorder: 1. It gets rid of a now-superfluous goto. 2. The binary case is at the top, which means we can further optimize it in the next patch. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e923eae commit ded0abc

File tree

2 files changed

+21
-10
lines changed

2 files changed

+21
-10
lines changed

diff.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,34 +1811,38 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
18111811
data->is_unmerged = 1;
18121812
return;
18131813
}
1814-
if (complete_rewrite) {
1814+
1815+
if (diff_filespec_is_binary(one) || diff_filespec_is_binary(two)) {
1816+
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
1817+
die("unable to read files to diff");
1818+
data->is_binary = 1;
1819+
data->added = mf2.size;
1820+
data->deleted = mf1.size;
1821+
}
1822+
1823+
else if (complete_rewrite) {
18151824
diff_populate_filespec(one, 0);
18161825
diff_populate_filespec(two, 0);
18171826
data->deleted = count_lines(one->data, one->size);
18181827
data->added = count_lines(two->data, two->size);
1819-
goto free_and_return;
18201828
}
1821-
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
1822-
die("unable to read files to diff");
18231829

1824-
if (diff_filespec_is_binary(one) || diff_filespec_is_binary(two)) {
1825-
data->is_binary = 1;
1826-
data->added = mf2.size;
1827-
data->deleted = mf1.size;
1828-
} else {
1830+
else {
18291831
/* Crazy xdl interfaces.. */
18301832
xpparam_t xpp;
18311833
xdemitconf_t xecfg;
18321834
xdemitcb_t ecb;
18331835

1836+
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
1837+
die("unable to read files to diff");
1838+
18341839
memset(&xpp, 0, sizeof(xpp));
18351840
memset(&xecfg, 0, sizeof(xecfg));
18361841
xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
18371842
xdi_diff_outf(&mf1, &mf2, diffstat_consume, diffstat,
18381843
&xpp, &xecfg, &ecb);
18391844
}
18401845

1841-
free_and_return:
18421846
diff_free_filespec_data(one);
18431847
diff_free_filespec_data(two);
18441848
}

t/t4031-diff-rewrite-binary.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ test_expect_success 'rewrite diff can show binary patch' '
4444
grep "GIT binary patch" diff
4545
'
4646

47+
test_expect_success 'rewrite diff --stat shows binary changes' '
48+
git diff -B --stat --summary >diff &&
49+
grep "Bin" diff &&
50+
grep "0 insertions.*0 deletions" diff &&
51+
grep " rewrite file" diff
52+
'
53+
4754
{
4855
echo "#!$SHELL_PATH"
4956
cat <<'EOF'

0 commit comments

Comments
 (0)