diff --git a/AUTHORS b/AUTHORS index f4e852357..ee55e6ad5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -70,6 +70,7 @@ Shawn O. Pearce Shuhei Tanuma Steve Frécinaux Sven Strickroth +Talya "kivikakk" Connor Tim Branyen Tim Clem Tim Harder diff --git a/src/libgit2/diff_stats.c b/src/libgit2/diff_stats.c index 259939844..b67aa48dd 100644 --- a/src/libgit2/diff_stats.c +++ b/src/libgit2/diff_stats.c @@ -28,7 +28,6 @@ struct git_diff_stats { size_t files_changed; size_t insertions; size_t deletions; - size_t renames; size_t max_name; size_t max_filestat; @@ -68,17 +67,19 @@ static int diff_file_stats_full_to_buf( size_t common_dirlen; int error; - padding = stats->max_name - strlen(old_path) - strlen(new_path); - if ((common_dirlen = git_fs_path_common_dirlen(old_path, new_path)) && common_dirlen <= INT_MAX) { error = git_str_printf(out, " %.*s{%s"DIFF_RENAME_FILE_SEPARATOR"%s}", (int) common_dirlen, old_path, old_path + common_dirlen, new_path + common_dirlen); + padding = stats->max_name + common_dirlen - strlen(old_path) + - strlen(new_path) - 2 - strlen(DIFF_RENAME_FILE_SEPARATOR); } else { error = git_str_printf(out, " %s" DIFF_RENAME_FILE_SEPARATOR "%s", old_path, new_path); + padding = stats->max_name - strlen(old_path) + - strlen(new_path) - strlen(DIFF_RENAME_FILE_SEPARATOR); } if (error < 0) @@ -89,9 +90,6 @@ static int diff_file_stats_full_to_buf( goto on_error; padding = stats->max_name - strlen(adddel_path); - - if (stats->renames > 0) - padding += strlen(DIFF_RENAME_FILE_SEPARATOR); } if (git_str_putcn(out, ' ', padding) < 0 || @@ -210,14 +208,23 @@ int git_diff_get_stats( if ((error = git_patch_from_diff(&patch, diff, i)) < 0) break; - /* keep a count of renames because it will affect formatting */ + /* Length calculation for renames mirrors the actual presentation format + * generated in diff_file_stats_full_to_buf; namelen is the full length of + * what will be printed, taking into account renames and common prefixes. + */ delta = patch->delta; - - /* TODO ugh */ namelen = strlen(delta->new_file.path); - if (delta->old_file.path && strcmp(delta->old_file.path, delta->new_file.path) != 0) { - namelen += strlen(delta->old_file.path); - stats->renames++; + if (delta->old_file.path && + strcmp(delta->old_file.path, delta->new_file.path) != 0) { + size_t common_dirlen; + if ((common_dirlen = git_fs_path_common_dirlen(delta->old_file.path, delta->new_file.path)) && + common_dirlen <= INT_MAX) { + namelen += strlen(delta->old_file.path) + 2 + + strlen(DIFF_RENAME_FILE_SEPARATOR) - common_dirlen; + } else { + namelen += strlen(delta->old_file.path) + + strlen(DIFF_RENAME_FILE_SEPARATOR); + } } /* and, of course, count the line stats */ diff --git a/tests/libgit2/diff/stats.c b/tests/libgit2/diff/stats.c index f80813622..5a51aac78 100644 --- a/tests/libgit2/diff/stats.c +++ b/tests/libgit2/diff/stats.c @@ -229,6 +229,26 @@ void test_diff_stats__rename_in_subdirectory(void) git_buf_dispose(&buf); } +void test_diff_stats__rename_in_subdirectory_aligns(void) +{ + git_buf buf = GIT_BUF_INIT; + const char *stat = + " dir/{renamed.txt => rerenamed.txt} | 0\n" + " file3.txt | 2 +-\n" + " 2 files changed, 1 insertion(+), 1 deletion(-)\n"; + + diff_stats_from_commit_oid( + &_stats, "7f4c6d9d6ba363e3352f7c21807ca3a7835072b2", true); + + cl_assert_equal_sz(2, git_diff_stats_files_changed(_stats)); + cl_assert_equal_sz(1, git_diff_stats_insertions(_stats)); + cl_assert_equal_sz(1, git_diff_stats_deletions(_stats)); + + cl_git_pass(git_diff_stats_to_buf(&buf, _stats, GIT_DIFF_STATS_FULL, 0)); + cl_assert_equal_s(stat, buf.ptr); + git_buf_dispose(&buf); +} + void test_diff_stats__rename_no_find(void) { git_buf buf = GIT_BUF_INIT; diff --git a/tests/resources/diff_format_email/.gitted/index b/tests/resources/diff_format_email/.gitted/index index 4514a6b9c..7053c2159 100644 Binary files a/tests/resources/diff_format_email/.gitted/index and b/tests/resources/diff_format_email/.gitted/index differ diff --git a/tests/resources/diff_format_email/.gitted/objects/7f/4c6d9d6ba363e3352f7c21807ca3a7835072b2 b/tests/resources/diff_format_email/.gitted/objects/7f/4c6d9d6ba363e3352f7c21807ca3a7835072b2 new file mode 100644 index 000000000..1be0e7927 --- /dev/null +++ b/tests/resources/diff_format_email/.gitted/objects/7f/4c6d9d6ba363e3352f7c21807ca3a7835072b2 @@ -0,0 +1 @@ +xKj1EьLZ[JǢR@v