Commit 32def5af by Russell Belfer

Fix checkout behavior when its hands are tied

So, @nulltoken created a failing test case for checkout that
proved to be particularly daunting.  If checkout is given only
a very limited strategy mask (e.g. just GIT_CHECKOUT_CREATE_MISSING)
then it is possible for typechange/rename modifications to leave it
unable to complete the request.  That's okay, but the existing code
did not have enough information not to generate an error (at least
for tree/blob conflicts).

This led me to a significant reorganization of the code to handle
the failing case, but it has three benefits:

1. The test case is handled correctly (I think)
2. The new code should actually be much faster than the old code
   since I decided to make checkout aware of diff list internals.
3. The progress value accuracy is hugely increased since I added
   a fourth pass which calculates exactly what work needs to be
   done before doing anything.
parent 331e7de9
...@@ -377,3 +377,34 @@ void test_checkout_index__calls_progress_callback(void) ...@@ -377,3 +377,34 @@ void test_checkout_index__calls_progress_callback(void)
cl_git_pass(git_checkout_index(g_repo, &g_opts)); cl_git_pass(git_checkout_index(g_repo, &g_opts));
cl_assert_equal_i(was_called, true); cl_assert_equal_i(was_called, true);
} }
void test_checkout_index__can_overcome_name_clashes(void)
{
git_index *index;
cl_git_pass(git_repository_index(&index, g_repo));
git_index_clear(index);
cl_git_mkfile("./testrepo/path0", "content\r\n");
cl_git_pass(p_mkdir("./testrepo/path1", 0777));
cl_git_mkfile("./testrepo/path1/file1", "content\r\n");
cl_git_pass(git_index_add(index, "path0", 0));
cl_git_pass(git_index_add(index, "path1/file1", 0));
cl_git_pass(p_unlink("./testrepo/path0"));
cl_git_pass(git_futils_rmdir_r(
"./testrepo/path1", NULL, GIT_RMDIR_REMOVE_FILES));
cl_git_mkfile("./testrepo/path1", "content\r\n");
cl_git_pass(p_mkdir("./testrepo/path0", 0777));
cl_git_mkfile("./testrepo/path0/file0", "content\r\n");
g_opts.checkout_strategy = GIT_CHECKOUT_CREATE_MISSING;
cl_git_pass(git_checkout_index(g_repo, &g_opts));
cl_assert(git_path_isfile("./testrepo/path1"));
cl_assert(git_path_isfile("./testrepo/path0/file0"));
git_index_free(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