mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-12 01:15:09 +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),
|
GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE = (1 << 13),
|
||||||
/** measure similarity only by comparing SHAs (fast and cheap) */
|
/** measure similarity only by comparing SHAs (fast and cheap) */
|
||||||
GIT_DIFF_FIND_EXACT_MATCH_ONLY = (1 << 14),
|
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;
|
} git_diff_find_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -799,6 +799,9 @@ int git_diff_find_similar(
|
|||||||
|
|
||||||
if (is_rename_target(diff, &opts, t, sigcache))
|
if (is_rename_target(diff, &opts, t, sigcache))
|
||||||
++num_tgts;
|
++num_tgts;
|
||||||
|
|
||||||
|
if ((tgt->flags & GIT_DIFF_FLAG__TO_SPLIT) != 0)
|
||||||
|
num_rewrites++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if there are no candidate srcs or tgts, we're done */
|
/* 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)
|
if (num_rewrites > 0 || num_updates > 0)
|
||||||
error = apply_splits_and_deletes(
|
error = apply_splits_and_deletes(
|
||||||
diff, diff->deltas.length - num_rewrites,
|
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:
|
cleanup:
|
||||||
git__free(tgt2src);
|
git__free(tgt2src);
|
||||||
|
@ -284,8 +284,10 @@ int git_status_list_new(
|
|||||||
diffopt.flags = diffopt.flags | GIT_DIFF_IGNORE_SUBMODULES;
|
diffopt.flags = diffopt.flags | GIT_DIFF_IGNORE_SUBMODULES;
|
||||||
|
|
||||||
if ((flags & GIT_STATUS_OPT_RENAMES_FROM_REWRITES) != 0)
|
if ((flags & GIT_STATUS_OPT_RENAMES_FROM_REWRITES) != 0)
|
||||||
findopt.flags = findopt.flags | GIT_DIFF_FIND_AND_BREAK_REWRITES |
|
findopt.flags = findopt.flags |
|
||||||
GIT_DIFF_FIND_RENAMES_FROM_REWRITES;
|
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 (show != GIT_STATUS_SHOW_WORKDIR_ONLY) {
|
||||||
if ((error = git_diff_tree_to_index(
|
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_index_free(index);
|
||||||
git_tree_free(tree);
|
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);
|
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)
|
void test_status_renames__both_casechange_one(void)
|
||||||
{
|
{
|
||||||
git_index *index;
|
git_index *index;
|
||||||
|
Loading…
Reference in New Issue
Block a user