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>
			
			
				maint
			
			
		
							parent
							
								
									dfea79004c
								
							
						
					
					
						commit
						296c6bb21a
					
				
							
								
								
									
										23
									
								
								diff.c
								
								
								
								
							
							
						
						
									
										23
									
								
								diff.c
								
								
								
								
							|  | @ -1596,6 +1596,7 @@ static void builtin_diff(const char *name_a, | |||
| 			 struct diff_filespec *one, | ||||
| 			 struct diff_filespec *two, | ||||
| 			 const char *xfrm_msg, | ||||
| 			 int must_show_header, | ||||
| 			 struct diff_options *o, | ||||
| 			 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); | ||||
| 		if (xfrm_msg && xfrm_msg[0]) | ||||
| 			strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset); | ||||
| 		must_show_header = 1; | ||||
| 	} | ||||
| 	else if (lbl[1][0] == '/') { | ||||
| 		strbuf_addf(&header, "%sdeleted file mode %06o%s\n", set, one->mode, reset); | ||||
| 		if (xfrm_msg && xfrm_msg[0]) | ||||
| 			strbuf_addf(&header, "%s%s%s\n", set, xfrm_msg, reset); | ||||
| 		must_show_header = 1; | ||||
| 	} | ||||
| 	else { | ||||
| 		if (one->mode != two->mode) { | ||||
| 			strbuf_addf(&header, "%sold mode %06o%s\n", set, one->mode, reset); | ||||
| 			strbuf_addf(&header, "%snew mode %06o%s\n", set, two->mode, reset); | ||||
| 			must_show_header = 1; | ||||
| 		} | ||||
| 		if (xfrm_msg && xfrm_msg[0]) | ||||
| 			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) )) { | ||||
| 		/* Quite common confusing case */ | ||||
| 		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; | ||||
| 		} | ||||
| 		fprintf(o->file, "%s", header.buf); | ||||
| 		strbuf_reset(&header); | ||||
| 		if (DIFF_OPT_TST(o, BINARY)) | ||||
|  | @ -1706,7 +1713,7 @@ static void builtin_diff(const char *name_a, | |||
| 		struct emit_callback ecbdata; | ||||
| 		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); | ||||
| 			strbuf_reset(&header); | ||||
| 		} | ||||
|  | @ -2315,8 +2322,10 @@ static void fill_metainfo(struct strbuf *msg, | |||
| 			  struct diff_filespec *one, | ||||
| 			  struct diff_filespec *two, | ||||
| 			  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); | ||||
| 	switch (p->status) { | ||||
| 	case DIFF_STATUS_COPIED: | ||||
|  | @ -2344,7 +2353,7 @@ static void fill_metainfo(struct strbuf *msg, | |||
| 		/* fallthru */ | ||||
| 	default: | ||||
| 		/* nothing */ | ||||
| 		; | ||||
| 		*must_show_header = 0; | ||||
| 	} | ||||
| 	if (one && two && hashcmp(one->sha1, two->sha1)) { | ||||
| 		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; | ||||
| 	int complete_rewrite = (p->status == DIFF_STATUS_MODIFIED) && p->score; | ||||
| 	int must_show_header = 0; | ||||
|  | ||||
| 	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; | ||||
| 	} | ||||
|  | ||||
|  | @ -2399,7 +2409,8 @@ static void run_diff_cmd(const char *pgm, | |||
| 	} | ||||
| 	if (one && two) | ||||
| 		builtin_diff(name, other ? other : name, | ||||
| 			     one, two, xfrm_msg, o, complete_rewrite); | ||||
| 			     one, two, xfrm_msg, must_show_header, | ||||
| 			     o, complete_rewrite); | ||||
| 	else | ||||
| 		fprintf(o->file, "* Unmerged path %s\n", name); | ||||
| } | ||||
|  |  | |||
|  | @ -396,6 +396,43 @@ test_expect_success 'whitespace-only changes not reported' ' | |||
| 	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' ' | ||||
|  | ||||
| 	git reset --hard && | ||||
|  |  | |||
|  | @ -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 | ||||
		Loading…
	
		Reference in New Issue
	
	 Christian Couder
						Christian Couder