Commit 1c7fb21246629d6d5c7dd5d6eaf646339c57ab1c

Edward Thomson 2020-04-01T20:00:24

Merge pull request #5466 from pks-t/pks/patch-modechange-with-rename patch: correctly handle mode changes for renames

diff --git a/src/diff_print.c b/src/diff_print.c
index 369e5c1..a78953c 100644
--- a/src/diff_print.c
+++ b/src/diff_print.c
@@ -359,9 +359,9 @@ int diff_delta_format_similarity_header(
 		abort();
 
 	if ((error = git_buf_puts(&old_path, delta->old_file.path)) < 0 ||
-		(error = git_buf_puts(&new_path, delta->new_file.path)) < 0 ||
-		(error = git_buf_quote(&old_path)) < 0 ||
-		(error = git_buf_quote(&new_path)) < 0)
+	    (error = git_buf_puts(&new_path, delta->new_file.path)) < 0 ||
+	    (error = git_buf_quote(&old_path)) < 0 ||
+	    (error = git_buf_quote(&new_path)) < 0)
 		goto done;
 
 	git_buf_printf(out,
@@ -428,8 +428,11 @@ int git_diff_delta__format_file_header(
 	git_buf_printf(out, "diff --git %s %s\n",
 		old_path.ptr, new_path.ptr);
 
+	if (unchanged && delta->old_file.mode != delta->new_file.mode)
+		diff_print_modes(out, delta);
+
 	if (delta->status == GIT_DELTA_RENAMED ||
-		(delta->status == GIT_DELTA_COPIED && unchanged)) {
+	    (delta->status == GIT_DELTA_COPIED && unchanged)) {
 		if ((error = diff_delta_format_similarity_header(out, delta)) < 0)
 			goto done;
 	}
@@ -444,9 +447,6 @@ int git_diff_delta__format_file_header(
 				"--- %s\n+++ %s\n", old_path.ptr, new_path.ptr);
 	}
 
-	if (unchanged && delta->old_file.mode != delta->new_file.mode)
-		diff_print_modes(out, delta);
-
 	if (git_buf_oom(out))
 		error = -1;
 
diff --git a/src/patch_parse.c b/src/patch_parse.c
index 9d089ad..0e251cb 100644
--- a/src/patch_parse.c
+++ b/src/patch_parse.c
@@ -411,6 +411,7 @@ static const parse_header_transition transitions[] = {
 	{ "GIT binary patch"    , STATE_INDEX,      STATE_END,        NULL },
 	{ "Binary files "       , STATE_INDEX,      STATE_END,        NULL },
 
+	{ "similarity index "   , STATE_END,        STATE_SIMILARITY, parse_header_similarity },
 	{ "similarity index "   , STATE_DIFF,       STATE_SIMILARITY, parse_header_similarity },
 	{ "dissimilarity index ", STATE_DIFF,       STATE_SIMILARITY, parse_header_dissimilarity },
 	{ "rename from "        , STATE_SIMILARITY, STATE_RENAME,     parse_header_renamefrom },
diff --git a/tests/patch/patch_common.h b/tests/patch/patch_common.h
index 7315247..1e03889 100644
--- a/tests/patch/patch_common.h
+++ b/tests/patch/patch_common.h
@@ -579,6 +579,14 @@
 	"rename from file.txt\n" \
 	"rename to newfile.txt\n"
 
+#define PATCH_RENAME_EXACT_WITH_MODE \
+	"diff --git a/RENAMED.md b/README.md\n" \
+	"old mode 100644\n" \
+	"new mode 100755\n" \
+	"similarity index 100%\n" \
+	"rename from RENAMED.md\n" \
+	"rename to README.md\n"
+
 #define PATCH_RENAME_SIMILAR \
 	"diff --git a/file.txt b/newfile.txt\n" \
 	"similarity index 77%\n" \
diff --git a/tests/patch/print.c b/tests/patch/print.c
index c4ff479..b0a9339 100644
--- a/tests/patch/print.c
+++ b/tests/patch/print.c
@@ -107,6 +107,12 @@ void test_patch_print__rename_exact(void)
 		strlen(PATCH_RENAME_EXACT));
 }
 
+void test_patch_print__rename_exact_with_mode(void)
+{
+	patch_print_from_patchfile(PATCH_RENAME_EXACT_WITH_MODE,
+		strlen(PATCH_RENAME_EXACT_WITH_MODE));
+}
+
 void test_patch_print__rename_similar(void)
 {
 	patch_print_from_patchfile(PATCH_RENAME_SIMILAR,