Skip to content

Commit b242cdb

Browse files
committed
index: commit the changes to the index properly
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.
1 parent dc4a18c commit b242cdb

File tree

9 files changed

+59
-15
lines changed

9 files changed

+59
-15
lines changed

src/checkout.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2412,7 +2412,7 @@ static int checkout_data_init(
24122412
* and those should not be overwritten.)
24132413
*/
24142414
if (data->index != git_iterator_index(target)) {
2415-
if ((error = git_index_read(data->index, true)) < 0)
2415+
if ((error = git_index_read_safely(data->index)) < 0)
24162416
goto cleanup;
24172417

24182418
/* cannot checkout if unresolved conflicts exist */

src/index.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,17 @@ int git_index_read(git_index *index, int force)
680680
return error;
681681
}
682682

683+
int git_index_read_safely(git_index *index)
684+
{
685+
if (index->dirty) {
686+
giterr_set(GITERR_INDEX,
687+
"the index has unsaved changes that would be overwritten by this operation");
688+
return -1;
689+
}
690+
691+
return git_index_read(index, false);
692+
}
693+
683694
int git_index__changed_relative_to(
684695
git_index *index, const git_oid *checksum)
685696
{

src/index.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ GIT_INLINE(int) git_index_is_dirty(git_index *index)
149149
return index->dirty;
150150
}
151151

152+
extern int git_index_read_safely(git_index *index);
153+
152154
typedef struct {
153155
git_index *index;
154156
git_filebuf file;

src/status.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ int git_status_list_new(
294294

295295
/* refresh index from disk unless prevented */
296296
if ((flags & GIT_STATUS_OPT_NO_REFRESH) == 0 &&
297-
git_index_read(index, false) < 0)
297+
git_index_read_safely(index) < 0)
298298
giterr_clear();
299299

300300
status = git_status_list_alloc(index);

tests/checkout/tree.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,7 @@ void assert_conflict(
543543
*/
544544
cl_git_pass(git_object_peel(&hack_tree, g_object, GIT_OBJ_TREE));
545545
cl_git_pass(git_index_read_tree(index, (git_tree *)hack_tree));
546+
cl_git_pass(git_index_write(index));
546547
git_object_free(hack_tree);
547548
git_object_free(g_object);
548549
g_object = NULL;
@@ -671,9 +672,12 @@ void test_checkout_tree__can_cancel_checkout_from_notify(void)
671672
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
672673
git_oid oid;
673674
git_object *obj = NULL;
675+
git_index *index = NULL;
674676

675677
assert_on_branch(g_repo, "master");
676678

679+
cl_git_pass(git_repository_index(&index, g_repo));
680+
677681
cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir"));
678682
cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
679683

@@ -700,6 +704,8 @@ void test_checkout_tree__can_cancel_checkout_from_notify(void)
700704
else
701705
cl_assert_equal_i(4, ca.count);
702706

707+
cl_git_pass(git_index_read(index, 1));
708+
703709
/* and again with a different stopping point and return code */
704710
ca.filename = "README";
705711
ca.error = 123;
@@ -715,6 +721,7 @@ void test_checkout_tree__can_cancel_checkout_from_notify(void)
715721
cl_assert_equal_i(1, ca.count);
716722

717723
git_object_free(obj);
724+
git_index_free(index);
718725
}
719726

720727
void test_checkout_tree__can_checkout_with_last_workdir_item_missing(void)
@@ -739,7 +746,9 @@ void test_checkout_tree__can_checkout_with_last_workdir_item_missing(void)
739746
cl_git_mkfile("./testrepo/this-is-dir/contained_file", "content\n");
740747

741748
cl_git_pass(git_index_add_bypath(index, "this-is-dir/contained_file"));
742-
git_index_write_tree(&tree_id, index);
749+
cl_git_pass(git_index_write(index));
750+
751+
cl_git_pass(git_index_write_tree(&tree_id, index));
743752
cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));
744753

