@matheusbsbs / matheus-bagliano / commits / 0c01857df5
Fork 0

diff: fix handling of binary rewrite diffs

The current emit_rewrite_diff code always writes a text patch without checking whether the content is binary. This means that if you end up with a rewrite diff for a binary file, you get lots of raw binary goo in your patch. Instead, if we have binary files, then let's just skip emit_rewrite_diff altogether. We will already have shown the "dissimilarity index" line, so it is really about the diff contents. If binary diffs are turned off, the "Binary files a/file and b/file differ" message should be the same in either case. If we do have binary patches turned on, there isn't much point in making a less-efficient binary patch that does a total rewrite; no human is going to read it, and since binary patches don't apply with any fuzz anyway, the result of application should be the same. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Dec 9, 2008 at 03:12 UTC 0c01857df57fe8723714e49459e0c061fcaf056b
2 files changed +48 -1
diff.c
+3 -1
@@ -1376,7 +1376,9 @@ static void builtin_diff(const char *name_a,
1376 */
1377 if ((one->mode ^ two->mode) & S_IFMT)
1378 goto free_ab_and_return;
1379 - if (complete_rewrite) {
1379 + if (complete_rewrite &&
1380 + !diff_filespec_is_binary(one) &&
1381 + !diff_filespec_is_binary(two)) {
1382 emit_rewrite_diff(name_a, name_b, one, two, o);
1383 o->found_changes = 1;
1384 goto free_ab_and_return;
t/t4031-diff-rewrite-binary.sh new
+45
@@ -0,0 +1,45 @@
1 +#!/bin/sh
2 +
3 +test_description='rewrite diff on binary file'
4 +
5 +. ./test-lib.sh
6 +
7 +# We must be large enough to meet the MINIMUM_BREAK_SIZE
8 +# requirement.
9 +make_file() {
10 + for i in 1 2 3 4 5 6 7 8 9 10
11 + do
12 + for j in 1 2 3 4 5 6 7 8 9
13 + do
14 + for k in 1 2 3 4 5
15 + do
16 + printf "$1\n"
17 + done
18 + done
19 + done >file
20 +}
21 +
22 +test_expect_success 'create binary file with changes' '
23 + make_file "\\0" &&
24 + git add file &&
25 + make_file "\\01"
26 +'
27 +
28 +test_expect_success 'vanilla diff is binary' '
29 + git diff >diff &&
30 + grep "Binary files a/file and b/file differ" diff
31 +'
32 +
33 +test_expect_success 'rewrite diff is binary' '
34 + git diff -B >diff &&
35 + grep "dissimilarity index" diff &&
36 + grep "Binary files a/file and b/file differ" diff
37 +'
38 +
39 +test_expect_success 'rewrite diff can show binary patch' '
40 + git diff -B --binary >diff &&
41 + grep "dissimilarity index" diff &&
42 + grep "GIT binary patch" diff
43 +'
44 +
45 +test_done