From 0c01857df57fe8723714e49459e0c061fcaf056b Mon Sep 17 00:00:00 2001 From: Jeff King Date: Tue, 9 Dec 2008 03:12:28 -0500 Subject: 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 Signed-off-by: Junio C Hamano --- t/t4031-diff-rewrite-binary.sh | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100755 t/t4031-diff-rewrite-binary.sh (limited to 't/t4031-diff-rewrite-binary.sh') diff --git a/t/t4031-diff-rewrite-binary.sh b/t/t4031-diff-rewrite-binary.sh new file mode 100755 index 0000000000..e16c355103 --- /dev/null +++ b/t/t4031-diff-rewrite-binary.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +test_description='rewrite diff on binary file' + +. ./test-lib.sh + +# We must be large enough to meet the MINIMUM_BREAK_SIZE +# requirement. +make_file() { + for i in 1 2 3 4 5 6 7 8 9 10 + do + for j in 1 2 3 4 5 6 7 8 9 + do + for k in 1 2 3 4 5 + do + printf "$1\n" + done + done + done >file +} + +test_expect_success 'create binary file with changes' ' + make_file "\\0" && + git add file && + make_file "\\01" +' + +test_expect_success 'vanilla diff is binary' ' + git diff >diff && + grep "Binary files a/file and b/file differ" diff +' + +test_expect_success 'rewrite diff is binary' ' + git diff -B >diff && + grep "dissimilarity index" diff && + grep "Binary files a/file and b/file differ" diff +' + +test_expect_success 'rewrite diff can show binary patch' ' + git diff -B --binary >diff && + grep "dissimilarity index" diff && + grep "GIT binary patch" diff +' + +test_done -- cgit v1.2.3 From 3aa1f7ca3779f73164b285c070b71abcdd7397c1 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Tue, 9 Dec 2008 03:13:21 -0500 Subject: diff: respect textconv in rewrite diffs Currently we just skip rewrite diffs for binary files; this patch makes an exception for files which will be textconv'd, and actually performs the textconv before generating the diff. Conceptually, rewrite diffs should be in the exact same format as the a non-rewrite diff, except that we refuse to share any context. Thus it makes very little sense for "git diff" to show a textconv'd diff, but for "git diff -B" to show "Binary files differ". Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- t/t4031-diff-rewrite-binary.sh | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 't/t4031-diff-rewrite-binary.sh') diff --git a/t/t4031-diff-rewrite-binary.sh b/t/t4031-diff-rewrite-binary.sh index e16c355103..157ed85a79 100755 --- a/t/t4031-diff-rewrite-binary.sh +++ b/t/t4031-diff-rewrite-binary.sh @@ -7,6 +7,8 @@ test_description='rewrite diff on binary file' # We must be large enough to meet the MINIMUM_BREAK_SIZE # requirement. make_file() { + # common first line to help identify rewrite versus regular diff + printf "=\n" >file for i in 1 2 3 4 5 6 7 8 9 10 do for j in 1 2 3 4 5 6 7 8 9 @@ -16,7 +18,7 @@ make_file() { printf "$1\n" done done - done >file + done >>file } test_expect_success 'create binary file with changes' ' @@ -42,4 +44,24 @@ test_expect_success 'rewrite diff can show binary patch' ' grep "GIT binary patch" diff ' +{ + echo "#!$SHELL_PATH" + cat >dump <<'EOF' +perl -e '$/ = undef; $_ = <>; s/./ord($&)/ge; print $_' < "$1" +EOF +} >dump +chmod +x dump + +test_expect_success 'setup textconv' ' + echo file diff=foo >.gitattributes && + git config diff.foo.textconv "$PWD"/dump +' + +test_expect_success 'rewrite diff respects textconv' ' + git diff -B >diff && + grep "dissimilarity index" diff && + grep "^-61" diff && + grep "^-0" diff +' + test_done -- cgit v1.2.3 From de749a972d3e262de27928785c83c7b286a18df0 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 10 Dec 2008 11:39:07 -0800 Subject: Fix t4031 When I tweaked the patch to use $SHELL_PATH instead of a hard-coded "#!/bin/sh" to produce 3aa1f7c (diff: respect textconv in rewrite diffs, 2008-12-09), I screwed up. This should fix it. Signed-off-by: Junio C Hamano --- t/t4031-diff-rewrite-binary.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 't/t4031-diff-rewrite-binary.sh') diff --git a/t/t4031-diff-rewrite-binary.sh b/t/t4031-diff-rewrite-binary.sh index 157ed85a79..a894c60622 100755 --- a/t/t4031-diff-rewrite-binary.sh +++ b/t/t4031-diff-rewrite-binary.sh @@ -46,7 +46,7 @@ test_expect_success 'rewrite diff can show binary patch' ' { echo "#!$SHELL_PATH" - cat >dump <<'EOF' + cat <<'EOF' perl -e '$/ = undef; $_ = <>; s/./ord($&)/ge; print $_' < "$1" EOF } >dump -- cgit v1.2.3