1 #include "clar_libgit2.h"
6 static git_repository
*_repo
;
7 static git_index
*_index
;
9 void test_index_read_index__initialize(void)
12 git_reference
*head_ref
;
14 _repo
= cl_git_sandbox_init("testrepo");
15 cl_git_pass(git_revparse_ext(&head
, &head_ref
, _repo
, "HEAD"));
16 cl_git_pass(git_reset(_repo
, head
, GIT_RESET_HARD
, NULL
));
17 cl_git_pass(git_repository_index(&_index
, _repo
));
19 git_reference_free(head_ref
);
20 git_object_free(head
);
23 void test_index_read_index__cleanup(void)
25 git_index_free(_index
);
26 cl_git_sandbox_cleanup();
29 void test_index_read_index__maintains_stat_cache(void)
33 git_index_entry new_entry
;
34 const git_index_entry
*e
;
38 cl_assert_equal_i(4, git_index_entrycount(_index
));
41 cl_git_pass(git_index_write_tree(&index_id
, _index
));
43 /* read-tree, then read index */
44 git_tree_lookup(&tree
, _repo
, &index_id
);
45 cl_git_pass(git_index_new(&new_index
));
46 cl_git_pass(git_index_read_tree(new_index
, tree
));
49 /* add a new entry that will not have stat data */
50 memset(&new_entry
, 0, sizeof(git_index_entry
));
51 new_entry
.path
= "Hello";
52 git_oid_fromstr(&new_entry
.id
, "0123456789012345678901234567890123456789");
53 new_entry
.file_size
= 1234;
54 new_entry
.mode
= 0100644;
55 cl_git_pass(git_index_add(new_index
, &new_entry
));
56 cl_assert_equal_i(5, git_index_entrycount(new_index
));
58 cl_git_pass(git_index_read_index(_index
, new_index
));
59 git_index_free(new_index
);
61 cl_assert_equal_i(5, git_index_entrycount(_index
));
63 for (i
= 0; i
< git_index_entrycount(_index
); i
++) {
64 e
= git_index_get_byindex(_index
, i
);
66 if (strcmp(e
->path
, "Hello") == 0) {
67 cl_assert_equal_i(0, e
->ctime
.seconds
);
68 cl_assert_equal_i(0, e
->mtime
.seconds
);
70 cl_assert(0 != e
->ctime
.seconds
);
71 cl_assert(0 != e
->mtime
.seconds
);
76 static bool roundtrip_with_read_index(const char *tree_idstr
)
78 git_oid tree_id
, new_tree_id
;
80 git_index
*tree_index
;
82 cl_git_pass(git_oid_fromstr(&tree_id
, tree_idstr
));
83 cl_git_pass(git_tree_lookup(&tree
, _repo
, &tree_id
));
84 cl_git_pass(git_index_new(&tree_index
));
85 cl_git_pass(git_index_read_tree(tree_index
, tree
));
86 cl_git_pass(git_index_read_index(_index
, tree_index
));
87 cl_git_pass(git_index_write_tree(&new_tree_id
, _index
));
90 git_index_free(tree_index
);
92 return git_oid_equal(&tree_id
, &new_tree_id
);
95 void test_index_read_index__produces_treesame_indexes(void)
97 roundtrip_with_read_index("53fc32d17276939fc79ed05badaef2db09990016");
98 roundtrip_with_read_index("944c0f6e4dfa41595e6eb3ceecdb14f50fe18162");
99 roundtrip_with_read_index("1810dff58d8a660512d4832e740f692884338ccd");
100 roundtrip_with_read_index("d52a8fe84ceedf260afe4f0287bbfca04a117e83");
101 roundtrip_with_read_index("c36d8ea75da8cb510fcb0c408c1d7e53f9a99dbe");
102 roundtrip_with_read_index("7b2417a23b63e1fdde88c80e14b33247c6e5785a");
103 roundtrip_with_read_index("f82a8eb4cb20e88d1030fd10d89286215a715396");
104 roundtrip_with_read_index("fd093bff70906175335656e6ce6ae05783708765");
105 roundtrip_with_read_index("ae90f12eea699729ed24555e40b9fd669da12a12");
108 void test_index_read_index__read_and_writes(void)
110 git_oid tree_id
, new_tree_id
;
112 git_index
*tree_index
, *new_index
;
114 cl_git_pass(git_oid_fromstr(&tree_id
, "ae90f12eea699729ed24555e40b9fd669da12a12"));
115 cl_git_pass(git_tree_lookup(&tree
, _repo
, &tree_id
));
116 cl_git_pass(git_index_new(&tree_index
));
117 cl_git_pass(git_index_read_tree(tree_index
, tree
));
118 cl_git_pass(git_index_read_index(_index
, tree_index
));
119 cl_git_pass(git_index_write(_index
));
121 cl_git_pass(git_index_open(&new_index
, git_index_path(_index
)));
122 cl_git_pass(git_index_write_tree_to(&new_tree_id
, new_index
, _repo
));
124 cl_assert_equal_oid(&tree_id
, &new_tree_id
);
127 git_index_free(tree_index
);
128 git_index_free(new_index
);
131 static void add_conflicts(git_index
*index
, const char *filename
)
133 git_index_entry ancestor_entry
, our_entry
, their_entry
;
134 static int conflict_idx
= 0;
135 char *ancestor_ids
[] =
136 { CONFLICTS_ONE_ANCESTOR_OID
, CONFLICTS_TWO_ANCESTOR_OID
};
138 { CONFLICTS_ONE_OUR_OID
, CONFLICTS_TWO_OUR_OID
};
140 { CONFLICTS_ONE_THEIR_OID
, CONFLICTS_TWO_THEIR_OID
};
142 conflict_idx
= (conflict_idx
+ 1) % 2;
144 memset(&ancestor_entry
, 0x0, sizeof(git_index_entry
));
145 memset(&our_entry
, 0x0, sizeof(git_index_entry
));
146 memset(&their_entry
, 0x0, sizeof(git_index_entry
));
148 ancestor_entry
.path
= filename
;
149 ancestor_entry
.mode
= 0100644;
150 GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry
, 1);
151 git_oid_fromstr(&ancestor_entry
.id
, ancestor_ids
[conflict_idx
]);
153 our_entry
.path
= filename
;
154 our_entry
.mode
= 0100644;
155 GIT_INDEX_ENTRY_STAGE_SET(&our_entry
, 2);
156 git_oid_fromstr(&our_entry
.id
, our_ids
[conflict_idx
]);
158 their_entry
.path
= filename
;
159 their_entry
.mode
= 0100644;
160 GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry
, 2);
161 git_oid_fromstr(&their_entry
.id
, their_ids
[conflict_idx
]);
163 cl_git_pass(git_index_conflict_add(index
, &ancestor_entry
,
164 &our_entry
, &their_entry
));
167 void test_index_read_index__handles_conflicts(void)
171 git_index
*index
, *new_index
;
172 git_index_conflict_iterator
*conflict_iterator
;
173 const git_index_entry
*ancestor
, *ours
, *theirs
;
175 cl_git_pass(git_oid_fromstr(&tree_id
, "ae90f12eea699729ed24555e40b9fd669da12a12"));
176 cl_git_pass(git_tree_lookup(&tree
, _repo
, &tree_id
));
177 cl_git_pass(git_index_new(&index
));
178 cl_git_pass(git_index_new(&new_index
));
179 cl_git_pass(git_index_read_tree(index
, tree
));
180 cl_git_pass(git_index_read_tree(new_index
, tree
));
182 /* put some conflicts in only the old side, these should be removed */
183 add_conflicts(index
, "orig_side-1.txt");
184 add_conflicts(index
, "orig_side-2.txt");
186 /* put some conflicts in both indexes, these should be unchanged */
187 add_conflicts(index
, "both_sides-1.txt");
188 add_conflicts(new_index
, "both_sides-1.txt");
189 add_conflicts(index
, "both_sides-2.txt");
190 add_conflicts(new_index
, "both_sides-2.txt");
192 /* put some conflicts in the new index, these should be added */
193 add_conflicts(new_index
, "new_side-1.txt");
194 add_conflicts(new_index
, "new_side-2.txt");
196 cl_git_pass(git_index_read_index(index
, new_index
));
197 cl_git_pass(git_index_conflict_iterator_new(&conflict_iterator
, index
));
199 cl_git_pass(git_index_conflict_next(
200 &ancestor
, &ours
, &theirs
, conflict_iterator
));
201 cl_assert_equal_s("both_sides-1.txt", ancestor
->path
);
202 cl_assert_equal_s("both_sides-1.txt", ours
->path
);
203 cl_assert_equal_s("both_sides-1.txt", theirs
->path
);
205 cl_git_pass(git_index_conflict_next(
206 &ancestor
, &ours
, &theirs
, conflict_iterator
));
207 cl_assert_equal_s("both_sides-2.txt", ancestor
->path
);
208 cl_assert_equal_s("both_sides-2.txt", ours
->path
);
209 cl_assert_equal_s("both_sides-2.txt", theirs
->path
);
211 cl_git_pass(git_index_conflict_next(
212 &ancestor
, &ours
, &theirs
, conflict_iterator
));
213 cl_assert_equal_s("new_side-1.txt", ancestor
->path
);
214 cl_assert_equal_s("new_side-1.txt", ours
->path
);
215 cl_assert_equal_s("new_side-1.txt", theirs
->path
);
217 cl_git_pass(git_index_conflict_next(
218 &ancestor
, &ours
, &theirs
, conflict_iterator
));
219 cl_assert_equal_s("new_side-2.txt", ancestor
->path
);
220 cl_assert_equal_s("new_side-2.txt", ours
->path
);
221 cl_assert_equal_s("new_side-2.txt", theirs
->path
);
224 cl_git_fail_with(GIT_ITEROVER
, git_index_conflict_next(
225 &ancestor
, &ours
, &theirs
, conflict_iterator
));
227 git_index_conflict_iterator_free(conflict_iterator
);
230 git_index_free(new_index
);
231 git_index_free(index
);