Commit aa5994b0 by Yori

diff: fix removal of unmodified deltas

When finding similar deltas, count the targets that are tagged to be deleted.
Apply deletions even in the absense of rewrites or updates.
parent 4939fa74
......@@ -810,7 +810,7 @@ int git_diff_find_similar(
git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
size_t num_deltas, num_srcs = 0, num_tgts = 0;
size_t tried_srcs = 0, tried_tgts = 0;
size_t num_rewrites = 0, num_updates = 0, num_bumped = 0;
size_t num_rewrites = 0, num_updates = 0, num_bumped = 0, num_to_delete = 0;
size_t sigcache_size;
void **sigcache = NULL; /* cache of similarity metric file signatures */
diff_find_match *tgt2src = NULL;
......@@ -852,11 +852,14 @@ int git_diff_find_similar(
if ((tgt->flags & GIT_DIFF_FLAG__TO_SPLIT) != 0)
num_rewrites++;
if ((tgt->flags & GIT_DIFF_FLAG__TO_DELETE) != 0)
num_to_delete++;
}
/* if there are no candidate srcs or tgts, we're done */
/* If there are no candidate srcs or tgts, no need to find matches */
if (!num_srcs || !num_tgts)
goto cleanup;
goto split_and_delete;
src2tgt = git__calloc(num_deltas, sizeof(diff_find_match));
GIT_ERROR_CHECK_ALLOC(src2tgt);
......@@ -1093,13 +1096,14 @@ find_best_matches:
}
}
split_and_delete:
/*
* Actually split and delete entries as needed
*/
if (num_rewrites > 0 || num_updates > 0)
if (num_rewrites > 0 || num_updates > 0 || num_to_delete > 0)
error = apply_splits_and_deletes(
diff, diff->deltas.length - num_rewrites,
diff, diff->deltas.length - num_rewrites - num_to_delete,
FLAG_SET(&opts, GIT_DIFF_BREAK_REWRITES) &&
!FLAG_SET(&opts, GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY));
......
......@@ -1441,6 +1441,47 @@ void test_diff_rename__can_delete_unmodified_deltas(void)
git_str_dispose(&c1);
}
void test_diff_rename__can_delete_unmodified_deltas_without_changes(void)
{
git_str c1 = GIT_STR_INIT;
git_index *index;
git_tree *tree;
git_diff *diff;
git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
diff_expects exp;
cl_git_pass(
git_revparse_single((git_object **)&tree, g_repo, "HEAD^{tree}"));
cl_git_pass(git_repository_index(&index, g_repo));
cl_git_pass(git_index_read_tree(index, tree));
diffopts.flags = GIT_DIFF_INCLUDE_UNMODIFIED;
cl_git_pass(git_diff_tree_to_index(&diff, g_repo, tree, index, &diffopts));
memset(&exp, 0, sizeof(exp));
cl_git_pass(git_diff_foreach(
diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
cl_assert_equal_i(4, exp.files);
cl_assert_equal_i(4, exp.file_status[GIT_DELTA_UNMODIFIED]);
opts.flags = GIT_DIFF_FIND_ALL | GIT_DIFF_FIND_REMOVE_UNMODIFIED;
cl_git_pass(git_diff_find_similar(diff, &opts));
memset(&exp, 0, sizeof(exp));
cl_git_pass(git_diff_foreach(
diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &exp));
cl_assert_equal_i(0, exp.files);
git_diff_free(diff);
git_tree_free(tree);
git_index_free(index);
git_str_dispose(&c1);
}
void test_diff_rename__matches_config_behavior(void)
{
const char *sha0 = INITIAL_COMMIT;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment