diff: fix "git show -C -C" output when renaming a binary file
A bug was introduced in 3e97c7c6af2901cec63bf35fcd43ae3472e24af8 (No diff -b/-w output for all-whitespace changes, Nov 19 2009) that made the lines: diff --git a/bar b/sub/bar similarity index 100% rename from bar rename to sub/bar disappear from "git show -C -C" output when file bar is a binary file. Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Christian Couder committed
May 26, 2010 at 04:50 UTC
296c6bb21a6980f6e5b42f0790d6365c1e3f696f
3 files changed
+99
-6
diff.c
+17
-6
@@ -1596,6 +1596,7 @@ static void builtin_diff(const char *name_a,
1596
struct diff_filespec *one,
1597
struct diff_filespec *two,
1598
const char *xfrm_msg,
1599
+ int must_show_header,
1600
struct diff_options *o,
1601
int complete_rewrite)
1602
{
@@ -1647,16 +1648,19 @@ static void builtin_diff(const char *name_a,
1648
strbuf_addf(&header, "%snew file mode %06o%s\n", set, two->mode, reset);
1649
if (xfrm_msg && xfrm_msg[0])
1650
strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset);
1651
+ must_show_header = 1;
1652
}
1653
else if (lbl[1][0] == '/') {
1654
strbuf_addf(&header, "%sdeleted file mode %06o%s\n", set, one->mode, reset);
1655
if (xfrm_msg && xfrm_msg[0])
1656
strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset);
1657
+ must_show_header = 1;
1658
}
1659
else {
1660
if (one->mode != two->mode) {
1661
strbuf_addf(&header, "%sold mode %06o%s\n", set, one->mode, reset);
1662
strbuf_addf(&header, "%snew mode %06o%s\n", set, two->mode, reset);
1663
+ must_show_header = 1;
1664
}
1665
if (xfrm_msg && xfrm_msg[0])
1666
strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset);
@@ -1687,8 +1691,11 @@ static void builtin_diff(const char *name_a,
1691
(diff_filespec_is_binary(two) && !textconv_two) )) {
1692
/* Quite common confusing case */
1693
if (mf1.size == mf2.size &&
1690
- !memcmp(mf1.ptr, mf2.ptr, mf1.size))
1694
+ !memcmp(mf1.ptr, mf2.ptr, mf1.size)) {
1695
+ if (must_show_header)
1696
+ fprintf(o->file, "%s", header.buf);
1697
goto free_ab_and_return;
1698
+ }
1699
fprintf(o->file, "%s", header.buf);
1700
strbuf_reset(&header);
1701
if (DIFF_OPT_TST(o, BINARY))
@@ -1706,7 +1713,7 @@ static void builtin_diff(const char *name_a,
1713
struct emit_callback ecbdata;
1714
const struct userdiff_funcname *pe;
1715
1709
- if (!DIFF_XDL_TST(o, WHITESPACE_FLAGS)) {
1716
+ if (!DIFF_XDL_TST(o, WHITESPACE_FLAGS) || must_show_header) {
1717
fprintf(o->file, "%s", header.buf);
1718
strbuf_reset(&header);
1719
}
@@ -2315,8 +2322,10 @@ static void fill_metainfo(struct strbuf *msg,
2322
struct diff_filespec *one,
2323
struct diff_filespec *two,
2324
struct diff_options *o,
2318
- struct diff_filepair *p)
2325
+ struct diff_filepair *p,
2326
+ int *must_show_header)
2327
{
2328
+ *must_show_header = 1;
2329
strbuf_init(msg, PATH_MAX * 2 + 300);
2330
switch (p->status) {
2331
case DIFF_STATUS_COPIED:
@@ -2344,7 +2353,7 @@ static void fill_metainfo(struct strbuf *msg,
2353
/* fallthru */
2354
default:
2355
/* nothing */
2347
- ;
2356
+ *must_show_header = 0;
2357
}
2358
if (one && two && hashcmp(one->sha1, two->sha1)) {
2359
int abbrev = DIFF_OPT_TST(o, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
@@ -2378,9 +2387,10 @@ static void run_diff_cmd(const char *pgm,
2387
{
2388
const char *xfrm_msg = NULL;
2389
int complete_rewrite = (p->status == DIFF_STATUS_MODIFIED) && p->score;
2390
+ int must_show_header = 0;
2391
2392
if (msg) {
2383
- fill_metainfo(msg, name, other, one, two, o, p);
2393
+ fill_metainfo(msg, name, other, one, two, o, p, &must_show_header);
2394
xfrm_msg = msg->len ? msg->buf : NULL;
2395
}
2396
@@ -2399,7 +2409,8 @@ static void run_diff_cmd(const char *pgm,
2409
}
2410
if (one && two)
2411
builtin_diff(name, other ? other : name,
2402
- one, two, xfrm_msg, o, complete_rewrite);
2412
+ one, two, xfrm_msg, must_show_header,
2413
+ o, complete_rewrite);
2414
else
2415
fprintf(o->file, "* Unmerged path %s\n", name);
2416
}
t/t4015-diff-whitespace.sh
+37
@@ -396,6 +396,43 @@ test_expect_success 'whitespace-only changes not reported' '
396
test_cmp expect actual
397
'
398
399
+cat <<EOF >expect
400
+diff --git a/x b/z
401
+similarity index NUM%
402
+rename from x
403
+rename to z
404
+index 380c32a..a97b785 100644
405
+EOF
406
+test_expect_success 'whitespace-only changes reported across renames' '
407
+ git reset --hard &&
408
+ for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x &&
409
+ git add x &&
410
+ git commit -m "base" &&
411
+ sed -e "5s/^/ /" x >z &&
412
+ git rm x &&
413
+ git add z &&
414
+ git diff -w -M --cached |
415
+ sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" >actual &&
416
+ test_cmp expect actual
417
+'
418
+
419
+cat >expected <<\EOF
420
+diff --git a/empty b/void
421
+similarity index 100%
422
+rename from empty
423
+rename to void
424
+EOF
425
+
426
+test_expect_success 'rename empty' '
427
+ git reset --hard &&
428
+ >empty &&
429
+ git add empty &&
430
+ git commit -m empty &&
431
+ git mv empty void &&
432
+ git diff -w --cached -M >current &&
433
+ test_cmp expected current
434
+'
435
+
436
test_expect_success 'combined diff with autocrlf conversion' '
437
438
git reset --hard &&
t/t4043-diff-rename-binary.sh
new
+45
@@ -0,0 +1,45 @@
1
+#!/bin/sh
2
+#
3
+# Copyright (c) 2010 Jakub Narebski, Christian Couder
4
+#
5
+
6
+test_description='Move a binary file'
7
+
8
+. ./test-lib.sh
9
+
10
+
11
+test_expect_success 'prepare repository' '
12
+ git init &&
13
+ echo foo > foo &&
14
+ echo "barQ" | q_to_nul > bar &&
15
+ git add . &&
16
+ git commit -m "Initial commit"
17
+'
18
+
19
+test_expect_success 'move the files into a "sub" directory' '
20
+ mkdir sub &&
21
+ git mv bar foo sub/ &&
22
+ git commit -m "Moved to sub/"
23
+'
24
+
25
+cat > expected <<\EOF
26
+ bar => sub/bar | Bin 5 -> 5 bytes
27
+ foo => sub/foo | 0
28
+ 2 files changed, 0 insertions(+), 0 deletions(-)
29
+
30
+diff --git a/bar b/sub/bar
31
+similarity index 100%
32
+rename from bar
33
+rename to sub/bar
34
+diff --git a/foo b/sub/foo
35
+similarity index 100%
36
+rename from foo
37
+rename to sub/foo
38
+EOF
39
+
40
+test_expect_success 'git show -C -C report renames' '
41
+ git show -C -C --raw --binary --stat | tail -n 12 > current &&
42
+ test_cmp expected current
43
+'
44
+
45
+test_done