Skip to content

Commit

Permalink
index: commit the changes to the index properly
Browse files Browse the repository at this point in the history
Now that the index has a "dirty" state, where it has changes that have
not yet been committed or rolled back, our tests need to be adapted to
actually commit or rollback the changes instead of assuming that the
index can be operated on in its indeterminate state.
  • Loading branch information
ethomson committed Feb 19, 2018
1 parent 2bd462e commit a07ddf9
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -2408,7 +2408,7 @@ static int checkout_data_init(
* and those should not be overwritten.)
*/
if (data->index != git_iterator_index(target)) {
if ((error = git_index_read(data->index, true)) < 0)
if ((error = git_index_read_safely(data->index)) < 0)
goto cleanup;

/* cannot checkout if unresolved conflicts exist */
Expand Down
12 changes: 12 additions & 0 deletions src/index.c
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,17 @@ int git_index_read(git_index *index, int force)
return error;
}

int git_index_read_safely(git_index *index)
{
if (index->dirty) {
giterr_set(GITERR_INDEX,
"the index has unsaved changes that would be overwritten by this operation");
return -1;
}

return git_index_read(index, false);
}

int git_index__changed_relative_to(
git_index *index, const git_oid *checksum)
{
Expand Down Expand Up @@ -3596,6 +3607,7 @@ int git_indexwriter_commit(git_indexwriter *writer)
return -1;
}

writer->index->dirty = 0;
writer->index->on_disk = 1;
git_oid_cpy(&writer->index->checksum, &checksum);

Expand Down
2 changes: 2 additions & 0 deletions src/index.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ GIT_INLINE(int) git_index_is_dirty(git_index *index)
return index->dirty;
}

extern int git_index_read_safely(git_index *index);

typedef struct {
git_index *index;
git_filebuf file;
Expand Down
2 changes: 1 addition & 1 deletion src/status.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ int git_status_list_new(

/* refresh index from disk unless prevented */
if ((flags & GIT_STATUS_OPT_NO_REFRESH) == 0 &&
git_index_read(index, false) < 0)
git_index_read_safely(index) < 0)
giterr_clear();

status = git_status_list_alloc(index);
Expand Down
23 changes: 21 additions & 2 deletions tests/checkout/tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,7 @@ void assert_conflict(
*/
cl_git_pass(git_object_peel(&hack_tree, g_object, GIT_OBJ_TREE));
cl_git_pass(git_index_read_tree(index, (git_tree *)hack_tree));
cl_git_pass(git_index_write(index));
git_object_free(hack_tree);
git_object_free(g_object);
g_object = NULL;
Expand Down Expand Up @@ -671,9 +672,12 @@ 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));

Expand All @@ -700,6 +704,8 @@ 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;
Expand All @@ -715,6 +721,7 @@ 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)
Expand All @@ -739,7 +746,9 @@ void test_checkout_tree__can_checkout_with_last_workdir_item_missing(void)
cl_git_mkfile("./testrepo/this-is-dir/contained_file", "content\n");

cl_git_pass(git_index_add_bypath(index, "this-is-dir/contained_file"));
git_index_write_tree(&tree_id, index);
cl_git_pass(git_index_write(index));

cl_git_pass(git_index_write_tree(&tree_id, index));
cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));

cl_git_pass(p_unlink("./testrepo/this-is-dir/contained_file"));
Expand Down Expand Up @@ -1493,8 +1502,11 @@ 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));

Expand All @@ -1513,6 +1525,8 @@ 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));
Expand All @@ -1521,6 +1535,7 @@ 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)
Expand Down Expand Up @@ -1551,8 +1566,12 @@ void test_checkout_tree__mode_change_is_force_updated(void)
cl_must_pass(p_chmod("testrepo/README", 0755));
cl_must_pass(git_index_add_bypath(index, "README"));

cl_git_pass(git_index_write(index));
assert_status_entrycount(g_repo, 1);
cl_git_pass(git_checkout_tree(g_repo, obj, &g_opts));

cl_git_pass(git_reset(g_repo, obj, GIT_RESET_HARD, NULL));
cl_git_pass(git_index_write(index));

assert_status_entrycount(g_repo, 0);

git_object_free(obj);
Expand Down
5 changes: 5 additions & 0 deletions tests/checkout/typechange.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ 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};
Expand Down Expand Up @@ -288,6 +289,10 @@ 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));
Expand Down
1 change: 1 addition & 0 deletions tests/cherrypick/workdir.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ void test_cherrypick_workdir__conflict_use_ours(void)
opts.merge_opts.file_favor = GIT_MERGE_FILE_FAVOR_OURS;

