diff: fix "git show -C -C" output when renaming a binary file

A bug was introduced in 3e97c7c6af
(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>
This commit is contained in:
Christian Couder 2010-05-26 04:50:12 +02:00 коммит произвёл Junio C Hamano
Родитель dfea79004c
Коммит 296c6bb21a
3 изменённых файлов: 99 добавлений и 6 удалений

23
diff.c
Просмотреть файл

@ -1596,6 +1596,7 @@ static void builtin_diff(const char *name_a,
struct diff_filespec *one, struct diff_filespec *one,
struct diff_filespec *two, struct diff_filespec *two,
const char *xfrm_msg, const char *xfrm_msg,
int must_show_header,
struct diff_options *o, struct diff_options *o,
int complete_rewrite) int complete_rewrite)
{ {
@ -1647,16 +1648,19 @@ static void builtin_diff(const char *name_a,
strbuf_addf(&header, "%snew file mode %06o%s\n", set, two->mode, reset); strbuf_addf(&header, "%snew file mode %06o%s\n", set, two->mode, reset);
if (xfrm_msg && xfrm_msg[0]) if (xfrm_msg && xfrm_msg[0])
strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset); strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset);
must_show_header = 1;
} }
else if (lbl[1][0] == '/') { else if (lbl[1][0] == '/') {
strbuf_addf(&header, "%sdeleted file mode %06o%s\n", set, one->mode, reset); strbuf_addf(&header, "%sdeleted file mode %06o%s\n", set, one->mode, reset);
if (xfrm_msg && xfrm_msg[0]) if (xfrm_msg && xfrm_msg[0])
strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset); strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset);
must_show_header = 1;
} }
else { else {
if (one->mode != two->mode) { if (one->mode != two->mode) {
strbuf_addf(&header, "%sold mode %06o%s\n", set, one->mode, reset); strbuf_addf(&header, "%sold mode %06o%s\n", set, one->mode, reset);
strbuf_addf(&header, "%snew mode %06o%s\n", set, two->mode, reset); strbuf_addf(&header, "%snew mode %06o%s\n", set, two->mode, reset);
must_show_header = 1;
} }
if (xfrm_msg && xfrm_msg[0]) if (xfrm_msg && xfrm_msg[0])
strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset); strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset);
@ -1687,8 +1691,11 @@ static void builtin_diff(const char *name_a,
(diff_filespec_is_binary(two) && !textconv_two) )) { (diff_filespec_is_binary(two) && !textconv_two) )) {
/* Quite common confusing case */ /* Quite common confusing case */
if (mf1.size == mf2.size && if (mf1.size == mf2.size &&
!memcmp(mf1.ptr, mf2.ptr, mf1.size)) !memcmp(mf1.ptr, mf2.ptr, mf1.size)) {
if (must_show_header)
fprintf(o->file, "%s", header.buf);
goto free_ab_and_return; goto free_ab_and_return;
}
fprintf(o->file, "%s", header.buf); fprintf(o->file, "%s", header.buf);
strbuf_reset(&header); strbuf_reset(&header);
if (DIFF_OPT_TST(o, BINARY)) if (DIFF_OPT_TST(o, BINARY))
@ -1706,7 +1713,7 @@ static void builtin_diff(const char *name_a,
struct emit_callback ecbdata; struct emit_callback ecbdata;
const struct userdiff_funcname *pe; const struct userdiff_funcname *pe;
if (!DIFF_XDL_TST(o, WHITESPACE_FLAGS)) { if (!DIFF_XDL_TST(o, WHITESPACE_FLAGS) || must_show_header) {
fprintf(o->file, "%s", header.buf); fprintf(o->file, "%s", header.buf);
strbuf_reset(&header); strbuf_reset(&header);
} }
@ -2315,8 +2322,10 @@ static void fill_metainfo(struct strbuf *msg,
struct diff_filespec *one, struct diff_filespec *one,
struct diff_filespec *two, struct diff_filespec *two,
struct diff_options *o, struct diff_options *o,
struct diff_filepair *p) struct diff_filepair *p,
int *must_show_header)
{ {
*must_show_header = 1;
strbuf_init(msg, PATH_MAX * 2 + 300); strbuf_init(msg, PATH_MAX * 2 + 300);
switch (p->status) { switch (p->status) {
case DIFF_STATUS_COPIED: case DIFF_STATUS_COPIED:
@ -2344,7 +2353,7 @@ static void fill_metainfo(struct strbuf *msg,
/* fallthru */ /* fallthru */
default: default:
/* nothing */ /* nothing */
; *must_show_header = 0;
} }
if (one && two && hashcmp(one->sha1, two->sha1)) { if (one && two && hashcmp(one->sha1, two->sha1)) {
int abbrev = DIFF_OPT_TST(o, FULL_INDEX) ? 40 : DEFAULT_ABBREV; int abbrev = DIFF_OPT_TST(o, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
@ -2378,9 +2387,10 @@ static void run_diff_cmd(const char *pgm,
{ {
const char *xfrm_msg = NULL; const char *xfrm_msg = NULL;
int complete_rewrite = (p->status == DIFF_STATUS_MODIFIED) && p->score; int complete_rewrite = (p->status == DIFF_STATUS_MODIFIED) && p->score;
int must_show_header = 0;
if (msg) { if (msg) {
fill_metainfo(msg, name, other, one, two, o, p); fill_metainfo(msg, name, other, one, two, o, p, &must_show_header);
xfrm_msg = msg->len ? msg->buf : NULL; xfrm_msg = msg->len ? msg->buf : NULL;
} }
@ -2399,7 +2409,8 @@ static void run_diff_cmd(const char *pgm,
} }
if (one && two) if (one && two)
builtin_diff(name, other ? other : name, builtin_diff(name, other ? other : name,
one, two, xfrm_msg, o, complete_rewrite); one, two, xfrm_msg, must_show_header,
o, complete_rewrite);
else else
fprintf(o->file, "* Unmerged path %s\n", name); fprintf(o->file, "* Unmerged path %s\n", name);
} }

Просмотреть файл

@ -396,6 +396,43 @@ test_expect_success 'whitespace-only changes not reported' '
test_cmp expect actual test_cmp expect actual
' '
cat <<EOF >expect
diff --git a/x b/z
similarity index NUM%
rename from x
rename to z
index 380c32a..a97b785 100644
EOF
test_expect_success 'whitespace-only changes reported across renames' '
git reset --hard &&
for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x &&
git add x &&
git commit -m "base" &&
sed -e "5s/^/ /" x >z &&
git rm x &&
git add z &&
git diff -w -M --cached |
sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" >actual &&
test_cmp expect actual
'
cat >expected <<\EOF
diff --git a/empty b/void
similarity index 100%
rename from empty
rename to void
EOF
test_expect_success 'rename empty' '
git reset --hard &&
>empty &&
git add empty &&
git commit -m empty &&
git mv empty void &&
git diff -w --cached -M >current &&
test_cmp expected current
'
test_expect_success 'combined diff with autocrlf conversion' ' test_expect_success 'combined diff with autocrlf conversion' '
git reset --hard && git reset --hard &&

45
t/t4043-diff-rename-binary.sh Executable file
Просмотреть файл

@ -0,0 +1,45 @@
#!/bin/sh
#
# Copyright (c) 2010 Jakub Narebski, Christian Couder
#
test_description='Move a binary file'
. ./test-lib.sh
test_expect_success 'prepare repository' '
git init &&
echo foo > foo &&
echo "barQ" | q_to_nul > bar &&
git add . &&
git commit -m "Initial commit"
'
test_expect_success 'move the files into a "sub" directory' '
mkdir sub &&
git mv bar foo sub/ &&
git commit -m "Moved to sub/"
'
cat > expected <<\EOF
bar => sub/bar | Bin 5 -> 5 bytes
foo => sub/foo | 0
2 files changed, 0 insertions(+), 0 deletions(-)
diff --git a/bar b/sub/bar
similarity index 100%
rename from bar
rename to sub/bar
diff --git a/foo b/sub/foo
similarity index 100%
rename from foo
rename to sub/foo
EOF
test_expect_success 'git show -C -C report renames' '
git show -C -C --raw --binary --stat | tail -n 12 > current &&
test_cmp expected current
'
test_done