Commit 5e26391a by Edward Thomson

checkout: FORCE doesn't halt on dirty index

If the index is dirty, allow `GIT_CHECKOUT_FORCE` to obliterate unsaved
changes.  This is in keeping with its name and description.
parent b242cdbf
...@@ -2412,16 +2412,25 @@ static int checkout_data_init( ...@@ -2412,16 +2412,25 @@ static int checkout_data_init(
* and those should not be overwritten.) * and those should not be overwritten.)
*/ */
if (data->index != git_iterator_index(target)) { if (data->index != git_iterator_index(target)) {
if ((error = git_index_read_safely(data->index)) < 0) if (data->opts.checkout_strategy & GIT_CHECKOUT_FORCE) {
goto cleanup; /* When forcing, we can blindly re-read the index */
if ((error = git_index_read(data->index, false)) < 0)
/* cannot checkout if unresolved conflicts exist */ goto cleanup;
if ((data->opts.checkout_strategy & GIT_CHECKOUT_FORCE) == 0 && } else {
git_index_has_conflicts(data->index)) { /*
error = GIT_ECONFLICT; * When not being forced, we need to check for unresolved
giterr_set(GITERR_CHECKOUT, * conflicts and unsaved changes in the index before
"unresolved conflicts exist in the index"); * proceeding.
goto cleanup; */
if (git_index_has_conflicts(data->index)) {
error = GIT_ECONFLICT;
giterr_set(GITERR_CHECKOUT,
"unresolved conflicts exist in the index");
goto cleanup;
}
if ((error = git_index_read_safely(data->index)) < 0)
goto cleanup;
} }
/* clean conflict data in the current index */ /* clean conflict data in the current index */
......
...@@ -672,12 +672,9 @@ void test_checkout_tree__can_cancel_checkout_from_notify(void) ...@@ -672,12 +672,9 @@ void test_checkout_tree__can_cancel_checkout_from_notify(void)
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
git_oid oid; git_oid oid;
git_object *obj = NULL; git_object *obj = NULL;
git_index *index = NULL;
assert_on_branch(g_repo, "master"); assert_on_branch(g_repo, "master");
cl_git_pass(git_repository_index(&index, g_repo));
cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir")); cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir"));
cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY)); cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
...@@ -704,8 +701,6 @@ void test_checkout_tree__can_cancel_checkout_from_notify(void) ...@@ -704,8 +701,6 @@ void test_checkout_tree__can_cancel_checkout_from_notify(void)
else else
cl_assert_equal_i(4, ca.count); cl_assert_equal_i(4, ca.count);
cl_git_pass(git_index_read(index, 1));
/* and again with a different stopping point and return code */ /* and again with a different stopping point and return code */
ca.filename = "README"; ca.filename = "README";
ca.error = 123; ca.error = 123;
...@@ -721,7 +716,6 @@ void test_checkout_tree__can_cancel_checkout_from_notify(void) ...@@ -721,7 +716,6 @@ void test_checkout_tree__can_cancel_checkout_from_notify(void)
cl_assert_equal_i(1, ca.count); cl_assert_equal_i(1, ca.count);
git_object_free(obj); git_object_free(obj);
git_index_free(index);
} }
void test_checkout_tree__can_checkout_with_last_workdir_item_missing(void) void test_checkout_tree__can_checkout_with_last_workdir_item_missing(void)
...@@ -1502,11 +1496,9 @@ void test_checkout_tree__baseline_is_empty_when_no_index(void) ...@@ -1502,11 +1496,9 @@ void test_checkout_tree__baseline_is_empty_when_no_index(void)
git_reference *head; git_reference *head;
git_object *obj; git_object *obj;
size_t conflicts = 0; size_t conflicts = 0;
git_index *index;
assert_on_branch(g_repo, "master"); assert_on_branch(g_repo, "master");
cl_git_pass(git_repository_index(&index, g_repo));
cl_git_pass(git_repository_head(&head, g_repo)); cl_git_pass(git_repository_head(&head, g_repo));
cl_git_pass(git_reference_peel(&obj, head, GIT_OBJ_COMMIT)); cl_git_pass(git_reference_peel(&obj, head, GIT_OBJ_COMMIT));
...@@ -1525,8 +1517,6 @@ void test_checkout_tree__baseline_is_empty_when_no_index(void) ...@@ -1525,8 +1517,6 @@ void test_checkout_tree__baseline_is_empty_when_no_index(void)
cl_git_fail_with(GIT_ECONFLICT, git_checkout_tree(g_repo, obj, &opts)); cl_git_fail_with(GIT_ECONFLICT, git_checkout_tree(g_repo, obj, &opts));
cl_assert_equal_i(4, conflicts); cl_assert_equal_i(4, conflicts);
cl_git_pass(git_index_read(index, 1));
/* but force should succeed and update the index */ /* but force should succeed and update the index */
opts.checkout_strategy |= GIT_CHECKOUT_FORCE; opts.checkout_strategy |= GIT_CHECKOUT_FORCE;
cl_git_pass(git_checkout_tree(g_repo, obj, &opts)); cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
...@@ -1535,7 +1525,6 @@ void test_checkout_tree__baseline_is_empty_when_no_index(void) ...@@ -1535,7 +1525,6 @@ void test_checkout_tree__baseline_is_empty_when_no_index(void)
git_object_free(obj); git_object_free(obj);
git_reference_free(head); git_reference_free(head);
git_index_free(index);
} }
void test_checkout_tree__mode_change_is_force_updated(void) void test_checkout_tree__mode_change_is_force_updated(void)
......
...@@ -259,7 +259,6 @@ static int make_submodule_dirty(git_submodule *sm, const char *name, void *paylo ...@@ -259,7 +259,6 @@ static int make_submodule_dirty(git_submodule *sm, const char *name, void *paylo
void test_checkout_typechange__checkout_with_conflicts(void) void test_checkout_typechange__checkout_with_conflicts(void)
{ {
int i; int i;
git_index *index;
git_object *obj; git_object *obj;
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
notify_counts cts = {0}; notify_counts cts = {0};
...@@ -290,10 +289,6 @@ void test_checkout_typechange__checkout_with_conflicts(void) ...@@ -290,10 +289,6 @@ void test_checkout_typechange__checkout_with_conflicts(void)
cl_assert_equal_i(cts.updates, 0); cl_assert_equal_i(cts.updates, 0);
cl_assert_equal_i(cts.ignored, 0); cl_assert_equal_i(cts.ignored, 0);
cl_git_pass(git_repository_index(&index, g_repo));
cl_git_pass(git_index_read(index, 1));
git_index_free(index);
opts.checkout_strategy = opts.checkout_strategy =
GIT_CHECKOUT_FORCE | GIT_CHECKOUT_REMOVE_UNTRACKED; GIT_CHECKOUT_FORCE | GIT_CHECKOUT_REMOVE_UNTRACKED;
memset(&cts, 0, sizeof(cts)); memset(&cts, 0, sizeof(cts));
......
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