]> git.proxmox.com Git - libgit2.git/blame - tests/iterator/index.c
leaks: fix some iterator leaks
[libgit2.git] / tests / iterator / index.c
CommitLineData
de034cd2
ET
1#include "clar_libgit2.h"
2#include "iterator.h"
3#include "repository.h"
4#include "fileops.h"
5#include "iterator_helpers.h"
6#include "../submodule/submodule_helpers.h"
7#include <stdarg.h>
8
9static git_repository *g_repo;
10
11void test_iterator_index__initialize(void)
12{
13}
14
15void test_iterator_index__cleanup(void)
16{
17 cl_git_sandbox_cleanup();
18 g_repo = NULL;
19}
20
21static void index_iterator_test(
22 const char *sandbox,
23 const char *start,
24 const char *end,
25 git_iterator_flag_t flags,
26 int expected_count,
27 const char **expected_names,
28 const char **expected_oids)
29{
30 git_index *index;
31 git_iterator *i;
32 const git_index_entry *entry;
33 int error, count = 0, caps;
34 git_iterator_options iter_opts = GIT_ITERATOR_OPTIONS_INIT;
35
36 g_repo = cl_git_sandbox_init(sandbox);
37
38 cl_git_pass(git_repository_index(&index, g_repo));
39 caps = git_index_caps(index);
40
41 iter_opts.flags = flags;
42 iter_opts.start = start;
43 iter_opts.end = end;
44
45 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &iter_opts));
46
47 while (!(error = git_iterator_advance(&entry, i))) {
48 cl_assert(entry);
49
50 if (expected_names != NULL)
51 cl_assert_equal_s(expected_names[count], entry->path);
52
53 if (expected_oids != NULL) {
54 git_oid oid;
55 cl_git_pass(git_oid_fromstr(&oid, expected_oids[count]));
56 cl_assert_equal_oid(&oid, &entry->id);
57 }
58
59 count++;
60 }
61
62 cl_assert_equal_i(GIT_ITEROVER, error);
63 cl_assert(!entry);
64 cl_assert_equal_i(expected_count, count);
65
66 git_iterator_free(i);
67
68 cl_assert(caps == git_index_caps(index));
69 git_index_free(index);
70}
71
72static const char *expected_index_0[] = {
73 "attr0",
74 "attr1",
75 "attr2",
76 "attr3",
77 "binfile",
78 "gitattributes",
79 "macro_bad",
80 "macro_test",
81 "root_test1",
82 "root_test2",
83 "root_test3",
84 "root_test4.txt",
85 "sub/abc",
86 "sub/file",
87 "sub/sub/file",
88 "sub/sub/subsub.txt",
89 "sub/subdir_test1",
90 "sub/subdir_test2.txt",
91 "subdir/.gitattributes",
92 "subdir/abc",
93 "subdir/subdir_test1",
94 "subdir/subdir_test2.txt",
95 "subdir2/subdir2_test1",
96};
97
98static const char *expected_index_oids_0[] = {
99 "556f8c827b8e4a02ad5cab77dca2bcb3e226b0b3",
100 "3b74db7ab381105dc0d28f8295a77f6a82989292",
101 "2c66e14f77196ea763fb1e41612c1aa2bc2d8ed2",
102 "c485abe35abd4aa6fd83b076a78bbea9e2e7e06c",
103 "d800886d9c86731ae5c4a62b0b77c437015e00d2",
104 "2b40c5aca159b04ea8d20ffe36cdf8b09369b14a",
105 "5819a185d77b03325aaf87cafc771db36f6ddca7",
106 "ff69f8639ce2e6010b3f33a74160aad98b48da2b",
107 "45141a79a77842c59a63229403220a4e4be74e3d",
108 "4d713dc48e6b1bd75b0d61ad078ba9ca3a56745d",
109 "108bb4e7fd7b16490dc33ff7d972151e73d7166e",
110 "a0f7217ae99f5ac3e88534f5cea267febc5fa85b",
111 "3e42ffc54a663f9401cc25843d6c0e71a33e4249",
112 "45b983be36b73c0788dc9cbcb76cbb80fc7bb057",
113 "45b983be36b73c0788dc9cbcb76cbb80fc7bb057",
114 "9e5bdc47d6a80f2be0ea3049ad74231b94609242",
115 "e563cf4758f0d646f1b14b76016aa17fa9e549a4",
116 "fb5067b1aef3ac1ada4b379dbcb7d17255df7d78",
117 "99eae476896f4907224978b88e5ecaa6c5bb67a9",
118 "3e42ffc54a663f9401cc25843d6c0e71a33e4249",
119 "e563cf4758f0d646f1b14b76016aa17fa9e549a4",
120 "fb5067b1aef3ac1ada4b379dbcb7d17255df7d78",
121 "dccada462d3df8ac6de596fb8c896aba9344f941"
122};
123
124void test_iterator_index__0(void)
125{
126 index_iterator_test(
127 "attr", NULL, NULL, 0, ARRAY_SIZE(expected_index_0),
128 expected_index_0, expected_index_oids_0);
129}
130
131static const char *expected_index_1[] = {
132 "current_file",
133 "file_deleted",
134 "modified_file",
135 "staged_changes",
136 "staged_changes_file_deleted",
137 "staged_changes_modified_file",
138 "staged_new_file",
139 "staged_new_file_deleted_file",
140 "staged_new_file_modified_file",
141 "subdir.txt",
142 "subdir/current_file",
143 "subdir/deleted_file",
144 "subdir/modified_file",
145};
146
147static const char* expected_index_oids_1[] = {
148 "a0de7e0ac200c489c41c59dfa910154a70264e6e",
149 "5452d32f1dd538eb0405e8a83cc185f79e25e80f",
150 "452e4244b5d083ddf0460acf1ecc74db9dcfa11a",
151 "55d316c9ba708999f1918e9677d01dfcae69c6b9",
152 "a6be623522ce87a1d862128ac42672604f7b468b",
153 "906ee7711f4f4928ddcb2a5f8fbc500deba0d2a8",
154 "529a16e8e762d4acb7b9636ff540a00831f9155a",
155 "90b8c29d8ba39434d1c63e1b093daaa26e5bd972",
156 "ed062903b8f6f3dccb2fa81117ba6590944ef9bd",
157 "e8ee89e15bbe9b20137715232387b3de5b28972e",
158 "53ace0d1cc1145a5f4fe4f78a186a60263190733",
159 "1888c805345ba265b0ee9449b8877b6064592058",
160 "a6191982709b746d5650e93c2acf34ef74e11504"
161};
162
163void test_iterator_index__1(void)
164{
165 index_iterator_test(
166 "status", NULL, NULL, 0, ARRAY_SIZE(expected_index_1),
167 expected_index_1, expected_index_oids_1);
168}
169
170static const char *expected_index_range[] = {
171 "root_test1",
172 "root_test2",
173 "root_test3",
174 "root_test4.txt",
175};
176
177static const char *expected_index_oids_range[] = {
178 "45141a79a77842c59a63229403220a4e4be74e3d",
179 "4d713dc48e6b1bd75b0d61ad078ba9ca3a56745d",
180 "108bb4e7fd7b16490dc33ff7d972151e73d7166e",
181 "a0f7217ae99f5ac3e88534f5cea267febc5fa85b",
182};
183
184void test_iterator_index__range(void)
185{
186 index_iterator_test(
187 "attr", "root", "root", 0, ARRAY_SIZE(expected_index_range),
188 expected_index_range, expected_index_oids_range);
189}
190
191void test_iterator_index__range_empty_0(void)
192{
193 index_iterator_test(
194 "attr", "empty", "empty", 0, 0, NULL, NULL);
195}
196
197void test_iterator_index__range_empty_1(void)
198{
199 index_iterator_test(
200 "attr", "z_empty_after", NULL, 0, 0, NULL, NULL);
201}
202
203void test_iterator_index__range_empty_2(void)
204{
205 index_iterator_test(
206 "attr", NULL, ".aaa_empty_before", 0, 0, NULL, NULL);
207}
208
209static void check_index_range(
210 git_repository *repo,
211 const char *start,
212 const char *end,
213 bool ignore_case,
214 int expected_count)
215{
216 git_index *index;
217 git_iterator *i;
218 git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
219 int error, count, caps;
220 bool is_ignoring_case;
221
222 cl_git_pass(git_repository_index(&index, repo));
223
224 caps = git_index_caps(index);
225 is_ignoring_case = ((caps & GIT_INDEXCAP_IGNORE_CASE) != 0);
226
227 if (ignore_case != is_ignoring_case)
228 cl_git_pass(git_index_set_caps(index, caps ^ GIT_INDEXCAP_IGNORE_CASE));
229
230 i_opts.flags = 0;
231 i_opts.start = start;
232 i_opts.end = end;
233
234 cl_git_pass(git_iterator_for_index(&i, repo, index, &i_opts));
235
236 cl_assert(git_iterator_ignore_case(i) == ignore_case);
237
238 for (count = 0; !(error = git_iterator_advance(NULL, i)); ++count)
239 /* count em up */;
240
241 cl_assert_equal_i(GIT_ITEROVER, error);
242 cl_assert_equal_i(expected_count, count);
243
244 git_iterator_free(i);
245 git_index_free(index);
246}
247
248void test_iterator_index__range_icase(void)
249{
250 git_index *index;
251 git_tree *head;
252
253 g_repo = cl_git_sandbox_init("testrepo");
254
255 /* reset index to match HEAD */
256 cl_git_pass(git_repository_head_tree(&head, g_repo));
257 cl_git_pass(git_repository_index(&index, g_repo));
258 cl_git_pass(git_index_read_tree(index, head));
259 cl_git_pass(git_index_write(index));
260 git_tree_free(head);
261 git_index_free(index);
262
263 /* do some ranged iterator checks toggling case sensitivity */
264 check_index_range(g_repo, "B", "C", false, 0);
265 check_index_range(g_repo, "B", "C", true, 1);
266 check_index_range(g_repo, "a", "z", false, 3);
267 check_index_range(g_repo, "a", "z", true, 4);
268}
269
270static const char *expected_index_cs[] = {
271 "B", "D", "F", "H", "J", "L/1", "L/B", "L/D", "L/a", "L/c",
272 "a", "c", "e", "g", "i", "k/1", "k/B", "k/D", "k/a", "k/c",
273};
274
275static const char *expected_index_ci[] = {
276 "a", "B", "c", "D", "e", "F", "g", "H", "i", "J",
277 "k/1", "k/a", "k/B", "k/c", "k/D", "L/1", "L/a", "L/B", "L/c", "L/D",
278};
279
280void test_iterator_index__case_folding(void)
281{
282 git_buf path = GIT_BUF_INIT;
283 int fs_is_ci = 0;
284
285 cl_git_pass(git_buf_joinpath(&path, cl_fixture("icase"), ".gitted/CoNfIg"));
286 fs_is_ci = git_path_exists(path.ptr);
287 git_buf_free(&path);
288
289 index_iterator_test(
290 "icase", NULL, NULL, 0, ARRAY_SIZE(expected_index_cs),
291 fs_is_ci ? expected_index_ci : expected_index_cs, NULL);
292
293 cl_git_sandbox_cleanup();
294
295 index_iterator_test(
296 "icase", NULL, NULL, GIT_ITERATOR_IGNORE_CASE,
297 ARRAY_SIZE(expected_index_ci), expected_index_ci, NULL);
298
299 cl_git_sandbox_cleanup();
300
301 index_iterator_test(
302 "icase", NULL, NULL, GIT_ITERATOR_DONT_IGNORE_CASE,
303 ARRAY_SIZE(expected_index_cs), expected_index_cs, NULL);
304}
305
306/* Index contents (including pseudotrees):
307 *
308 * 0: a 5: F 10: k/ 16: L/
309 * 1: B 6: g 11: k/1 17: L/1
310 * 2: c 7: H 12: k/a 18: L/a
311 * 3: D 8: i 13: k/B 19: L/B
312 * 4: e 9: J 14: k/c 20: L/c
313 * 15: k/D 21: L/D
314 *
315 * 0: B 5: L/ 11: a 16: k/
316 * 1: D 6: L/1 12: c 17: k/1
317 * 2: F 7: L/B 13: e 18: k/B
318 * 3: H 8: L/D 14: g 19: k/D
319 * 4: J 9: L/a 15: i 20: k/a
320 * 10: L/c 21: k/c
321 */
322
323void test_iterator_index__icase_0(void)
324{
325 git_iterator *i;
326 git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
327 git_index *index;
328
329 g_repo = cl_git_sandbox_init("icase");
330
331 cl_git_pass(git_repository_index(&index, g_repo));
332
333 /* autoexpand with no tree entries for index */
334 cl_git_pass(git_iterator_for_index(&i, g_repo, index, NULL));
335 expect_iterator_items(i, 20, NULL, 20, NULL);
336 git_iterator_free(i);
337
338 /* auto expand with tree entries */
339 i_opts.flags = GIT_ITERATOR_INCLUDE_TREES;
340 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
341 expect_iterator_items(i, 22, NULL, 22, NULL);
342 git_iterator_free(i);
343
344 /* no auto expand (implies trees included) */
345 i_opts.flags = GIT_ITERATOR_DONT_AUTOEXPAND;
346 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
347 expect_iterator_items(i, 12, NULL, 22, NULL);
348 git_iterator_free(i);
349
350 git_index_free(index);
351}
352
353void test_iterator_index__icase_1(void)
354{
355 git_iterator *i;
356 git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
357 git_index *index;
358 int caps;
359
360 g_repo = cl_git_sandbox_init("icase");
361
362 cl_git_pass(git_repository_index(&index, g_repo));
363 caps = git_index_caps(index);
364
365 /* force case sensitivity */
366 cl_git_pass(git_index_set_caps(index, caps & ~GIT_INDEXCAP_IGNORE_CASE));
367
368 /* autoexpand with no tree entries over range */
369 i_opts.start = "c";
370 i_opts.end = "k/D";
371 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
372 expect_iterator_items(i, 7, NULL, 7, NULL);
373 git_iterator_free(i);
374
375 i_opts.start = "k";
376 i_opts.end = "k/Z";
377 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
378 expect_iterator_items(i, 3, NULL, 3, NULL);
379 git_iterator_free(i);
380
381 /* auto expand with tree entries */
382 i_opts.flags = GIT_ITERATOR_INCLUDE_TREES;
383
384 i_opts.start = "c";
385 i_opts.end = "k/D";
386 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
387 expect_iterator_items(i, 8, NULL, 8, NULL);
388 git_iterator_free(i);
389
390 i_opts.start = "k";
391 i_opts.end = "k/Z";
392 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
393 expect_iterator_items(i, 4, NULL, 4, NULL);
394 git_iterator_free(i);
395
396 /* no auto expand (implies trees included) */
397 i_opts.flags = GIT_ITERATOR_DONT_AUTOEXPAND;
398
399 i_opts.start = "c";
400 i_opts.end = "k/D";
401 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
402 expect_iterator_items(i, 5, NULL, 8, NULL);
403 git_iterator_free(i);
404
405 i_opts.start = "k";
406 i_opts.end = "k/Z";
407 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
408 expect_iterator_items(i, 1, NULL, 4, NULL);
409 git_iterator_free(i);
410
411 /* force case insensitivity */
412 cl_git_pass(git_index_set_caps(index, caps | GIT_INDEXCAP_IGNORE_CASE));
413
414 /* autoexpand with no tree entries over range */
415 i_opts.flags = 0;
416
417 i_opts.start = "c";
418 i_opts.end = "k/D";
419 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
420 expect_iterator_items(i, 13, NULL, 13, NULL);
421 git_iterator_free(i);
422
423 i_opts.start = "k";
424 i_opts.end = "k/Z";
425 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
426 expect_iterator_items(i, 5, NULL, 5, NULL);
427 git_iterator_free(i);
428
429 /* auto expand with tree entries */
430 i_opts.flags = GIT_ITERATOR_INCLUDE_TREES;
431
432 i_opts.start = "c";
433 i_opts.end = "k/D";
434 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
435 expect_iterator_items(i, 14, NULL, 14, NULL);
436 git_iterator_free(i);
437
438 i_opts.start = "k";
439 i_opts.end = "k/Z";
440 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
441 expect_iterator_items(i, 6, NULL, 6, NULL);
442 git_iterator_free(i);
443
444 /* no auto expand (implies trees included) */
445 i_opts.flags = GIT_ITERATOR_DONT_AUTOEXPAND;
446
447 i_opts.start = "c";
448 i_opts.end = "k/D";
449 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
450 expect_iterator_items(i, 9, NULL, 14, NULL);
451 git_iterator_free(i);
452
453 i_opts.start = "k";
454 i_opts.end = "k/Z";
455 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
456 expect_iterator_items(i, 1, NULL, 6, NULL);
457 git_iterator_free(i);
458
459 cl_git_pass(git_index_set_caps(index, caps));
460 git_index_free(index);
461}
462
463void test_iterator_index__pathlist(void)
464{
465 git_iterator *i;
466 git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
467 git_index *index;
468 git_vector filelist;
de034cd2
ET
469
470 cl_git_pass(git_vector_init(&filelist, 100, &git__strcmp_cb));
471 cl_git_pass(git_vector_insert(&filelist, "a"));
472 cl_git_pass(git_vector_insert(&filelist, "B"));
473 cl_git_pass(git_vector_insert(&filelist, "c"));
474 cl_git_pass(git_vector_insert(&filelist, "D"));
475 cl_git_pass(git_vector_insert(&filelist, "e"));
476 cl_git_pass(git_vector_insert(&filelist, "k/1"));
477 cl_git_pass(git_vector_insert(&filelist, "k/a"));
478 cl_git_pass(git_vector_insert(&filelist, "L/1"));
479
480 g_repo = cl_git_sandbox_init("icase");
481
482 cl_git_pass(git_repository_index(&index, g_repo));
483
de034cd2
ET
484 i_opts.pathlist.strings = (char **)filelist.contents;
485 i_opts.pathlist.count = filelist.length;
486
0ef0b71c
ET
487 /* Case sensitive */
488 {
489 const char *expected[] = {
490 "B", "D", "L/1", "a", "c", "e", "k/1", "k/a" };
491 size_t expected_len = 8;
de034cd2 492
0ef0b71c
ET
493 i_opts.start = NULL;
494 i_opts.end = NULL;
495 i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
de034cd2 496
0ef0b71c
ET
497 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
498 expect_iterator_items(i, expected_len, expected, expected_len, expected);
499 git_iterator_free(i);
500 }
de034cd2 501
0ef0b71c
ET
502 /* Case INsensitive */
503 {
504 const char *expected[] = {
505 "a", "B", "c", "D", "e", "k/1", "k/a", "L/1" };
506 size_t expected_len = 8;
de034cd2 507
0ef0b71c
ET
508 i_opts.start = NULL;
509 i_opts.end = NULL;
510 i_opts.flags = GIT_ITERATOR_IGNORE_CASE;
de034cd2 511
0ef0b71c
ET
512 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
513 expect_iterator_items(i, expected_len, expected, expected_len, expected);
514 git_iterator_free(i);
515 }
516
517 /* Set a start, but no end. Case sensitive. */
518 {
519 const char *expected[] = { "c", "e", "k/1", "k/a" };
520 size_t expected_len = 4;
521
522 i_opts.start = "c";
523 i_opts.end = NULL;
524 i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
525
526 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
527 expect_iterator_items(i, expected_len, expected, expected_len, expected);
528 git_iterator_free(i);
529 }
530
531 /* Set a start, but no end. Case INsensitive. */
532 {
533 const char *expected[] = { "c", "D", "e", "k/1", "k/a", "L/1" };
534 size_t expected_len = 6;
535
536 i_opts.start = "c";
537 i_opts.end = NULL;
538 i_opts.flags = GIT_ITERATOR_IGNORE_CASE;
539
540 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
541 expect_iterator_items(i, expected_len, expected, expected_len, expected);
542 git_iterator_free(i);
543 }
544
545 /* Set no start, but an end. Case sensitive. */
546 {
547 const char *expected[] = { "B", "D", "L/1", "a", "c", "e" };
548 size_t expected_len = 6;
549
550 i_opts.start = NULL;
551 i_opts.end = "e";
552 i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
553
554 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
555 expect_iterator_items(i, expected_len, expected, expected_len, expected);
556 git_iterator_free(i);
557 }
558
559 /* Set no start, but an end. Case INsensitive. */
560 {
561 const char *expected[] = { "a", "B", "c", "D", "e" };
562 size_t expected_len = 5;
563
564 i_opts.start = NULL;
565 i_opts.end = "e";
566 i_opts.flags = GIT_ITERATOR_IGNORE_CASE;
567
568 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
569 expect_iterator_items(i, expected_len, expected, expected_len, expected);
570 git_iterator_free(i);
571 }
572
573 /* Start and an end, case sensitive */
574 {
575 const char *expected[] = { "c", "e", "k/1" };
576 size_t expected_len = 3;
577
578 i_opts.start = "c";
579 i_opts.end = "k/D";
580 i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
581
582 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
583 expect_iterator_items(i, expected_len, expected, expected_len, expected);
584 git_iterator_free(i);
585 }
586
587 /* Start and an end, case sensitive */
588 {
589 const char *expected[] = { "k/1" };
590 size_t expected_len = 1;
591
592 i_opts.start = "k";
593 i_opts.end = "k/D";
594 i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
595
596 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
597 expect_iterator_items(i, expected_len, expected, expected_len, expected);
598 git_iterator_free(i);
599 }
600
601 /* Start and an end, case INsensitive */
602 {
603 const char *expected[] = { "c", "D", "e", "k/1", "k/a" };
604 size_t expected_len = 5;
605
606 i_opts.start = "c";
607 i_opts.end = "k/D";
608 i_opts.flags = GIT_ITERATOR_IGNORE_CASE;
609
610 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
611 expect_iterator_items(i, expected_len, expected, expected_len, expected);
612 git_iterator_free(i);
613 }
614
615 /* Start and an end, case INsensitive */
616 {
617 const char *expected[] = { "k/1", "k/a" };
618 size_t expected_len = 2;
619
620 i_opts.start = "k";
621 i_opts.end = "k/D";
622 i_opts.flags = GIT_ITERATOR_IGNORE_CASE;
623
624 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
625 expect_iterator_items(i, expected_len, expected, expected_len, expected);
626 git_iterator_free(i);
627 }
628
629 git_index_free(index);
630 git_vector_free(&filelist);
631}
632
633void test_iterator_index__pathlist_with_dirs(void)
634{
635 git_iterator *i;
636 git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
637 git_index *index;
638 git_vector filelist;
639
640 cl_git_pass(git_vector_init(&filelist, 5, NULL));
641
642 g_repo = cl_git_sandbox_init("icase");
643
644 cl_git_pass(git_repository_index(&index, g_repo));
645
646 /* Test that a prefix `k` matches folders, even without trailing slash */
647 {
648 const char *expected[] = { "k/1", "k/B", "k/D", "k/a", "k/c" };
649 size_t expected_len = 5;
650
651 git_vector_clear(&filelist);
652 cl_git_pass(git_vector_insert(&filelist, "k"));
653
654 i_opts.pathlist.strings = (char **)filelist.contents;
655 i_opts.pathlist.count = filelist.length;
656 i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
657
658 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
659 expect_iterator_items(i, expected_len, expected, expected_len, expected);
660 git_iterator_free(i);
661 }
662
663 /* Test that a `k/` matches a folder */
664 {
665 const char *expected[] = { "k/1", "k/B", "k/D", "k/a", "k/c" };
666 size_t expected_len = 5;
667
668 git_vector_clear(&filelist);
669 cl_git_pass(git_vector_insert(&filelist, "k/"));
670
671 i_opts.pathlist.strings = (char **)filelist.contents;
672 i_opts.pathlist.count = filelist.length;
673 i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
674
675 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
676 expect_iterator_items(i, expected_len, expected, expected_len, expected);
677 git_iterator_free(i);
678 }
679
680 /* When the iterator is case sensitive, ensure we can't lookup the
681 * directory with the wrong case.
682 */
683 {
684 git_vector_clear(&filelist);
685 cl_git_pass(git_vector_insert(&filelist, "K/"));
686
687 i_opts.pathlist.strings = (char **)filelist.contents;
688 i_opts.pathlist.count = filelist.length;
689 i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
690
691 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
692 cl_git_fail_with(GIT_ITEROVER, git_iterator_advance(NULL, i));
693 git_iterator_free(i);
694 }
695
696 /* Test that case insensitive matching works. */
697 {
698 const char *expected[] = { "k/1", "k/a", "k/B", "k/c", "k/D" };
699 size_t expected_len = 5;
700
701 git_vector_clear(&filelist);
702 cl_git_pass(git_vector_insert(&filelist, "K/"));
703
704 i_opts.pathlist.strings = (char **)filelist.contents;
705 i_opts.pathlist.count = filelist.length;
706 i_opts.flags = GIT_ITERATOR_IGNORE_CASE;
707
708 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
709 expect_iterator_items(i, expected_len, expected, expected_len, expected);
710 git_iterator_free(i);
711 }
712
713 /* Test that case insensitive matching works without trailing slash. */
714 {
715 const char *expected[] = { "k/1", "k/a", "k/B", "k/c", "k/D" };
716 size_t expected_len = 5;
717
718 git_vector_clear(&filelist);
719 cl_git_pass(git_vector_insert(&filelist, "K"));
720
721 i_opts.pathlist.strings = (char **)filelist.contents;
722 i_opts.pathlist.count = filelist.length;
723 i_opts.flags = GIT_ITERATOR_IGNORE_CASE;
724
725 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
726 expect_iterator_items(i, expected_len, expected, expected_len, expected);
727 git_iterator_free(i);
728 }
de034cd2
ET
729
730 git_index_free(index);
09064f15
MS
731 git_vector_free(&filelist);
732}
733
734void test_iterator_index__pathlist_with_dirs_include_trees(void)
735{
736 git_iterator *i;
737 git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
738 git_index *index;
739 git_vector filelist;
740
741 const char *expected[] = { "k/", "k/1", "k/B", "k/D", "k/a", "k/c" };
742 size_t expected_len = 6;
743
744 cl_git_pass(git_vector_init(&filelist, 5, NULL));
745
746 g_repo = cl_git_sandbox_init("icase");
747
748 cl_git_pass(git_repository_index(&index, g_repo));
749
750 git_vector_clear(&filelist);
751 cl_git_pass(git_vector_insert(&filelist, "k"));
752
753 i_opts.pathlist.strings = (char **)filelist.contents;
754 i_opts.pathlist.count = filelist.length;
755 i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE | GIT_ITERATOR_INCLUDE_TREES;
756
757 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
758 expect_iterator_items(i, expected_len, expected, expected_len, expected);
759 git_iterator_free(i);
760
761 git_index_free(index);
de034cd2
ET
762 git_vector_free(&filelist);
763}
764
765void test_iterator_index__pathlist_1(void)
766{
767 git_iterator *i;
768 git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
769 git_index *index;
770 git_vector filelist = GIT_VECTOR_INIT;
771 int default_icase, expect;
772
773 g_repo = cl_git_sandbox_init("icase");
774
775 cl_git_pass(git_repository_index(&index, g_repo));
776
777 cl_git_pass(git_vector_init(&filelist, 100, &git__strcmp_cb));
778 cl_git_pass(git_vector_insert(&filelist, "0"));
779 cl_git_pass(git_vector_insert(&filelist, "c"));
780 cl_git_pass(git_vector_insert(&filelist, "D"));
781 cl_git_pass(git_vector_insert(&filelist, "e"));
782 cl_git_pass(git_vector_insert(&filelist, "k/1"));
783 cl_git_pass(git_vector_insert(&filelist, "k/a"));
784
785 /* In this test we DO NOT force a case setting on the index. */
786 default_icase = ((git_index_caps(index) & GIT_INDEXCAP_IGNORE_CASE) != 0);
787
788 i_opts.pathlist.strings = (char **)filelist.contents;
789 i_opts.pathlist.count = filelist.length;
790
791 i_opts.start = "b";
792 i_opts.end = "k/D";
793
794 /* (c D e k/1 k/a ==> 5) vs (c e k/1 ==> 3) */
795 expect = default_icase ? 5 : 3;
796
797 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
798 expect_iterator_items(i, expect, NULL, expect, NULL);
799 git_iterator_free(i);
800
801 git_index_free(index);
802 git_vector_free(&filelist);
803}
804
805void test_iterator_index__pathlist_2(void)
806{
807 git_iterator *i;
808 git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
809 git_index *index;
810 git_vector filelist = GIT_VECTOR_INIT;
811 int default_icase, expect;
812
813 g_repo = cl_git_sandbox_init("icase");
814
815 cl_git_pass(git_repository_index(&index, g_repo));
816
817 cl_git_pass(git_vector_init(&filelist, 100, &git__strcmp_cb));
818 cl_git_pass(git_vector_insert(&filelist, "0"));
819 cl_git_pass(git_vector_insert(&filelist, "c"));
820 cl_git_pass(git_vector_insert(&filelist, "D"));
821 cl_git_pass(git_vector_insert(&filelist, "e"));
822 cl_git_pass(git_vector_insert(&filelist, "k/"));
823 cl_git_pass(git_vector_insert(&filelist, "k.a"));
824 cl_git_pass(git_vector_insert(&filelist, "k.b"));
825 cl_git_pass(git_vector_insert(&filelist, "kZZZZZZZ"));
826
827 /* In this test we DO NOT force a case setting on the index. */
828 default_icase = ((git_index_caps(index) & GIT_INDEXCAP_IGNORE_CASE) != 0);
829
830 i_opts.pathlist.strings = (char **)filelist.contents;
831 i_opts.pathlist.count = filelist.length;
832
833 i_opts.start = "b";
834 i_opts.end = "k/D";
835
836 /* (c D e k/1 k/a k/B k/c k/D) vs (c e k/1 k/B k/D) */
837 expect = default_icase ? 8 : 5;
838
839 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
840 expect_iterator_items(i, expect, NULL, expect, NULL);
841 git_iterator_free(i);
842
843 git_index_free(index);
844 git_vector_free(&filelist);
845}
846
847void test_iterator_index__pathlist_four(void)
848{
849 git_iterator *i;
850 git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
851 git_index *index;
852 git_vector filelist = GIT_VECTOR_INIT;
853 int default_icase, expect;
854
855 g_repo = cl_git_sandbox_init("icase");
856
857 cl_git_pass(git_repository_index(&index, g_repo));
858
859 cl_git_pass(git_vector_init(&filelist, 100, &git__strcmp_cb));
860 cl_git_pass(git_vector_insert(&filelist, "0"));
861 cl_git_pass(git_vector_insert(&filelist, "c"));
862 cl_git_pass(git_vector_insert(&filelist, "D"));
863 cl_git_pass(git_vector_insert(&filelist, "e"));
864 cl_git_pass(git_vector_insert(&filelist, "k"));
865 cl_git_pass(git_vector_insert(&filelist, "k.a"));
866 cl_git_pass(git_vector_insert(&filelist, "k.b"));
867 cl_git_pass(git_vector_insert(&filelist, "kZZZZZZZ"));
868
869 /* In this test we DO NOT force a case setting on the index. */
870 default_icase = ((git_index_caps(index) & GIT_INDEXCAP_IGNORE_CASE) != 0);
871
872 i_opts.pathlist.strings = (char **)filelist.contents;
873 i_opts.pathlist.count = filelist.length;
874
875 i_opts.start = "b";
876 i_opts.end = "k/D";
877
878 /* (c D e k/1 k/a k/B k/c k/D) vs (c e k/1 k/B k/D) */
879 expect = default_icase ? 8 : 5;
880
881 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
882 expect_iterator_items(i, expect, NULL, expect, NULL);
883 git_iterator_free(i);
884
885 git_index_free(index);
886 git_vector_free(&filelist);
887}
888
889void test_iterator_index__pathlist_icase(void)
890{
891 git_iterator *i;
892 git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
893 git_index *index;
894 int caps;
895 git_vector filelist;
896
897 cl_git_pass(git_vector_init(&filelist, 100, &git__strcmp_cb));
898 cl_git_pass(git_vector_insert(&filelist, "a"));
899 cl_git_pass(git_vector_insert(&filelist, "B"));
900 cl_git_pass(git_vector_insert(&filelist, "c"));
901 cl_git_pass(git_vector_insert(&filelist, "D"));
902 cl_git_pass(git_vector_insert(&filelist, "e"));
903 cl_git_pass(git_vector_insert(&filelist, "k/1"));
904 cl_git_pass(git_vector_insert(&filelist, "k/a"));
905 cl_git_pass(git_vector_insert(&filelist, "L/1"));
906
907 g_repo = cl_git_sandbox_init("icase");
908
909 cl_git_pass(git_repository_index(&index, g_repo));
910 caps = git_index_caps(index);
911
912 /* force case sensitivity */
913 cl_git_pass(git_index_set_caps(index, caps & ~GIT_INDEXCAP_IGNORE_CASE));
914
915 /* All indexfilelist iterator tests are "autoexpand with no tree entries" */
916
917 i_opts.pathlist.strings = (char **)filelist.contents;
918 i_opts.pathlist.count = filelist.length;
919
920 i_opts.start = "c";
921 i_opts.end = "k/D";
922 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
923 expect_iterator_items(i, 3, NULL, 3, NULL);
924 git_iterator_free(i);
925
926 i_opts.start = "k";
927 i_opts.end = "k/Z";
928 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
929 expect_iterator_items(i, 1, NULL, 1, NULL);
930 git_iterator_free(i);
931
932 /* force case insensitivity */
933 cl_git_pass(git_index_set_caps(index, caps | GIT_INDEXCAP_IGNORE_CASE));
934
935 i_opts.start = "c";
936 i_opts.end = "k/D";
937 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
938 expect_iterator_items(i, 5, NULL, 5, NULL);
939 git_iterator_free(i);
940
941 i_opts.start = "k";
942 i_opts.end = "k/Z";
943 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
944 expect_iterator_items(i, 2, NULL, 2, NULL);
945 git_iterator_free(i);
946
947 cl_git_pass(git_index_set_caps(index, caps));
948 git_index_free(index);
949 git_vector_free(&filelist);
950}
951
952void test_iterator_index__pathlist_with_directory(void)
953{
954 git_iterator *i;
955 git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
956 git_vector filelist;
957 git_tree *tree;
958 git_index *index;
959
960 g_repo = cl_git_sandbox_init("testrepo2");
961 git_repository_head_tree(&tree, g_repo);
962
963 cl_git_pass(git_vector_init(&filelist, 100, &git__strcmp_cb));
964 cl_git_pass(git_vector_insert(&filelist, "subdir"));
965
966 i_opts.pathlist.strings = (char **)filelist.contents;
967 i_opts.pathlist.count = filelist.length;
968
969 cl_git_pass(git_repository_index(&index, g_repo));
970 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
971 expect_iterator_items(i, 4, NULL, 4, NULL);
972 git_iterator_free(i);
973 git_index_free(index);
974 git_vector_free(&filelist);
975}
976
0ef0b71c
ET
977static void create_paths(git_index *index, const char *root, int depth)
978{
979 git_buf fullpath = GIT_BUF_INIT;
980 git_index_entry entry;
981 size_t root_len;
982 int i;
983
984 if (root) {
985 cl_git_pass(git_buf_puts(&fullpath, root));
986 cl_git_pass(git_buf_putc(&fullpath, '/'));
987 }
988
989 root_len = fullpath.size;
990
991 for (i = 0; i < 8; i++) {
992 bool file = (depth == 0 || (i % 2) == 0);
993 git_buf_truncate(&fullpath, root_len);
994 cl_git_pass(git_buf_printf(&fullpath, "item%d", i));
995
996 if (file) {
997 memset(&entry, 0, sizeof(git_index_entry));
998 entry.path = fullpath.ptr;
999 entry.mode = GIT_FILEMODE_BLOB;
1000 git_oid_fromstr(&entry.id, "d44e18fb93b7107b5cd1b95d601591d77869a1b6");
1001
1002 cl_git_pass(git_index_add(index, &entry));
1003 } else if (depth > 0) {
1004 create_paths(index, fullpath.ptr, (depth - 1));
1005 }
1006 }
1007
1008 git_buf_free(&fullpath);
1009}
1010
1011void test_iterator_index__pathlist_for_deeply_nested_item(void)
1012{
1013 git_iterator *i;
1014 git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
1015 git_index *index;
1016 git_vector filelist;
1017
1018 cl_git_pass(git_vector_init(&filelist, 5, NULL));
1019
1020 g_repo = cl_git_sandbox_init("icase");
1021 cl_git_pass(git_repository_index(&index, g_repo));
1022
1023 create_paths(index, NULL, 3);
1024
1025 /* Ensure that we find the single path we're interested in */
1026 {
1027 const char *expected[] = { "item1/item3/item5/item7" };
1028 size_t expected_len = 1;
1029
1030 git_vector_clear(&filelist);
1031 cl_git_pass(git_vector_insert(&filelist, "item1/item3/item5/item7"));
1032
1033 i_opts.pathlist.strings = (char **)filelist.contents;
1034 i_opts.pathlist.count = filelist.length;
1035 i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
1036
1037 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
1038 expect_iterator_items(i, expected_len, expected, expected_len, expected);
1039 git_iterator_free(i);
1040 }
1041
1042 {
1043 const char *expected[] = {
1044 "item1/item3/item5/item0", "item1/item3/item5/item1",
1045 "item1/item3/item5/item2", "item1/item3/item5/item3",
1046 "item1/item3/item5/item4", "item1/item3/item5/item5",
1047 "item1/item3/item5/item6", "item1/item3/item5/item7",
1048 };
1049 size_t expected_len = 8;
1050
1051 git_vector_clear(&filelist);
1052 cl_git_pass(git_vector_insert(&filelist, "item1/item3/item5/"));
1053
1054 i_opts.pathlist.strings = (char **)filelist.contents;
1055 i_opts.pathlist.count = filelist.length;
1056 i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
1057
1058 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
1059 expect_iterator_items(i, expected_len, expected, expected_len, expected);
1060 git_iterator_free(i);
1061 }
1062
1063 {
1064 const char *expected[] = {
1065 "item1/item3/item0",
1066 "item1/item3/item1/item0", "item1/item3/item1/item1",
1067 "item1/item3/item1/item2", "item1/item3/item1/item3",
1068 "item1/item3/item1/item4", "item1/item3/item1/item5",
1069 "item1/item3/item1/item6", "item1/item3/item1/item7",
1070 "item1/item3/item2",
1071 "item1/item3/item3/item0", "item1/item3/item3/item1",
1072 "item1/item3/item3/item2", "item1/item3/item3/item3",
1073 "item1/item3/item3/item4", "item1/item3/item3/item5",
1074 "item1/item3/item3/item6", "item1/item3/item3/item7",
1075 "item1/item3/item4",
1076 "item1/item3/item5/item0", "item1/item3/item5/item1",
1077 "item1/item3/item5/item2", "item1/item3/item5/item3",
1078 "item1/item3/item5/item4", "item1/item3/item5/item5",
1079 "item1/item3/item5/item6", "item1/item3/item5/item7",
1080 "item1/item3/item6",
1081 "item1/item3/item7/item0", "item1/item3/item7/item1",
1082 "item1/item3/item7/item2", "item1/item3/item7/item3",
1083 "item1/item3/item7/item4", "item1/item3/item7/item5",
1084 "item1/item3/item7/item6", "item1/item3/item7/item7",
1085 };
1086 size_t expected_len = 36;
1087
1088 git_vector_clear(&filelist);
1089 cl_git_pass(git_vector_insert(&filelist, "item1/item3/"));
1090
1091 i_opts.pathlist.strings = (char **)filelist.contents;
1092 i_opts.pathlist.count = filelist.length;
1093 i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
1094
1095 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
1096 expect_iterator_items(i, expected_len, expected, expected_len, expected);
1097 git_iterator_free(i);
1098 }
1099
1100 /* Ensure that we find the single path we're interested in, and we find
1101 * it efficiently, and don't stat the entire world to get there.
1102 */
1103 {
1104 const char *expected[] = {
1105 "item0", "item1/item2", "item5/item7/item4", "item6",
1106 "item7/item3/item1/item6" };
1107 size_t expected_len = 5;
1108
1109 git_vector_clear(&filelist);
1110 cl_git_pass(git_vector_insert(&filelist, "item7/item3/item1/item6"));
1111 cl_git_pass(git_vector_insert(&filelist, "item6"));
1112 cl_git_pass(git_vector_insert(&filelist, "item5/item7/item4"));
1113 cl_git_pass(git_vector_insert(&filelist, "item1/item2"));
1114 cl_git_pass(git_vector_insert(&filelist, "item0"));
1115
1116 /* also add some things that don't exist or don't match the right type */
1117 cl_git_pass(git_vector_insert(&filelist, "item2/"));
1118 cl_git_pass(git_vector_insert(&filelist, "itemN"));
1119 cl_git_pass(git_vector_insert(&filelist, "item1/itemA"));
1120 cl_git_pass(git_vector_insert(&filelist, "item5/item3/item4/"));
1121
1122 i_opts.pathlist.strings = (char **)filelist.contents;
1123 i_opts.pathlist.count = filelist.length;
1124 i_opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
1125
1126 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
1127 expect_iterator_items(i, expected_len, expected, expected_len, expected);
1128 git_iterator_free(i);
1129 }
1130
1131 git_index_free(index);
1132 git_vector_free(&filelist);
1133}
1134
1135void test_iterator_index__advance_over(void)
1136{
1137 git_iterator *i;
1138 git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
1139 git_index *index;
1140
1141 i_opts.flags |= GIT_ITERATOR_DONT_IGNORE_CASE |
1142 GIT_ITERATOR_DONT_AUTOEXPAND;
1143
1144 g_repo = cl_git_sandbox_init("icase");
1145 cl_git_pass(git_repository_index(&index, g_repo));
1146
1147 create_paths(index, NULL, 1);
1148
1149 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
1150
1151 expect_advance_over(i, "B", GIT_ITERATOR_STATUS_NORMAL);
1152 expect_advance_over(i, "D", GIT_ITERATOR_STATUS_NORMAL);
1153 expect_advance_over(i, "F", GIT_ITERATOR_STATUS_NORMAL);
1154 expect_advance_over(i, "H", GIT_ITERATOR_STATUS_NORMAL);
1155 expect_advance_over(i, "J", GIT_ITERATOR_STATUS_NORMAL);
1156 expect_advance_over(i, "L/", GIT_ITERATOR_STATUS_NORMAL);
1157 expect_advance_over(i, "a", GIT_ITERATOR_STATUS_NORMAL);
1158 expect_advance_over(i, "c", GIT_ITERATOR_STATUS_NORMAL);
1159 expect_advance_over(i, "e", GIT_ITERATOR_STATUS_NORMAL);
1160 expect_advance_over(i, "g", GIT_ITERATOR_STATUS_NORMAL);
1161 expect_advance_over(i, "i", GIT_ITERATOR_STATUS_NORMAL);
1162 expect_advance_over(i, "item0", GIT_ITERATOR_STATUS_NORMAL);
1163 expect_advance_over(i, "item1/", GIT_ITERATOR_STATUS_NORMAL);
1164 expect_advance_over(i, "item2", GIT_ITERATOR_STATUS_NORMAL);
1165 expect_advance_over(i, "item3/", GIT_ITERATOR_STATUS_NORMAL);
1166 expect_advance_over(i, "item4", GIT_ITERATOR_STATUS_NORMAL);
1167 expect_advance_over(i, "item5/", GIT_ITERATOR_STATUS_NORMAL);
1168 expect_advance_over(i, "item6", GIT_ITERATOR_STATUS_NORMAL);
1169 expect_advance_over(i, "item7/", GIT_ITERATOR_STATUS_NORMAL);
1170 expect_advance_over(i, "k/", GIT_ITERATOR_STATUS_NORMAL);
1171
1172 cl_git_fail_with(GIT_ITEROVER, git_iterator_advance(NULL, i));
1173 git_iterator_free(i);
1174 git_index_free(index);
1175}
1176
1177void test_iterator_index__advance_into(void)
1178{
1179 git_iterator *i;
1180 git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
1181 git_index *index;
1182
1183 g_repo = cl_git_sandbox_init("icase");
1184
1185 i_opts.flags |= GIT_ITERATOR_DONT_IGNORE_CASE |
1186 GIT_ITERATOR_DONT_AUTOEXPAND;
1187
1188 cl_git_pass(git_repository_index(&index, g_repo));
1189
1190 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
1191 expect_advance_into(i, "B");
1192 expect_advance_into(i, "D");
1193 expect_advance_into(i, "F");
1194 expect_advance_into(i, "H");
1195 expect_advance_into(i, "J");
1196 expect_advance_into(i, "L/");
1197 expect_advance_into(i, "L/1");
1198 expect_advance_into(i, "L/B");
1199 expect_advance_into(i, "L/D");
1200 expect_advance_into(i, "L/a");
1201 expect_advance_into(i, "L/c");
1202 expect_advance_into(i, "a");
1203 expect_advance_into(i, "c");
1204 expect_advance_into(i, "e");
1205 expect_advance_into(i, "g");
1206 expect_advance_into(i, "i");
1207 expect_advance_into(i, "k/");
1208 expect_advance_into(i, "k/1");
1209 expect_advance_into(i, "k/B");
1210 expect_advance_into(i, "k/D");
1211 expect_advance_into(i, "k/a");
1212 expect_advance_into(i, "k/c");
1213
1214 cl_git_fail_with(GIT_ITEROVER, git_iterator_advance(NULL, i));
1215 git_iterator_free(i);
1216 git_index_free(index);
1217}
1218
1219void test_iterator_index__advance_into_and_over(void)
1220{
1221 git_iterator *i;
1222 git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
1223 git_index *index;
1224
1225 g_repo = cl_git_sandbox_init("icase");
1226
1227 i_opts.flags |= GIT_ITERATOR_DONT_IGNORE_CASE |
1228 GIT_ITERATOR_DONT_AUTOEXPAND;
1229
1230 cl_git_pass(git_repository_index(&index, g_repo));
1231
1232 create_paths(index, NULL, 2);
1233
1234 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
1235 expect_advance_into(i, "B");
1236 expect_advance_into(i, "D");
1237 expect_advance_into(i, "F");
1238 expect_advance_into(i, "H");
1239 expect_advance_into(i, "J");
1240 expect_advance_into(i, "L/");
1241 expect_advance_into(i, "L/1");
1242 expect_advance_into(i, "L/B");
1243 expect_advance_into(i, "L/D");
1244 expect_advance_into(i, "L/a");
1245 expect_advance_into(i, "L/c");
1246 expect_advance_into(i, "a");
1247 expect_advance_into(i, "c");
1248 expect_advance_into(i, "e");
1249 expect_advance_into(i, "g");
1250 expect_advance_into(i, "i");
1251 expect_advance_into(i, "item0");
1252 expect_advance_into(i, "item1/");
1253 expect_advance_into(i, "item1/item0");
1254 expect_advance_into(i, "item1/item1/");
1255 expect_advance_into(i, "item1/item1/item0");
1256 expect_advance_into(i, "item1/item1/item1");
1257 expect_advance_into(i, "item1/item1/item2");
1258 expect_advance_into(i, "item1/item1/item3");
1259 expect_advance_into(i, "item1/item1/item4");
1260 expect_advance_into(i, "item1/item1/item5");
1261 expect_advance_into(i, "item1/item1/item6");
1262 expect_advance_into(i, "item1/item1/item7");
1263 expect_advance_into(i, "item1/item2");
1264 expect_advance_over(i, "item1/item3/", GIT_ITERATOR_STATUS_NORMAL);
1265 expect_advance_over(i, "item1/item4", GIT_ITERATOR_STATUS_NORMAL);
1266 expect_advance_over(i, "item1/item5/", GIT_ITERATOR_STATUS_NORMAL);
1267 expect_advance_over(i, "item1/item6", GIT_ITERATOR_STATUS_NORMAL);
1268 expect_advance_over(i, "item1/item7/", GIT_ITERATOR_STATUS_NORMAL);
1269 expect_advance_into(i, "item2");
1270 expect_advance_over(i, "item3/", GIT_ITERATOR_STATUS_NORMAL);
1271 expect_advance_over(i, "item4", GIT_ITERATOR_STATUS_NORMAL);
1272 expect_advance_over(i, "item5/", GIT_ITERATOR_STATUS_NORMAL);
1273 expect_advance_over(i, "item6", GIT_ITERATOR_STATUS_NORMAL);
1274 expect_advance_over(i, "item7/", GIT_ITERATOR_STATUS_NORMAL);
1275 expect_advance_into(i, "k/");
1276 expect_advance_into(i, "k/1");
1277 expect_advance_into(i, "k/B");
1278 expect_advance_into(i, "k/D");
1279 expect_advance_into(i, "k/a");
1280 expect_advance_into(i, "k/c");
1281
1282 cl_git_fail_with(GIT_ITEROVER, git_iterator_advance(NULL, i));
1283 git_iterator_free(i);
1284 git_index_free(index);
1285}
1286
1287static void add_conflict(
1288 git_index *index,
1289 const char *ancestor_path,
1290 const char *our_path,
1291 const char *their_path)
1292{
1293 git_index_entry ancestor = {{0}}, ours = {{0}}, theirs = {{0}};
1294
1295 ancestor.path = ancestor_path;
1296 ancestor.mode = GIT_FILEMODE_BLOB;
1297 git_oid_fromstr(&ancestor.id, "d44e18fb93b7107b5cd1b95d601591d77869a1b6");
1298 GIT_IDXENTRY_STAGE_SET(&ancestor, 1);
1299
1300 ours.path = our_path;
1301 ours.mode = GIT_FILEMODE_BLOB;
1302 git_oid_fromstr(&ours.id, "d44e18fb93b7107b5cd1b95d601591d77869a1b6");
1303 GIT_IDXENTRY_STAGE_SET(&ours, 2);
1304
1305 theirs.path = their_path;
1306 theirs.mode = GIT_FILEMODE_BLOB;
1307 git_oid_fromstr(&theirs.id, "d44e18fb93b7107b5cd1b95d601591d77869a1b6");
1308 GIT_IDXENTRY_STAGE_SET(&theirs, 3);
1309
1310 cl_git_pass(git_index_conflict_add(index, &ancestor, &ours, &theirs));
1311}
1312
1313void test_iterator_index__include_conflicts(void)
1314{
1315 git_iterator *i;
1316 git_iterator_options i_opts = GIT_ITERATOR_OPTIONS_INIT;
1317 git_index *index;
1318
1319 i_opts.flags |= GIT_ITERATOR_DONT_IGNORE_CASE |
1320 GIT_ITERATOR_DONT_AUTOEXPAND;
1321
1322 g_repo = cl_git_sandbox_init("icase");
1323 cl_git_pass(git_repository_index(&index, g_repo));
1324
1325 add_conflict(index, "CONFLICT1", "CONFLICT1" ,"CONFLICT1");
1326 add_conflict(index, "ZZZ-CONFLICT2.ancestor", "ZZZ-CONFLICT2.ours", "ZZZ-CONFLICT2.theirs");
1327 add_conflict(index, "ancestor.conflict3", "ours.conflict3", "theirs.conflict3");
1328 add_conflict(index, "zzz-conflict4", "zzz-conflict4", "zzz-conflict4");
1329
1330 /* Iterate the index, ensuring that conflicts are not included */
1331 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
1332
1333 expect_advance_over(i, "B", GIT_ITERATOR_STATUS_NORMAL);
1334 expect_advance_over(i, "D", GIT_ITERATOR_STATUS_NORMAL);
1335 expect_advance_over(i, "F", GIT_ITERATOR_STATUS_NORMAL);
1336 expect_advance_over(i, "H", GIT_ITERATOR_STATUS_NORMAL);
1337 expect_advance_over(i, "J", GIT_ITERATOR_STATUS_NORMAL);
1338 expect_advance_over(i, "L/", GIT_ITERATOR_STATUS_NORMAL);
1339 expect_advance_over(i, "a", GIT_ITERATOR_STATUS_NORMAL);
1340 expect_advance_over(i, "c", GIT_ITERATOR_STATUS_NORMAL);
1341 expect_advance_over(i, "e", GIT_ITERATOR_STATUS_NORMAL);
1342 expect_advance_over(i, "g", GIT_ITERATOR_STATUS_NORMAL);
1343 expect_advance_over(i, "i", GIT_ITERATOR_STATUS_NORMAL);
1344 expect_advance_over(i, "k/", GIT_ITERATOR_STATUS_NORMAL);
1345
1346 cl_git_fail_with(GIT_ITEROVER, git_iterator_advance(NULL, i));
1347 git_iterator_free(i);
1348
1349 /* Try again, returning conflicts */
1350 i_opts.flags |= GIT_ITERATOR_INCLUDE_CONFLICTS;
1351
1352 cl_git_pass(git_iterator_for_index(&i, g_repo, index, &i_opts));
1353
1354 expect_advance_over(i, "B", GIT_ITERATOR_STATUS_NORMAL);
1355 expect_advance_over(i, "CONFLICT1", GIT_ITERATOR_STATUS_NORMAL);
1356 expect_advance_over(i, "CONFLICT1", GIT_ITERATOR_STATUS_NORMAL);
1357 expect_advance_over(i, "CONFLICT1", GIT_ITERATOR_STATUS_NORMAL);
1358 expect_advance_over(i, "D", GIT_ITERATOR_STATUS_NORMAL);
1359 expect_advance_over(i, "F", GIT_ITERATOR_STATUS_NORMAL);
1360 expect_advance_over(i, "H", GIT_ITERATOR_STATUS_NORMAL);
1361 expect_advance_over(i, "J", GIT_ITERATOR_STATUS_NORMAL);
1362 expect_advance_over(i, "L/", GIT_ITERATOR_STATUS_NORMAL);
1363 expect_advance_over(i, "ZZZ-CONFLICT2.ancestor", GIT_ITERATOR_STATUS_NORMAL);
1364 expect_advance_over(i, "ZZZ-CONFLICT2.ours", GIT_ITERATOR_STATUS_NORMAL);
1365 expect_advance_over(i, "ZZZ-CONFLICT2.theirs", GIT_ITERATOR_STATUS_NORMAL);
1366 expect_advance_over(i, "a", GIT_ITERATOR_STATUS_NORMAL);
1367 expect_advance_over(i, "ancestor.conflict3", GIT_ITERATOR_STATUS_NORMAL);
1368 expect_advance_over(i, "c", GIT_ITERATOR_STATUS_NORMAL);
1369 expect_advance_over(i, "e", GIT_ITERATOR_STATUS_NORMAL);
1370 expect_advance_over(i, "g", GIT_ITERATOR_STATUS_NORMAL);
1371 expect_advance_over(i, "i", GIT_ITERATOR_STATUS_NORMAL);
1372 expect_advance_over(i, "k/", GIT_ITERATOR_STATUS_NORMAL);
1373 expect_advance_over(i, "ours.conflict3", GIT_ITERATOR_STATUS_NORMAL);
1374 expect_advance_over(i, "theirs.conflict3", GIT_ITERATOR_STATUS_NORMAL);
1375 expect_advance_over(i, "zzz-conflict4", GIT_ITERATOR_STATUS_NORMAL);
1376 expect_advance_over(i, "zzz-conflict4", GIT_ITERATOR_STATUS_NORMAL);
1377 expect_advance_over(i, "zzz-conflict4", GIT_ITERATOR_STATUS_NORMAL);
1378
1379 cl_git_fail_with(GIT_ITEROVER, git_iterator_advance(NULL, i));
1380 git_iterator_free(i);
1381
1382 git_index_free(index);
1383}