Commit e5090ee329aecdc2a298e442868cbf1d4b10d0e9

Patrick Steinhardt 2018-10-04T11:19:28

diff_stats: use git's formatting of renames with common directories In cases where a file gets renamed such that the directories containing it previous and after the rename have a common prefix, then git will avoid printing this prefix twice and instead format the rename as "prefix/{old => new}". We currently didn't do anything like that, but simply printed "prefix/old -> prefix/new". Adjust our behaviour to instead match upstream. Adjust the test for this behaviour to expect the new format.

diff --git a/src/diff_stats.c b/src/diff_stats.c
index 583c684..3af5914 100644
--- a/src/diff_stats.c
+++ b/src/diff_stats.c
@@ -61,15 +61,29 @@ int git_diff_file_stats__full_to_buf(
 	old_size = delta->old_file.size;
 	new_size = delta->new_file.size;
 
-	if (git_buf_printf(out, " %s", old_path) < 0)
-		goto on_error;
-
 	if (strcmp(old_path, new_path) != 0) {
+		size_t common_dirlen;
+		int error;
+
 		padding = stats->max_name - strlen(old_path) - strlen(new_path);
 
-		if (git_buf_printf(out, DIFF_RENAME_FILE_SEPARATOR "%s", new_path) < 0)
+		if ((common_dirlen = git_path_common_dirlen(old_path, new_path)) &&
+		    common_dirlen <= INT_MAX) {
+			error = git_buf_printf(out, " %.*s{%s"DIFF_RENAME_FILE_SEPARATOR"%s}",
+					       (int) common_dirlen, old_path,
+					       old_path + common_dirlen,
+					       new_path + common_dirlen);
+		} else {
+			error = git_buf_printf(out, " %s" DIFF_RENAME_FILE_SEPARATOR "%s",
+					       old_path, new_path);
+		}
+
+		if (error < 0)
 			goto on_error;
 	} else {
+		if (git_buf_printf(out, " %s", old_path) < 0)
+			goto on_error;
+
 		padding = stats->max_name - strlen(old_path);
 
 		if (stats->renames > 0)
diff --git a/tests/diff/stats.c b/tests/diff/stats.c
index 1149b50..1503556 100644
--- a/tests/diff/stats.c
+++ b/tests/diff/stats.c
@@ -214,7 +214,7 @@ void test_diff_stats__rename_in_subdirectory(void)
 {
 	git_buf buf = GIT_BUF_INIT;
 	const char *stat =
-	" dir/orig.txt => dir/renamed.txt | 0\n"
+	" dir/{orig.txt => renamed.txt} | 0\n"
 	" 1 file changed, 0 insertions(+), 0 deletions(-)\n";
 
 	diff_stats_from_commit_oid(