cl_git_pass(git_reset(repo, (git_object *)head, GIT_RESET_HARD, NULL));

cl_git_pass(git_cherrypick(repo, commit, &opts));

cl_assert(merge_test_index(repo_index, merge_filesystem_entries, 3));
Expand Down
19 changes: 11 additions & 8 deletions tests/index/names.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ void test_index_names__add(void)
{
const git_index_name_entry *conflict_name;

index_add_main();
cl_git_pass(git_index_name_add(repo_index, "ancestor", "ours", "theirs"));
cl_git_pass(git_index_name_add(repo_index, "ancestor2", "ours2", NULL));
cl_git_pass(git_index_name_add(repo_index, "ancestor3", NULL, "theirs3"));
Expand All @@ -85,6 +86,8 @@ void test_index_names__add(void)
cl_assert(strcmp(conflict_name->ancestor, "ancestor3") == 0);
cl_assert(conflict_name->ours == NULL);
cl_assert(strcmp(conflict_name->theirs, "theirs3") == 0);

cl_git_pass(git_index_write(repo_index));
}

void test_index_names__roundtrip(void)
Expand Down Expand Up @@ -150,12 +153,12 @@ void test_index_names__cleaned_on_checkout_tree(void)
git_object *obj;
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;

opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_ONLY;
opts.checkout_strategy = GIT_CHECKOUT_FORCE | GIT_CHECKOUT_UPDATE_ONLY;

test_index_names__add();
git_reference_name_to_id(&oid, repo, "refs/heads/master");
git_object_lookup(&obj, repo, &oid, GIT_OBJ_ANY);
git_checkout_tree(repo, obj, &opts);
cl_git_pass(git_reference_name_to_id(&oid, repo, "refs/heads/master"));
cl_git_pass(git_object_lookup(&obj, repo, &oid, GIT_OBJ_ANY));
cl_git_pass(git_checkout_tree(repo, obj, &opts));
cl_assert_equal_sz(0, git_index_name_entrycount(repo_index));

git_object_free(obj);
Expand All @@ -165,20 +168,20 @@ void test_index_names__cleaned_on_checkout_head(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;

opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_ONLY;
opts.checkout_strategy = GIT_CHECKOUT_FORCE | GIT_CHECKOUT_UPDATE_ONLY;

test_index_names__add();
git_checkout_head(repo, &opts);
cl_git_pass(git_checkout_head(repo, &opts));
cl_assert_equal_sz(0, git_index_name_entrycount(repo_index));
}

void test_index_names__retained_on_checkout_index(void)
{
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;

opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_ONLY;
opts.checkout_strategy = GIT_CHECKOUT_FORCE | GIT_CHECKOUT_UPDATE_ONLY;

test_index_names__add();
git_checkout_index(repo, repo_index, &opts);
cl_git_pass(git_checkout_index(repo, repo_index, &opts));
cl_assert(git_index_name_entrycount(repo_index) > 0);
}
4 changes: 4 additions & 0 deletions tests/index/reuc.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ void test_index_reuc__add(void)
cl_assert_equal_oid(&reuc->oid[0], &ancestor_oid);
cl_assert_equal_oid(&reuc->oid[1], &our_oid);
cl_assert_equal_oid(&reuc->oid[2], &their_oid);

cl_git_pass(git_index_write(repo_index));
}

void test_index_reuc__add_no_ancestor(void)
Expand All @@ -81,6 +83,8 @@ void test_index_reuc__add_no_ancestor(void)
cl_assert_equal_oid(&reuc->oid[0], &ancestor_oid);
cl_assert_equal_oid(&reuc->oid[1], &our_oid);
cl_assert_equal_oid(&reuc->oid[2], &their_oid);

cl_git_pass(git_index_write(repo_index));
}

void test_index_reuc__read_bypath(void)
Expand Down
3 changes: 2 additions & 1 deletion tests/rebase/submodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ void test_rebase_submodule__initialize(void)
/* We have to commit the rewritten .gitmodules file */
cl_git_pass(git_repository_index(&index, repo));
cl_git_pass(git_index_add_bypath(index, ".gitmodules"));
cl_git_pass(git_index_write_tree(&tree_oid, index));
cl_git_pass(git_index_write(index));

cl_git_pass(git_index_write_tree(&tree_oid, index));
cl_git_pass(git_tree_lookup(&tree, repo, &tree_oid));

cl_git_pass(git_repository_head(&master_ref, repo));
Expand Down

0 comments on commit a07ddf9

Please sign in to comment.