]> git.proxmox.com Git - libgit2.git/blob - tests/index/conflicts.c
New upstream version 1.4.3+dfsg.1
[libgit2.git] / tests / index / conflicts.c
1 #include "clar_libgit2.h"
2 #include "index.h"
3 #include "git2/repository.h"
4 #include "conflicts.h"
5
6 static git_repository *repo;
7 static git_index *repo_index;
8
9 #define TEST_REPO_PATH "mergedrepo"
10 #define TEST_INDEX_PATH TEST_REPO_PATH "/.git/index"
11
12 /* Fixture setup and teardown */
13 void test_index_conflicts__initialize(void)
14 {
15 repo = cl_git_sandbox_init("mergedrepo");
16 git_repository_index(&repo_index, repo);
17 }
18
19 void test_index_conflicts__cleanup(void)
20 {
21 git_index_free(repo_index);
22 repo_index = NULL;
23
24 cl_git_sandbox_cleanup();
25 }
26
27 void test_index_conflicts__add(void)
28 {
29 git_index_entry ancestor_entry, our_entry, their_entry;
30
31 cl_assert(git_index_entrycount(repo_index) == 8);
32
33 memset(&ancestor_entry, 0x0, sizeof(git_index_entry));
34 memset(&our_entry, 0x0, sizeof(git_index_entry));
35 memset(&their_entry, 0x0, sizeof(git_index_entry));
36
37 ancestor_entry.path = "test-one.txt";
38 ancestor_entry.mode = 0100644;
39 GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, 1);
40 git_oid_fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID);
41
42 our_entry.path = "test-one.txt";
43 our_entry.mode = 0100644;
44 GIT_INDEX_ENTRY_STAGE_SET(&our_entry, 2);
45 git_oid_fromstr(&our_entry.id, CONFLICTS_ONE_OUR_OID);
46
47 their_entry.path = "test-one.txt";
48 their_entry.mode = 0100644;
49 GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, 2);
50 git_oid_fromstr(&their_entry.id, CONFLICTS_ONE_THEIR_OID);
51
52 cl_git_pass(git_index_conflict_add(repo_index, &ancestor_entry, &our_entry, &their_entry));
53
54 cl_assert(git_index_entrycount(repo_index) == 11);
55 }
56
57 void test_index_conflicts__add_fixes_incorrect_stage(void)
58 {
59 git_index_entry ancestor_entry, our_entry, their_entry;
60 const git_index_entry *conflict_entry[3];
61
62 cl_assert(git_index_entrycount(repo_index) == 8);
63
64 memset(&ancestor_entry, 0x0, sizeof(git_index_entry));
65 memset(&our_entry, 0x0, sizeof(git_index_entry));
66 memset(&their_entry, 0x0, sizeof(git_index_entry));
67
68 ancestor_entry.path = "test-one.txt";
69 ancestor_entry.mode = 0100644;
70 GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, 3);
71 git_oid_fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID);
72
73 our_entry.path = "test-one.txt";
74 our_entry.mode = 0100644;
75 GIT_INDEX_ENTRY_STAGE_SET(&our_entry, 1);
76 git_oid_fromstr(&our_entry.id, CONFLICTS_ONE_OUR_OID);
77
78 their_entry.path = "test-one.txt";
79 their_entry.mode = 0100644;
80 GIT_INDEX_ENTRY_STAGE_SET(&their_entry, 2);
81 git_oid_fromstr(&their_entry.id, CONFLICTS_ONE_THEIR_OID);
82
83 cl_git_pass(git_index_conflict_add(repo_index, &ancestor_entry, &our_entry, &their_entry));
84
85 cl_assert(git_index_entrycount(repo_index) == 11);
86
87 cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], repo_index, "test-one.txt"));
88
89 cl_assert(git_index_entry_stage(conflict_entry[0]) == 1);
90 cl_assert(git_index_entry_stage(conflict_entry[1]) == 2);
91 cl_assert(git_index_entry_stage(conflict_entry[2]) == 3);
92 }
93
94 void test_index_conflicts__add_detects_invalid_filemode(void)
95 {
96 git_index_entry ancestor_entry, our_entry, their_entry;
97 git_index_entry *conflict_entry[3];
98 int i;
99
100 cl_assert(git_index_entrycount(repo_index) == 8);
101
102 memset(&ancestor_entry, 0x0, sizeof(git_index_entry));
103 memset(&our_entry, 0x0, sizeof(git_index_entry));
104 memset(&their_entry, 0x0, sizeof(git_index_entry));
105
106 conflict_entry[0] = &ancestor_entry;
107 conflict_entry[1] = &our_entry;
108 conflict_entry[2] = &their_entry;
109
110 for (i = 0; i < 3; i++) {
111 ancestor_entry.path = "test-one.txt";
112 ancestor_entry.mode = 0100644;
113 GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, 3);
114 git_oid_fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID);
115
116 our_entry.path = "test-one.txt";
117 our_entry.mode = 0100644;
118 GIT_INDEX_ENTRY_STAGE_SET(&our_entry, 1);
119 git_oid_fromstr(&our_entry.id, CONFLICTS_ONE_OUR_OID);
120
121 their_entry.path = "test-one.txt";
122 their_entry.mode = 0100644;
123 GIT_INDEX_ENTRY_STAGE_SET(&their_entry, 2);
124 git_oid_fromstr(&their_entry.id, CONFLICTS_ONE_THEIR_OID);
125
126 /* Corrupt the conflict entry's mode */
127 conflict_entry[i]->mode = 027431745;
128
129 cl_git_fail(git_index_conflict_add(repo_index, &ancestor_entry, &our_entry, &their_entry));
130 }
131
132 cl_assert(git_index_entrycount(repo_index) == 8);
133 }
134
135
136 void test_index_conflicts__add_removes_stage_zero(void)
137 {
138 git_index_entry ancestor_entry, our_entry, their_entry;
139 const git_index_entry *conflict_entry[3];
140
141 cl_assert(git_index_entrycount(repo_index) == 8);
142
143 memset(&ancestor_entry, 0x0, sizeof(git_index_entry));
144 memset(&our_entry, 0x0, sizeof(git_index_entry));
145 memset(&their_entry, 0x0, sizeof(git_index_entry));
146
147 cl_git_mkfile("./mergedrepo/test-one.txt", "new-file\n");
148 cl_git_pass(git_index_add_bypath(repo_index, "test-one.txt"));
149 cl_assert(git_index_entrycount(repo_index) == 9);
150
151 ancestor_entry.path = "test-one.txt";
152 ancestor_entry.mode = 0100644;
153 GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, 3);
154 git_oid_fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID);
155
156 our_entry.path = "test-one.txt";
157 our_entry.mode = 0100644;
158 GIT_INDEX_ENTRY_STAGE_SET(&our_entry, 1);
159 git_oid_fromstr(&our_entry.id, CONFLICTS_ONE_OUR_OID);
160
161 their_entry.path = "test-one.txt";
162 their_entry.mode = 0100644;
163 GIT_INDEX_ENTRY_STAGE_SET(&their_entry, 2);
164 git_oid_fromstr(&their_entry.id, CONFLICTS_ONE_THEIR_OID);
165
166 cl_git_pass(git_index_conflict_add(repo_index, &ancestor_entry, &our_entry, &their_entry));
167
168 cl_assert(git_index_entrycount(repo_index) == 11);
169
170 cl_assert_equal_p(NULL, git_index_get_bypath(repo_index, "test-one.txt", 0));
171
172 cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], repo_index, "test-one.txt"));
173
174 cl_assert_equal_oid(&ancestor_entry.id, &conflict_entry[0]->id);
175 cl_assert_equal_i(1, git_index_entry_stage(conflict_entry[0]));
176 cl_assert_equal_oid(&our_entry.id, &conflict_entry[1]->id);
177 cl_assert_equal_i(2, git_index_entry_stage(conflict_entry[1]));
178 cl_assert_equal_oid(&their_entry.id, &conflict_entry[2]->id);
179 cl_assert_equal_i(3, git_index_entry_stage(conflict_entry[2]));
180 }
181
182 void test_index_conflicts__get(void)
183 {
184 const git_index_entry *conflict_entry[3];
185 git_oid oid;
186
187 cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1],
188 &conflict_entry[2], repo_index, "conflicts-one.txt"));
189
190 cl_assert_equal_s("conflicts-one.txt", conflict_entry[0]->path);
191
192 git_oid_fromstr(&oid, CONFLICTS_ONE_ANCESTOR_OID);
193 cl_assert_equal_oid(&oid, &conflict_entry[0]->id);
194
195 git_oid_fromstr(&oid, CONFLICTS_ONE_OUR_OID);
196 cl_assert_equal_oid(&oid, &conflict_entry[1]->id);
197
198 git_oid_fromstr(&oid, CONFLICTS_ONE_THEIR_OID);
199 cl_assert_equal_oid(&oid, &conflict_entry[2]->id);
200
201 cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1],
202 &conflict_entry[2], repo_index, "conflicts-two.txt"));
203
204 cl_assert_equal_s("conflicts-two.txt", conflict_entry[0]->path);
205
206 git_oid_fromstr(&oid, CONFLICTS_TWO_ANCESTOR_OID);
207 cl_assert_equal_oid(&oid, &conflict_entry[0]->id);
208
209 git_oid_fromstr(&oid, CONFLICTS_TWO_OUR_OID);
210 cl_assert_equal_oid(&oid, &conflict_entry[1]->id);
211
212 git_oid_fromstr(&oid, CONFLICTS_TWO_THEIR_OID);
213 cl_assert_equal_oid(&oid, &conflict_entry[2]->id);
214 }
215
216 void test_index_conflicts__iterate(void)
217 {
218 git_index_conflict_iterator *iterator;
219 const git_index_entry *conflict_entry[3];
220 git_oid oid;
221
222 cl_git_pass(git_index_conflict_iterator_new(&iterator, repo_index));
223
224 cl_git_pass(git_index_conflict_next(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], iterator));
225
226 git_oid_fromstr(&oid, CONFLICTS_ONE_ANCESTOR_OID);
227 cl_assert_equal_oid(&oid, &conflict_entry[0]->id);
228 cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-one.txt") == 0);
229
230 git_oid_fromstr(&oid, CONFLICTS_ONE_OUR_OID);
231 cl_assert_equal_oid(&oid, &conflict_entry[1]->id);
232 cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-one.txt") == 0);
233
234 git_oid_fromstr(&oid, CONFLICTS_ONE_THEIR_OID);
235 cl_assert_equal_oid(&oid, &conflict_entry[2]->id);
236 cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-one.txt") == 0);
237
238 cl_git_pass(git_index_conflict_next(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], iterator));
239
240 git_oid_fromstr(&oid, CONFLICTS_TWO_ANCESTOR_OID);
241 cl_assert_equal_oid(&oid, &conflict_entry[0]->id);
242 cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-two.txt") == 0);
243
244 git_oid_fromstr(&oid, CONFLICTS_TWO_OUR_OID);
245 cl_assert_equal_oid(&oid, &conflict_entry[1]->id);
246 cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-two.txt") == 0);
247
248 git_oid_fromstr(&oid, CONFLICTS_TWO_THEIR_OID);
249 cl_assert_equal_oid(&oid, &conflict_entry[2]->id);
250 cl_assert(git__strcmp(conflict_entry[0]->path, "conflicts-two.txt") == 0);
251
252 cl_assert(git_index_conflict_next(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], iterator) == GIT_ITEROVER);
253
254 cl_assert(conflict_entry[0] == NULL);
255 cl_assert(conflict_entry[2] == NULL);
256 cl_assert(conflict_entry[2] == NULL);
257
258 git_index_conflict_iterator_free(iterator);
259 }
260
261 void test_index_conflicts__remove(void)
262 {
263 const git_index_entry *entry;
264 size_t i;
265
266 cl_assert(git_index_entrycount(repo_index) == 8);
267
268 cl_git_pass(git_index_conflict_remove(repo_index, "conflicts-one.txt"));
269 cl_assert(git_index_entrycount(repo_index) == 5);
270
271 for (i = 0; i < git_index_entrycount(repo_index); i++) {
272 cl_assert(entry = git_index_get_byindex(repo_index, i));
273 cl_assert(strcmp(entry->path, "conflicts-one.txt") != 0);
274 }
275
276 cl_git_pass(git_index_conflict_remove(repo_index, "conflicts-two.txt"));
277 cl_assert(git_index_entrycount(repo_index) == 2);
278
279 for (i = 0; i < git_index_entrycount(repo_index); i++) {
280 cl_assert(entry = git_index_get_byindex(repo_index, i));
281 cl_assert(strcmp(entry->path, "conflicts-two.txt") != 0);
282 }
283 }
284
285 void test_index_conflicts__moved_to_reuc_on_add(void)
286 {
287 const git_index_entry *entry;
288 size_t i;
289
290 cl_assert(git_index_entrycount(repo_index) == 8);
291
292 cl_git_mkfile("./mergedrepo/conflicts-one.txt", "new-file\n");
293
294 cl_git_pass(git_index_add_bypath(repo_index, "conflicts-one.txt"));
295
296 cl_assert(git_index_entrycount(repo_index) == 6);
297
298 for (i = 0; i < git_index_entrycount(repo_index); i++) {
299 cl_assert(entry = git_index_get_byindex(repo_index, i));
300
301 if (strcmp(entry->path, "conflicts-one.txt") == 0)
302 cl_assert(!git_index_entry_is_conflict(entry));
303 }
304 }
305
306 void test_index_conflicts__moved_to_reuc_on_remove(void)
307 {
308 const git_index_entry *entry;
309 size_t i;
310
311 cl_assert(git_index_entrycount(repo_index) == 8);
312
313 cl_git_pass(p_unlink("./mergedrepo/conflicts-one.txt"));
314
315 cl_git_pass(git_index_remove_bypath(repo_index, "conflicts-one.txt"));
316
317 cl_assert(git_index_entrycount(repo_index) == 5);
318
319 for (i = 0; i < git_index_entrycount(repo_index); i++) {
320 cl_assert(entry = git_index_get_byindex(repo_index, i));
321 cl_assert(strcmp(entry->path, "conflicts-one.txt") != 0);
322 }
323 }
324
325 void test_index_conflicts__remove_all_conflicts(void)
326 {
327 size_t i;
328 const git_index_entry *entry;
329
330 cl_assert(git_index_entrycount(repo_index) == 8);
331
332 cl_assert_equal_i(true, git_index_has_conflicts(repo_index));
333
334 git_index_conflict_cleanup(repo_index);
335
336 cl_assert_equal_i(false, git_index_has_conflicts(repo_index));
337
338 cl_assert(git_index_entrycount(repo_index) == 2);
339
340 for (i = 0; i < git_index_entrycount(repo_index); i++) {
341 cl_assert(entry = git_index_get_byindex(repo_index, i));
342 cl_assert(!git_index_entry_is_conflict(entry));
343 }
344 }
345
346 void test_index_conflicts__partial(void)
347 {
348 git_index_entry ancestor_entry, our_entry, their_entry;
349 const git_index_entry *conflict_entry[3];
350
351 cl_assert(git_index_entrycount(repo_index) == 8);
352
353 memset(&ancestor_entry, 0x0, sizeof(git_index_entry));
354 memset(&our_entry, 0x0, sizeof(git_index_entry));
355 memset(&their_entry, 0x0, sizeof(git_index_entry));
356
357 ancestor_entry.path = "test-one.txt";
358 ancestor_entry.mode = 0100644;
359 GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, 1);
360 git_oid_fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID);
361
362 cl_git_pass(git_index_conflict_add(repo_index, &ancestor_entry, NULL, NULL));
363 cl_assert(git_index_entrycount(repo_index) == 9);
364
365 cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1],
366 &conflict_entry[2], repo_index, "test-one.txt"));
367
368 cl_assert_equal_oid(&ancestor_entry.id, &conflict_entry[0]->id);
369 cl_assert(conflict_entry[1] == NULL);
370 cl_assert(conflict_entry[2] == NULL);
371 }
372
373 void test_index_conflicts__case_matters(void)
374 {
375 const git_index_entry *conflict_entry[3];
376 git_oid oid;
377 const char *upper_case = "DIFFERS-IN-CASE.TXT";
378 const char *mixed_case = "Differs-In-Case.txt";
379 const char *correct_case;
380 bool ignorecase = cl_repo_get_bool(repo, "core.ignorecase");
381
382 git_index_entry ancestor_entry, our_entry, their_entry;
383
384 memset(&ancestor_entry, 0x0, sizeof(git_index_entry));
385 memset(&our_entry, 0x0, sizeof(git_index_entry));
386 memset(&their_entry, 0x0, sizeof(git_index_entry));
387
388 ancestor_entry.path = upper_case;
389 GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, GIT_INDEX_STAGE_ANCESTOR);
390 git_oid_fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID);
391 ancestor_entry.mode = GIT_FILEMODE_BLOB;
392
393 our_entry.path = upper_case;
394 GIT_INDEX_ENTRY_STAGE_SET(&our_entry, GIT_INDEX_STAGE_OURS);
395 git_oid_fromstr(&our_entry.id, CONFLICTS_ONE_OUR_OID);
396 our_entry.mode = GIT_FILEMODE_BLOB;
397
398 their_entry.path = upper_case;
399 GIT_INDEX_ENTRY_STAGE_SET(&their_entry, GIT_INDEX_STAGE_THEIRS);
400 git_oid_fromstr(&their_entry.id, CONFLICTS_ONE_THEIR_OID);
401 their_entry.mode = GIT_FILEMODE_BLOB;
402
403 cl_git_pass(git_index_conflict_add(repo_index,
404 &ancestor_entry, &our_entry, &their_entry));
405
406 ancestor_entry.path = mixed_case;
407 GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, GIT_INDEX_STAGE_ANCESTOR);
408 git_oid_fromstr(&ancestor_entry.id, CONFLICTS_TWO_ANCESTOR_OID);
409 ancestor_entry.mode = GIT_FILEMODE_BLOB;
410
411 our_entry.path = mixed_case;
412 GIT_INDEX_ENTRY_STAGE_SET(&ancestor_entry, GIT_INDEX_STAGE_ANCESTOR);
413 git_oid_fromstr(&our_entry.id, CONFLICTS_TWO_OUR_OID);
414 ancestor_entry.mode = GIT_FILEMODE_BLOB;
415
416 their_entry.path = mixed_case;
417 GIT_INDEX_ENTRY_STAGE_SET(&their_entry, GIT_INDEX_STAGE_THEIRS);
418 git_oid_fromstr(&their_entry.id, CONFLICTS_TWO_THEIR_OID);
419 their_entry.mode = GIT_FILEMODE_BLOB;
420
421 cl_git_pass(git_index_conflict_add(repo_index,
422 &ancestor_entry, &our_entry, &their_entry));
423
424 cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1],
425 &conflict_entry[2], repo_index, upper_case));
426
427 /*
428 * We inserted with mixed case last, so on a case-insensitive
429 * fs we should get the mixed case.
430 */
431 if (ignorecase)
432 correct_case = mixed_case;
433 else
434 correct_case = upper_case;
435
436 cl_assert_equal_s(correct_case, conflict_entry[0]->path);
437 git_oid_fromstr(&oid, ignorecase ? CONFLICTS_TWO_ANCESTOR_OID : CONFLICTS_ONE_ANCESTOR_OID);
438 cl_assert_equal_oid(&oid, &conflict_entry[0]->id);
439
440 cl_assert_equal_s(correct_case, conflict_entry[1]->path);
441 git_oid_fromstr(&oid, ignorecase ? CONFLICTS_TWO_OUR_OID : CONFLICTS_ONE_OUR_OID);
442 cl_assert_equal_oid(&oid, &conflict_entry[1]->id);
443
444 cl_assert_equal_s(correct_case, conflict_entry[2]->path);
445 git_oid_fromstr(&oid, ignorecase ? CONFLICTS_TWO_THEIR_OID : CONFLICTS_ONE_THEIR_OID);
446 cl_assert_equal_oid(&oid, &conflict_entry[2]->id);
447
448 cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1],
449 &conflict_entry[2], repo_index, mixed_case));
450
451 cl_assert_equal_s(mixed_case, conflict_entry[0]->path);
452 git_oid_fromstr(&oid, CONFLICTS_TWO_ANCESTOR_OID);
453 cl_assert_equal_oid(&oid, &conflict_entry[0]->id);
454
455 cl_assert_equal_s(mixed_case, conflict_entry[1]->path);
456 git_oid_fromstr(&oid, CONFLICTS_TWO_OUR_OID);
457 cl_assert_equal_oid(&oid, &conflict_entry[1]->id);
458
459 cl_assert_equal_s(mixed_case, conflict_entry[2]->path);
460 git_oid_fromstr(&oid, CONFLICTS_TWO_THEIR_OID);
461 cl_assert_equal_oid(&oid, &conflict_entry[2]->id);
462 }