diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2018-06-18 18:28:08 +0100 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2018-06-29 14:54:28 +0100 |
commit | 5e26391a2579062bdf5d6f0efe6b03f78d28f825 (patch) | |
tree | ab30a11f3fb10025e7eb8e199280488f1ea4aa7b | |
parent | b242cdbf1e1dd2cc9e26e0085a20230ff34d156b (diff) | |
download | libgit2-5e26391a2579062bdf5d6f0efe6b03f78d28f825.tar.gz |
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.
-rw-r--r-- | src/checkout.c | 29 | ||||
-rw-r--r-- | tests/checkout/tree.c | 11 | ||||
-rw-r--r-- | tests/checkout/typechange.c | 5 |
3 files changed, 19 insertions, 26 deletions
diff --git a/src/checkout.c b/src/checkout.c index d72f227de..2a4e5c4a5 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -2412,16 +2412,25 @@ static int checkout_data_init( * and those should not be overwritten.) */ if (data->index != git_iterator_index(target)) { - if ((error = git_index_read_safely(data->index)) < 0) - goto cleanup; - - /* cannot checkout if unresolved conflicts exist */ - if ((data->opts.checkout_strategy & GIT_CHECKOUT_FORCE) == 0 && - git_index_has_conflicts(data->index)) { - error = GIT_ECONFLICT; - giterr_set(GITERR_CHECKOUT, - "unresolved conflicts exist in the index"); - goto cleanup; + if (data->opts.checkout_strategy & GIT_CHECKOUT_FORCE) { + /* When forcing, we can blindly re-read the index */ + if ((error = git_index_read(data->index, false)) < 0) + goto cleanup; + } else { + /* + * When not being forced, we need to check for unresolved + * conflicts and unsaved changes in the index before + * proceeding. + */ + 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 */ diff --git a/tests/checkout/tree.c b/tests/checkout/tree.c index 97a2fb4b7..a78bf82df 100644 --- a/tests/checkout/tree.c +++ b/tests/checkout/tree.c @@ -672,12 +672,9 @@ void test_checkout_tree__can_cancel_checkout_from_notify(void) git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; git_oid oid; git_object *obj = NULL; - git_index *index = NULL; 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_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY)); @@ -704,8 +701,6 @@ void test_checkout_tree__can_cancel_checkout_from_notify(void) else 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 */ ca.filename = "README"; ca.error = 123; @@ -721,7 +716,6 @@ void test_checkout_tree__can_cancel_checkout_from_notify(void) cl_assert_equal_i(1, ca.count); git_object_free(obj); - git_index_free(index); } 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) git_reference *head; git_object *obj; size_t conflicts = 0; - git_index *index; 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_reference_peel(&obj, head, GIT_OBJ_COMMIT)); @@ -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_assert_equal_i(4, conflicts); - cl_git_pass(git_index_read(index, 1)); - /* but force should succeed and update the index */ opts.checkout_strategy |= GIT_CHECKOUT_FORCE; 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) git_object_free(obj); git_reference_free(head); - git_index_free(index); } void test_checkout_tree__mode_change_is_force_updated(void) diff --git a/tests/checkout/typechange.c b/tests/checkout/typechange.c index 5cd95081b..7299f8d33 100644 --- a/tests/checkout/typechange.c +++ b/tests/checkout/typechange.c @@ -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) { int i; - git_index *index; git_object *obj; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; notify_counts cts = {0}; @@ -290,10 +289,6 @@ void test_checkout_typechange__checkout_with_conflicts(void) cl_assert_equal_i(cts.updates, 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 = GIT_CHECKOUT_FORCE | GIT_CHECKOUT_REMOVE_UNTRACKED; memset(&cts, 0, sizeof(cts)); |