mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-09 16:45:49 +00:00
Split rewrites, status doesn't return rewrites
Ensure that we apply splits to rewrites, even if we're not interested in examining it closely for rename/copy detection. In keeping with core git, status should not display rewrites, it should simply show files as "modified".
This commit is contained in:
parent
1ef05e3f0e
commit
17c7fbf6d2
@ -454,6 +454,9 @@ typedef enum {
|
||||
GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE = (1 << 13),
|
||||
/** measure similarity only by comparing SHAs (fast and cheap) */
|
||||
GIT_DIFF_FIND_EXACT_MATCH_ONLY = (1 << 14),
|
||||
|
||||
/** do not break rewrites unless they contribute to a rename */
|
||||
GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY = (1 << 15),
|
||||
} git_diff_find_t;
|
||||
|
||||
/**
|
||||
|
@ -799,6 +799,9 @@ int git_diff_find_similar(
|
||||
|
||||
if (is_rename_target(diff, &opts, t, sigcache))
|
||||
++num_tgts;
|
||||
|
||||
if ((tgt->flags & GIT_DIFF_FLAG__TO_SPLIT) != 0)
|
||||
num_rewrites++;
|
||||
}
|
||||
|
||||
/* if there are no candidate srcs or tgts, we're done */
|
||||
@ -1036,7 +1039,8 @@ find_best_matches:
|
||||
if (num_rewrites > 0 || num_updates > 0)
|
||||
error = apply_splits_and_deletes(
|
||||
diff, diff->deltas.length - num_rewrites,
|
||||
FLAG_SET(&opts, GIT_DIFF_BREAK_REWRITES));
|
||||
FLAG_SET(&opts, GIT_DIFF_BREAK_REWRITES) &&
|
||||
!FLAG_SET(&opts, GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY));
|
||||
|
||||
cleanup:
|
||||
git__free(tgt2src);
|
||||
|
@ -284,8 +284,10 @@ int git_status_list_new(
|
||||
diffopt.flags = diffopt.flags | GIT_DIFF_IGNORE_SUBMODULES;
|
||||
|
||||
if ((flags & GIT_STATUS_OPT_RENAMES_FROM_REWRITES) != 0)
|
||||
findopt.flags = findopt.flags | GIT_DIFF_FIND_AND_BREAK_REWRITES |
|
||||
GIT_DIFF_FIND_RENAMES_FROM_REWRITES;
|
||||
findopt.flags = findopt.flags |
|
||||
GIT_DIFF_FIND_AND_BREAK_REWRITES |
|
||||
GIT_DIFF_FIND_RENAMES_FROM_REWRITES |
|
||||
GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY;
|
||||
|
||||
if (show != GIT_STATUS_SHOW_WORKDIR_ONLY) {
|
||||
if ((error = git_diff_tree_to_index(
|
||||
|
@ -1235,3 +1235,52 @@ void test_diff_rename__unmodified_can_be_renamed(void)
|
||||
git_index_free(index);
|
||||
git_tree_free(tree);
|
||||
}
|
||||
|
||||
void test_diff_rename__rewrite_on_single_file(void)
|
||||
{
|
||||
git_index *index;
|
||||
git_diff_list *diff = NULL;
|
||||
diff_expects exp;
|
||||
git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
|
||||
git_diff_find_options findopts = GIT_DIFF_FIND_OPTIONS_INIT;
|
||||
|
||||
diffopts.flags = GIT_DIFF_INCLUDE_UNTRACKED;
|
||||
|
||||
findopts.flags = GIT_DIFF_FIND_FOR_UNTRACKED |
|
||||
GIT_DIFF_FIND_AND_BREAK_REWRITES |
|
||||
GIT_DIFF_FIND_RENAMES_FROM_REWRITES;
|
||||
|
||||
cl_git_pass(git_repository_index(&index, g_repo));
|
||||
|
||||
cl_git_rewritefile("renames/ikeepsix.txt",
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n");
|
||||
|
||||
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, &diffopts));
|
||||
cl_git_pass(git_diff_find_similar(diff, &findopts));
|
||||
|
||||
memset(&exp, 0, sizeof(exp));
|
||||
|
||||
cl_git_pass(git_diff_foreach(
|
||||
diff, diff_file_cb, diff_hunk_cb, diff_line_cb, &exp));
|
||||
cl_assert_equal_i(2, exp.files);
|
||||
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
|
||||
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNTRACKED]);
|
||||
|
||||
git_diff_list_free(diff);
|
||||
git_index_free(index);
|
||||
}
|
||||
|
@ -403,6 +403,47 @@ void test_status_renames__both_rename_from_rewrite(void)
|
||||
git_index_free(index);
|
||||
}
|
||||
|
||||
void test_status_renames__rewrites_only_for_renames(void)
|
||||
{
|
||||
git_index *index;
|
||||
git_status_list *statuslist;
|
||||
git_status_options opts = GIT_STATUS_OPTIONS_INIT;
|
||||
struct status_entry expected[] = {
|
||||
{ GIT_STATUS_WT_MODIFIED, "ikeepsix.txt", "ikeepsix.txt" },
|
||||
};
|
||||
|
||||
opts.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED;
|
||||
opts.flags |= GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX;
|
||||
opts.flags |= GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR;
|
||||
opts.flags |= GIT_STATUS_OPT_RENAMES_FROM_REWRITES;
|
||||
|
||||
cl_git_pass(git_repository_index(&index, g_repo));
|
||||
|
||||
cl_git_rewritefile("renames/ikeepsix.txt",
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n" \
|
||||
"This is enough content for the file to be rewritten.\n");
|
||||
|
||||
cl_git_pass(git_status_list_new(&statuslist, g_repo, &opts));
|
||||
test_status(statuslist, expected, 1);
|
||||
git_status_list_free(statuslist);
|
||||
|
||||
git_index_free(index);
|
||||
}
|
||||
|
||||
void test_status_renames__both_casechange_one(void)
|
||||
{
|
||||
git_index *index;
|
||||
|
Loading…
Reference in New Issue
Block a user