Commit 17c7fbf6 by Edward Thomson

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".
parent 1ef05e3f
...@@ -454,6 +454,9 @@ typedef enum { ...@@ -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( ...@@ -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: ...@@ -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( ...@@ -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) ...@@ -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) ...@@ -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;
......
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