745754
cl_git_pass(p_unlink("./testrepo/this-is-dir/contained_file"));
@@ -1107,7 +1116,7 @@ void test_checkout_tree__removes_conflicts(void)
11071116
git_commit *commit;
11081117
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
11091118
git_index *index;
1110-
1119+
11111120
cl_git_pass(git_oid_fromstr(&commit_id, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6"));
11121121
cl_git_pass(git_commit_lookup(&commit, g_repo, &commit_id));
11131122

@@ -1150,7 +1159,7 @@ void test_checkout_tree__removes_conflicts_only_by_pathscope(void)
11501159
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
11511160
git_index *index;
11521161
const char *path = "executable.txt";
1153-
1162+
11541163
cl_git_pass(git_oid_fromstr(&commit_id, "afe4393b2b2a965f06acf2ca9658eaa01e0cd6b6"));
11551164
cl_git_pass(git_commit_lookup(&commit, g_repo, &commit_id));
11561165

@@ -1248,7 +1257,7 @@ void test_checkout_tree__case_changing_rename(void)
12481257

12491258
cl_git_pass(git_checkout_tree(g_repo, (git_object *)master_commit, &opts));
12501259
cl_git_pass(git_repository_set_head(g_repo, "refs/heads/master"));
1251-
1260+
12521261
assert_on_branch(g_repo, "master");
12531262

12541263
cl_assert(git_path_isfile("testrepo/README"));
@@ -1493,8 +1502,11 @@ void test_checkout_tree__baseline_is_empty_when_no_index(void)
14931502
git_reference *head;
14941503
git_object *obj;
14951504
size_t conflicts = 0;
1505+
git_index *index;
14961506

14971507
assert_on_branch(g_repo, "master");
1508+
1509+
cl_git_pass(git_repository_index(&index, g_repo));
14981510
cl_git_pass(git_repository_head(&head, g_repo));
14991511
cl_git_pass(git_reference_peel(&obj, head, GIT_OBJ_COMMIT));
15001512

@@ -1513,6 +1525,8 @@ void test_checkout_tree__baseline_is_empty_when_no_index(void)
15131525
cl_git_fail_with(GIT_ECONFLICT, git_checkout_tree(g_repo, obj, &opts));
15141526
cl_assert_equal_i(4, conflicts);
15151527

1528+
cl_git_pass(git_index_read(index, 1));
1529+
15161530
/* but force should succeed and update the index */
15171531
opts.checkout_strategy |= GIT_CHECKOUT_FORCE;
15181532
cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
@@ -1521,6 +1535,7 @@ void test_checkout_tree__baseline_is_empty_when_no_index(void)
15211535

15221536
git_object_free(obj);
15231537
git_reference_free(head);
1538+
git_index_free(index);
15241539
}
15251540

15261541
void test_checkout_tree__mode_change_is_force_updated(void)
@@ -1551,8 +1566,12 @@ void test_checkout_tree__mode_change_is_force_updated(void)
15511566
cl_must_pass(p_chmod("testrepo/README", 0755));
15521567
cl_must_pass(git_index_add_bypath(index, "README"));
15531568

1569+
cl_git_pass(git_index_write(index));
15541570
assert_status_entrycount(g_repo, 1);
1571+
15551572
cl_git_pass(git_checkout_tree(g_repo, obj, &g_opts));
1573+
cl_git_pass(git_index_write(index));
1574+
15561575
assert_status_entrycount(g_repo, 0);
15571576

15581577
git_object_free(obj);

tests/checkout/typechange.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ static int make_submodule_dirty(git_submodule *sm, const char *name, void *paylo
259259
void test_checkout_typechange__checkout_with_conflicts(void)
260260
{
261261
int i;
262+
git_index *index;
262263
git_object *obj;
263264
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
264265
notify_counts cts = {0};
@@ -289,6 +290,10 @@ void test_checkout_typechange__checkout_with_conflicts(void)
289290
cl_assert_equal_i(cts.updates, 0);
290291
cl_assert_equal_i(cts.ignored, 0);
291292

293+
cl_git_pass(git_repository_index(&index, g_repo));
294+
cl_git_pass(git_index_read(index, 1));
295+
git_index_free(index);
296+
292297
opts.checkout_strategy =
293298
GIT_CHECKOUT_FORCE | GIT_CHECKOUT_REMOVE_UNTRACKED;
294299
memset(&cts, 0, sizeof(cts));

tests/index/names.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ void test_index_names__add(void)
8686
cl_assert(strcmp(conflict_name->ancestor, "ancestor3") == 0);
8787
cl_assert(conflict_name->ours == NULL);
8888
cl_assert(strcmp(conflict_name->theirs, "theirs3") == 0);
89+
90+
cl_git_pass(git_index_write(repo_index));
8991
}
9092

9193
void test_index_names__roundtrip(void)
@@ -151,12 +153,12 @@ void test_index_names__cleaned_on_checkout_tree(void)
151153
git_object *obj;
152154
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
153155

154-
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_ONLY;
156+
opts.checkout_strategy = GIT_CHECKOUT_FORCE | GIT_CHECKOUT_UPDATE_ONLY;
155157

156158
test_index_names__add();
157-
git_reference_name_to_id(&oid, repo, "refs/heads/master");
158-
git_object_lookup(&obj, repo, &oid, GIT_OBJ_ANY);
159-
git_checkout_tree(repo, obj, &opts);
159+
cl_git_pass(git_reference_name_to_id(&oid, repo, "refs/heads/master"));
160+
cl_git_pass(git_object_lookup(&obj, repo, &oid, GIT_OBJ_ANY));
161+
cl_git_pass(git_checkout_tree(repo, obj, &opts));
160162
cl_assert_equal_sz(0, git_index_name_entrycount(repo_index));
161163

162164
git_object_free(obj);
@@ -166,20 +168,20 @@ void test_index_names__cleaned_on_checkout_head(void)
166168
{
167169
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
168170

169-
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_ONLY;
171+
opts.checkout_strategy = GIT_CHECKOUT_FORCE | GIT_CHECKOUT_UPDATE_ONLY;
170172

171173
test_index_names__add();
172-
git_checkout_head(repo, &opts);
174+
cl_git_pass(git_checkout_head(repo, &opts));
173175
cl_assert_equal_sz(0, git_index_name_entrycount(repo_index));
174176
}
175177

176178
void test_index_names__retained_on_checkout_index(void)
177179
{
178180
git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
179181

180-
opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_ONLY;
182+
opts.checkout_strategy = GIT_CHECKOUT_FORCE | GIT_CHECKOUT_UPDATE_ONLY;
181183

182184
test_index_names__add();
183-
git_checkout_index(repo, repo_index, &opts);
185+
cl_git_pass(git_checkout_index(repo, repo_index, &opts));
184186
cl_assert(git_index_name_entrycount(repo_index) > 0);
185187
}

tests/index/reuc.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ void test_index_reuc__add(void)
5656
cl_assert_equal_oid(&reuc->oid[0], &ancestor_oid);
5757
cl_assert_equal_oid(&reuc->oid[1], &our_oid);
5858
cl_assert_equal_oid(&reuc->oid[2], &their_oid);
59+
60+
cl_git_pass(git_index_write(repo_index));
5961
}
6062

6163
void test_index_reuc__add_no_ancestor(void)
@@ -81,6 +83,8 @@ void test_index_reuc__add_no_ancestor(void)
8183
cl_assert_equal_oid(&reuc->oid[0], &ancestor_oid);
8284
cl_assert_equal_oid(&reuc->oid[1], &our_oid);
8385
cl_assert_equal_oid(&reuc->oid[2], &their_oid);
86+
87+
cl_git_pass(git_index_write(repo_index));
8488
}
8589

8690
void test_index_reuc__read_bypath(void)

tests/rebase/submodule.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ void test_rebase_submodule__initialize(void)
3333
/* We have to commit the rewritten .gitmodules file */
3434
cl_git_pass(git_repository_index(&index, repo));
3535
cl_git_pass(git_index_add_bypath(index, ".gitmodules"));
36-
cl_git_pass(git_index_write_tree(&tree_oid, index));
36+
cl_git_pass(git_index_write(index));
3737

38+
cl_git_pass(git_index_write_tree(&tree_oid, index));
3839
cl_git_pass(git_tree_lookup(&tree, repo, &tree_oid));
3940

4041
cl_git_pass(git_repository_head(&master_ref, repo));

0 commit comments

Comments
 (0)