1 #include "clar_libgit2.h"
3 #include "repository.h"
7 static git_repository
*g_repo
;
9 void test_repo_iterator__initialize(void)
13 void test_repo_iterator__cleanup(void)
15 cl_git_sandbox_cleanup();
19 static void expect_iterator_items(
22 const char **expected_flat_paths
,
24 const char **expected_total_paths
)
26 const git_index_entry
*entry
;
28 int no_trees
= !(git_iterator_flags(i
) & GIT_ITERATOR_INCLUDE_TREES
);
31 if (expected_flat
< 0) { v
= true; expected_flat
= -expected_flat
; }
32 if (expected_total
< 0) { v
= true; expected_total
= -expected_total
; }
34 if (v
) fprintf(stderr
, "== %s ==\n", no_trees
? "notrees" : "trees");
38 while (!git_iterator_advance(&entry
, i
)) {
39 if (v
) fprintf(stderr
, " %s %07o\n", entry
->path
, (int)entry
->mode
);
42 cl_assert(entry
->mode
!= GIT_FILEMODE_TREE
);
44 if (expected_flat_paths
) {
45 const char *expect_path
= expected_flat_paths
[count
];
46 size_t expect_len
= strlen(expect_path
);
48 cl_assert_equal_s(expect_path
, entry
->path
);
50 if (expect_path
[expect_len
- 1] == '/')
51 cl_assert_equal_i(GIT_FILEMODE_TREE
, entry
->mode
);
53 cl_assert(entry
->mode
!= GIT_FILEMODE_TREE
);
56 if (++count
> expected_flat
)
60 cl_assert_equal_i(expected_flat
, count
);
62 cl_git_pass(git_iterator_reset(i
, NULL
, NULL
));
65 cl_git_pass(git_iterator_current(&entry
, i
));
67 if (v
) fprintf(stderr
, "-- %s --\n", no_trees
? "notrees" : "trees");
69 while (entry
!= NULL
) {
70 if (v
) fprintf(stderr
, " %s %07o\n", entry
->path
, (int)entry
->mode
);
73 cl_assert(entry
->mode
!= GIT_FILEMODE_TREE
);
75 if (expected_total_paths
) {
76 const char *expect_path
= expected_total_paths
[count
];
77 size_t expect_len
= strlen(expect_path
);
79 cl_assert_equal_s(expect_path
, entry
->path
);
81 if (expect_path
[expect_len
- 1] == '/')
82 cl_assert_equal_i(GIT_FILEMODE_TREE
, entry
->mode
);
84 cl_assert(entry
->mode
!= GIT_FILEMODE_TREE
);
87 if (entry
->mode
== GIT_FILEMODE_TREE
) {
88 error
= git_iterator_advance_into(&entry
, i
);
90 /* could return NOTFOUND if directory is empty */
91 cl_assert(!error
|| error
== GIT_ENOTFOUND
);
93 if (error
== GIT_ENOTFOUND
) {
94 error
= git_iterator_advance(&entry
, i
);
95 cl_assert(!error
|| error
== GIT_ITEROVER
);
98 error
= git_iterator_advance(&entry
, i
);
99 cl_assert(!error
|| error
== GIT_ITEROVER
);
102 if (++count
> expected_total
)
106 cl_assert_equal_i(expected_total
, count
);
109 /* Index contents (including pseudotrees):
111 * 0: a 5: F 10: k/ 16: L/
112 * 1: B 6: g 11: k/1 17: L/1
113 * 2: c 7: H 12: k/a 18: L/a
114 * 3: D 8: i 13: k/B 19: L/B
115 * 4: e 9: J 14: k/c 20: L/c
118 * 0: B 5: L/ 11: a 16: k/
119 * 1: D 6: L/1 12: c 17: k/1
120 * 2: F 7: L/B 13: e 18: k/B
121 * 3: H 8: L/D 14: g 19: k/D
122 * 4: J 9: L/a 15: i 20: k/a
126 void test_repo_iterator__index(void)
131 g_repo
= cl_git_sandbox_init("icase");
133 cl_git_pass(git_repository_index(&index
, g_repo
));
135 /* autoexpand with no tree entries for index */
136 cl_git_pass(git_iterator_for_index(&i
, index
, 0, NULL
, NULL
));
137 expect_iterator_items(i
, 20, NULL
, 20, NULL
);
138 git_iterator_free(i
);
140 /* auto expand with tree entries */
141 cl_git_pass(git_iterator_for_index(
142 &i
, index
, GIT_ITERATOR_INCLUDE_TREES
, NULL
, NULL
));
143 expect_iterator_items(i
, 22, NULL
, 22, NULL
);
144 git_iterator_free(i
);
146 /* no auto expand (implies trees included) */
147 cl_git_pass(git_iterator_for_index(
148 &i
, index
, GIT_ITERATOR_DONT_AUTOEXPAND
, NULL
, NULL
));
149 expect_iterator_items(i
, 12, NULL
, 22, NULL
);
150 git_iterator_free(i
);
152 git_index_free(index
);
155 void test_repo_iterator__index_icase(void)
161 g_repo
= cl_git_sandbox_init("icase");
163 cl_git_pass(git_repository_index(&index
, g_repo
));
164 caps
= git_index_caps(index
);
166 /* force case sensitivity */
167 cl_git_pass(git_index_set_caps(index
, caps
& ~GIT_INDEXCAP_IGNORE_CASE
));
169 /* autoexpand with no tree entries over range */
170 cl_git_pass(git_iterator_for_index(&i
, index
, 0, "c", "k/D"));
171 expect_iterator_items(i
, 7, NULL
, 7, NULL
);
172 git_iterator_free(i
);
174 cl_git_pass(git_iterator_for_index(&i
, index
, 0, "k", "k/Z"));
175 expect_iterator_items(i
, 3, NULL
, 3, NULL
);
176 git_iterator_free(i
);
178 /* auto expand with tree entries */
179 cl_git_pass(git_iterator_for_index(
180 &i
, index
, GIT_ITERATOR_INCLUDE_TREES
, "c", "k/D"));
181 expect_iterator_items(i
, 8, NULL
, 8, NULL
);
182 git_iterator_free(i
);
183 cl_git_pass(git_iterator_for_index(
184 &i
, index
, GIT_ITERATOR_INCLUDE_TREES
, "k", "k/Z"));
185 expect_iterator_items(i
, 4, NULL
, 4, NULL
);
186 git_iterator_free(i
);
188 /* no auto expand (implies trees included) */
189 cl_git_pass(git_iterator_for_index(
190 &i
, index
, GIT_ITERATOR_DONT_AUTOEXPAND
, "c", "k/D"));
191 expect_iterator_items(i
, 5, NULL
, 8, NULL
);
192 git_iterator_free(i
);
194 cl_git_pass(git_iterator_for_index(
195 &i
, index
, GIT_ITERATOR_DONT_AUTOEXPAND
, "k", "k/Z"));
196 expect_iterator_items(i
, 1, NULL
, 4, NULL
);
197 git_iterator_free(i
);
199 /* force case insensitivity */
200 cl_git_pass(git_index_set_caps(index
, caps
| GIT_INDEXCAP_IGNORE_CASE
));
202 /* autoexpand with no tree entries over range */
203 cl_git_pass(git_iterator_for_index(&i
, index
, 0, "c", "k/D"));
204 expect_iterator_items(i
, 13, NULL
, 13, NULL
);
205 git_iterator_free(i
);
207 cl_git_pass(git_iterator_for_index(&i
, index
, 0, "k", "k/Z"));
208 expect_iterator_items(i
, 5, NULL
, 5, NULL
);
209 git_iterator_free(i
);
211 /* auto expand with tree entries */
212 cl_git_pass(git_iterator_for_index(
213 &i
, index
, GIT_ITERATOR_INCLUDE_TREES
, "c", "k/D"));
214 expect_iterator_items(i
, 14, NULL
, 14, NULL
);
215 git_iterator_free(i
);
217 cl_git_pass(git_iterator_for_index(
218 &i
, index
, GIT_ITERATOR_INCLUDE_TREES
, "k", "k/Z"));
219 expect_iterator_items(i
, 6, NULL
, 6, NULL
);
220 git_iterator_free(i
);
222 /* no auto expand (implies trees included) */
223 cl_git_pass(git_iterator_for_index(
224 &i
, index
, GIT_ITERATOR_DONT_AUTOEXPAND
, "c", "k/D"));
225 expect_iterator_items(i
, 9, NULL
, 14, NULL
);
226 git_iterator_free(i
);
228 cl_git_pass(git_iterator_for_index(
229 &i
, index
, GIT_ITERATOR_DONT_AUTOEXPAND
, "k", "k/Z"));
230 expect_iterator_items(i
, 1, NULL
, 6, NULL
);
231 git_iterator_free(i
);
233 cl_git_pass(git_index_set_caps(index
, caps
));
234 git_index_free(index
);
237 void test_repo_iterator__tree(void)
242 g_repo
= cl_git_sandbox_init("icase");
244 cl_git_pass(git_repository_head_tree(&head
, g_repo
));
246 /* auto expand with no tree entries */
247 cl_git_pass(git_iterator_for_tree(&i
, head
, 0, NULL
, NULL
));
248 expect_iterator_items(i
, 20, NULL
, 20, NULL
);
249 git_iterator_free(i
);
251 /* auto expand with tree entries */
252 cl_git_pass(git_iterator_for_tree(
253 &i
, head
, GIT_ITERATOR_INCLUDE_TREES
, NULL
, NULL
));
254 expect_iterator_items(i
, 22, NULL
, 22, NULL
);
255 git_iterator_free(i
);
257 /* no auto expand (implies trees included) */
258 cl_git_pass(git_iterator_for_tree(
259 &i
, head
, GIT_ITERATOR_DONT_AUTOEXPAND
, NULL
, NULL
));
260 expect_iterator_items(i
, 12, NULL
, 22, NULL
);
261 git_iterator_free(i
);
266 void test_repo_iterator__tree_icase(void)
270 git_iterator_flag_t flag
;
272 g_repo
= cl_git_sandbox_init("icase");
274 cl_git_pass(git_repository_head_tree(&head
, g_repo
));
276 flag
= GIT_ITERATOR_DONT_IGNORE_CASE
;
278 /* auto expand with no tree entries */
279 cl_git_pass(git_iterator_for_tree(&i
, head
, flag
, "c", "k/D"));
280 expect_iterator_items(i
, 7, NULL
, 7, NULL
);
281 git_iterator_free(i
);
283 cl_git_pass(git_iterator_for_tree(&i
, head
, flag
, "k", "k/Z"));
284 expect_iterator_items(i
, 3, NULL
, 3, NULL
);
285 git_iterator_free(i
);
287 /* auto expand with tree entries */
288 cl_git_pass(git_iterator_for_tree(
289 &i
, head
, flag
| GIT_ITERATOR_INCLUDE_TREES
, "c", "k/D"));
290 expect_iterator_items(i
, 8, NULL
, 8, NULL
);
291 git_iterator_free(i
);
293 cl_git_pass(git_iterator_for_tree(
294 &i
, head
, flag
| GIT_ITERATOR_INCLUDE_TREES
, "k", "k/Z"));
295 expect_iterator_items(i
, 4, NULL
, 4, NULL
);
296 git_iterator_free(i
);
298 /* no auto expand (implies trees included) */
299 cl_git_pass(git_iterator_for_tree(
300 &i
, head
, flag
| GIT_ITERATOR_DONT_AUTOEXPAND
, "c", "k/D"));
301 expect_iterator_items(i
, 5, NULL
, 8, NULL
);
302 git_iterator_free(i
);
304 cl_git_pass(git_iterator_for_tree(
305 &i
, head
, flag
| GIT_ITERATOR_DONT_AUTOEXPAND
, "k", "k/Z"));
306 expect_iterator_items(i
, 1, NULL
, 4, NULL
);
307 git_iterator_free(i
);
309 flag
= GIT_ITERATOR_IGNORE_CASE
;
311 /* auto expand with no tree entries */
312 cl_git_pass(git_iterator_for_tree(&i
, head
, flag
, "c", "k/D"));
313 expect_iterator_items(i
, 13, NULL
, 13, NULL
);
314 git_iterator_free(i
);
316 cl_git_pass(git_iterator_for_tree(&i
, head
, flag
, "k", "k/Z"));
317 expect_iterator_items(i
, 5, NULL
, 5, NULL
);
318 git_iterator_free(i
);
320 /* auto expand with tree entries */
321 cl_git_pass(git_iterator_for_tree(
322 &i
, head
, flag
| GIT_ITERATOR_INCLUDE_TREES
, "c", "k/D"));
323 expect_iterator_items(i
, 14, NULL
, 14, NULL
);
324 git_iterator_free(i
);
326 cl_git_pass(git_iterator_for_tree(
327 &i
, head
, flag
| GIT_ITERATOR_INCLUDE_TREES
, "k", "k/Z"));
328 expect_iterator_items(i
, 6, NULL
, 6, NULL
);
329 git_iterator_free(i
);
331 /* no auto expand (implies trees included) */
332 cl_git_pass(git_iterator_for_tree(
333 &i
, head
, flag
| GIT_ITERATOR_DONT_AUTOEXPAND
, "c", "k/D"));
334 expect_iterator_items(i
, 9, NULL
, 14, NULL
);
335 git_iterator_free(i
);
337 cl_git_pass(git_iterator_for_tree(
338 &i
, head
, flag
| GIT_ITERATOR_DONT_AUTOEXPAND
, "k", "k/Z"));
339 expect_iterator_items(i
, 1, NULL
, 6, NULL
);
340 git_iterator_free(i
);
345 void test_repo_iterator__tree_more(void)
349 static const char *expect_basic
[] = {
354 "staged_changes_file_deleted",
355 "staged_changes_modified_file",
356 "staged_delete_file_deleted",
357 "staged_delete_modified_file",
359 "subdir/current_file",
360 "subdir/deleted_file",
361 "subdir/modified_file",
364 static const char *expect_trees
[] = {
369 "staged_changes_file_deleted",
370 "staged_changes_modified_file",
371 "staged_delete_file_deleted",
372 "staged_delete_modified_file",
375 "subdir/current_file",
376 "subdir/deleted_file",
377 "subdir/modified_file",
380 static const char *expect_noauto
[] = {
385 "staged_changes_file_deleted",
386 "staged_changes_modified_file",
387 "staged_delete_file_deleted",
388 "staged_delete_modified_file",
394 g_repo
= cl_git_sandbox_init("status");
396 cl_git_pass(git_repository_head_tree(&head
, g_repo
));
398 /* auto expand with no tree entries */
399 cl_git_pass(git_iterator_for_tree(&i
, head
, 0, NULL
, NULL
));
400 expect_iterator_items(i
, 12, expect_basic
, 12, expect_basic
);
401 git_iterator_free(i
);
403 /* auto expand with tree entries */
404 cl_git_pass(git_iterator_for_tree(
405 &i
, head
, GIT_ITERATOR_INCLUDE_TREES
, NULL
, NULL
));
406 expect_iterator_items(i
, 13, expect_trees
, 13, expect_trees
);
407 git_iterator_free(i
);
409 /* no auto expand (implies trees included) */
410 cl_git_pass(git_iterator_for_tree(
411 &i
, head
, GIT_ITERATOR_DONT_AUTOEXPAND
, NULL
, NULL
));
412 expect_iterator_items(i
, 10, expect_noauto
, 13, expect_trees
);
413 git_iterator_free(i
);
418 /* "b=name,t=name", blob_id, tree_id */
419 static void build_test_tree(
420 git_oid
*out
, git_repository
*repo
, const char *fmt
, ...)
423 git_treebuilder
*builder
;
424 const char *scan
= fmt
, *next
;
425 char type
, delimiter
;
426 git_filemode_t mode
= GIT_FILEMODE_BLOB
;
427 git_buf name
= GIT_BUF_INIT
;
430 cl_git_pass(git_treebuilder_create(&builder
, repo
, NULL
)); /* start builder */
432 va_start(arglist
, fmt
);
434 switch (type
= *scan
++) {
435 case 't': case 'T': mode
= GIT_FILEMODE_TREE
; break;
436 case 'b': case 'B': mode
= GIT_FILEMODE_BLOB
; break;
438 cl_assert(type
== 't' || type
== 'T' || type
== 'b' || type
== 'B');
441 delimiter
= *scan
++; /* read and skip delimiter */
442 for (next
= scan
; *next
&& *next
!= delimiter
; ++next
)
444 cl_git_pass(git_buf_set(&name
, scan
, (size_t)(next
- scan
)));
445 for (scan
= next
; *scan
&& (*scan
== delimiter
|| *scan
== ','); ++scan
)
446 /* skip delimiter and optional comma */;
448 id
= va_arg(arglist
, git_oid
*);
450 cl_git_pass(git_treebuilder_insert(NULL
, builder
, name
.ptr
, id
, mode
));
454 cl_git_pass(git_treebuilder_write(out
, builder
));
456 git_treebuilder_free(builder
);
460 void test_repo_iterator__tree_case_conflicts_0(void)
462 const char *blob_sha
= "d44e18fb93b7107b5cd1b95d601591d77869a1b6";
464 git_oid blob_id
, biga_id
, littlea_id
, tree_id
;
466 const char *expect_cs
[] = {
467 "A/1.file", "A/3.file", "a/2.file", "a/4.file" };
468 const char *expect_ci
[] = {
469 "A/1.file", "a/2.file", "A/3.file", "a/4.file" };
470 const char *expect_cs_trees
[] = {
471 "A/", "A/1.file", "A/3.file", "a/", "a/2.file", "a/4.file" };
472 const char *expect_ci_trees
[] = {
473 "A/", "A/1.file", "a/2.file", "A/3.file", "a/4.file" };
475 g_repo
= cl_git_sandbox_init("icase");
477 cl_git_pass(git_oid_fromstr(&blob_id
, blob_sha
)); /* lookup blob */
479 /* create tree with: A/1.file, A/3.file, a/2.file, a/4.file */
481 &biga_id
, g_repo
, "b|1.file|,b|3.file|", &blob_id
, &blob_id
);
483 &littlea_id
, g_repo
, "b|2.file|,b|4.file|", &blob_id
, &blob_id
);
485 &tree_id
, g_repo
, "t|A|,t|a|", &biga_id
, &littlea_id
);
487 cl_git_pass(git_tree_lookup(&tree
, g_repo
, &tree_id
));
489 cl_git_pass(git_iterator_for_tree(
490 &i
, tree
, GIT_ITERATOR_DONT_IGNORE_CASE
, NULL
, NULL
));
491 expect_iterator_items(i
, 4, expect_cs
, 4, expect_cs
);
492 git_iterator_free(i
);
494 cl_git_pass(git_iterator_for_tree(
495 &i
, tree
, GIT_ITERATOR_IGNORE_CASE
, NULL
, NULL
));
496 expect_iterator_items(i
, 4, expect_ci
, 4, expect_ci
);
497 git_iterator_free(i
);
499 cl_git_pass(git_iterator_for_tree(
500 &i
, tree
, GIT_ITERATOR_DONT_IGNORE_CASE
|
501 GIT_ITERATOR_INCLUDE_TREES
, NULL
, NULL
));
502 expect_iterator_items(i
, 6, expect_cs_trees
, 6, expect_cs_trees
);
503 git_iterator_free(i
);
505 cl_git_pass(git_iterator_for_tree(
506 &i
, tree
, GIT_ITERATOR_IGNORE_CASE
|
507 GIT_ITERATOR_INCLUDE_TREES
, NULL
, NULL
));
508 expect_iterator_items(i
, 5, expect_ci_trees
, 5, expect_ci_trees
);
509 git_iterator_free(i
);
514 void test_repo_iterator__tree_case_conflicts_1(void)
516 const char *blob_sha
= "d44e18fb93b7107b5cd1b95d601591d77869a1b6";
518 git_oid blob_id
, Ab_id
, biga_id
, littlea_id
, tree_id
;
520 const char *expect_cs
[] = {
521 "A/a", "A/b/1", "A/c", "a/C", "a/a", "a/b" };
522 const char *expect_ci
[] = {
523 "A/a", "a/b", "A/b/1", "A/c" };
524 const char *expect_cs_trees
[] = {
525 "A/", "A/a", "A/b/", "A/b/1", "A/c", "a/", "a/C", "a/a", "a/b" };
526 const char *expect_ci_trees
[] = {
527 "A/", "A/a", "a/b", "A/b/", "A/b/1", "A/c" };
529 g_repo
= cl_git_sandbox_init("icase");
531 cl_git_pass(git_oid_fromstr(&blob_id
, blob_sha
)); /* lookup blob */
533 /* create: A/a A/b/1 A/c a/a a/b a/C */
534 build_test_tree(&Ab_id
, g_repo
, "b|1|", &blob_id
);
536 &biga_id
, g_repo
, "b|a|,t|b|,b|c|", &blob_id
, &Ab_id
, &blob_id
);
538 &littlea_id
, g_repo
, "b|a|,b|b|,b|C|", &blob_id
, &blob_id
, &blob_id
);
540 &tree_id
, g_repo
, "t|A|,t|a|", &biga_id
, &littlea_id
);
542 cl_git_pass(git_tree_lookup(&tree
, g_repo
, &tree_id
));
544 cl_git_pass(git_iterator_for_tree(
545 &i
, tree
, GIT_ITERATOR_DONT_IGNORE_CASE
, NULL
, NULL
));
546 expect_iterator_items(i
, 6, expect_cs
, 6, expect_cs
);
547 git_iterator_free(i
);
549 cl_git_pass(git_iterator_for_tree(
550 &i
, tree
, GIT_ITERATOR_IGNORE_CASE
, NULL
, NULL
));
551 expect_iterator_items(i
, 4, expect_ci
, 4, expect_ci
);
552 git_iterator_free(i
);
554 cl_git_pass(git_iterator_for_tree(
555 &i
, tree
, GIT_ITERATOR_DONT_IGNORE_CASE
|
556 GIT_ITERATOR_INCLUDE_TREES
, NULL
, NULL
));
557 expect_iterator_items(i
, 9, expect_cs_trees
, 9, expect_cs_trees
);
558 git_iterator_free(i
);
560 cl_git_pass(git_iterator_for_tree(
561 &i
, tree
, GIT_ITERATOR_IGNORE_CASE
|
562 GIT_ITERATOR_INCLUDE_TREES
, NULL
, NULL
));
563 expect_iterator_items(i
, 6, expect_ci_trees
, 6, expect_ci_trees
);
564 git_iterator_free(i
);
569 void test_repo_iterator__tree_case_conflicts_2(void)
571 const char *blob_sha
= "d44e18fb93b7107b5cd1b95d601591d77869a1b6";
573 git_oid blob_id
, d1
, d2
, c1
, c2
, b1
, b2
, a1
, a2
, tree_id
;
575 const char *expect_cs
[] = {
576 "A/B/C/D/16", "A/B/C/D/foo", "A/B/C/d/15", "A/B/C/d/FOO",
577 "A/B/c/D/14", "A/B/c/D/foo", "A/B/c/d/13", "A/B/c/d/FOO",
578 "A/b/C/D/12", "A/b/C/D/foo", "A/b/C/d/11", "A/b/C/d/FOO",
579 "A/b/c/D/10", "A/b/c/D/foo", "A/b/c/d/09", "A/b/c/d/FOO",
580 "a/B/C/D/08", "a/B/C/D/foo", "a/B/C/d/07", "a/B/C/d/FOO",
581 "a/B/c/D/06", "a/B/c/D/foo", "a/B/c/d/05", "a/B/c/d/FOO",
582 "a/b/C/D/04", "a/b/C/D/foo", "a/b/C/d/03", "a/b/C/d/FOO",
583 "a/b/c/D/02", "a/b/c/D/foo", "a/b/c/d/01", "a/b/c/d/FOO", };
584 const char *expect_ci
[] = {
585 "a/b/c/d/01", "a/b/c/D/02", "a/b/C/d/03", "a/b/C/D/04",
586 "a/B/c/d/05", "a/B/c/D/06", "a/B/C/d/07", "a/B/C/D/08",
587 "A/b/c/d/09", "A/b/c/D/10", "A/b/C/d/11", "A/b/C/D/12",
588 "A/B/c/d/13", "A/B/c/D/14", "A/B/C/d/15", "A/B/C/D/16",
590 const char *expect_ci_trees
[] = {
591 "A/", "A/B/", "A/B/C/", "A/B/C/D/",
592 "a/b/c/d/01", "a/b/c/D/02", "a/b/C/d/03", "a/b/C/D/04",
593 "a/B/c/d/05", "a/B/c/D/06", "a/B/C/d/07", "a/B/C/D/08",
594 "A/b/c/d/09", "A/b/c/D/10", "A/b/C/d/11", "A/b/C/D/12",
595 "A/B/c/d/13", "A/B/c/D/14", "A/B/C/d/15", "A/B/C/D/16",
598 g_repo
= cl_git_sandbox_init("icase");
600 cl_git_pass(git_oid_fromstr(&blob_id
, blob_sha
)); /* lookup blob */
602 build_test_tree(&d1
, g_repo
, "b|16|,b|foo|", &blob_id
, &blob_id
);
603 build_test_tree(&d2
, g_repo
, "b|15|,b|FOO|", &blob_id
, &blob_id
);
604 build_test_tree(&c1
, g_repo
, "t|D|,t|d|", &d1
, &d2
);
605 build_test_tree(&d1
, g_repo
, "b|14|,b|foo|", &blob_id
, &blob_id
);
606 build_test_tree(&d2
, g_repo
, "b|13|,b|FOO|", &blob_id
, &blob_id
);
607 build_test_tree(&c2
, g_repo
, "t|D|,t|d|", &d1
, &d2
);
608 build_test_tree(&b1
, g_repo
, "t|C|,t|c|", &c1
, &c2
);
610 build_test_tree(&d1
, g_repo
, "b|12|,b|foo|", &blob_id
, &blob_id
);
611 build_test_tree(&d2
, g_repo
, "b|11|,b|FOO|", &blob_id
, &blob_id
);
612 build_test_tree(&c1
, g_repo
, "t|D|,t|d|", &d1
, &d2
);
613 build_test_tree(&d1
, g_repo
, "b|10|,b|foo|", &blob_id
, &blob_id
);
614 build_test_tree(&d2
, g_repo
, "b|09|,b|FOO|", &blob_id
, &blob_id
);
615 build_test_tree(&c2
, g_repo
, "t|D|,t|d|", &d1
, &d2
);
616 build_test_tree(&b2
, g_repo
, "t|C|,t|c|", &c1
, &c2
);
618 build_test_tree(&a1
, g_repo
, "t|B|,t|b|", &b1
, &b2
);
620 build_test_tree(&d1
, g_repo
, "b|08|,b|foo|", &blob_id
, &blob_id
);
621 build_test_tree(&d2
, g_repo
, "b|07|,b|FOO|", &blob_id
, &blob_id
);
622 build_test_tree(&c1
, g_repo
, "t|D|,t|d|", &d1
, &d2
);
623 build_test_tree(&d1
, g_repo
, "b|06|,b|foo|", &blob_id
, &blob_id
);
624 build_test_tree(&d2
, g_repo
, "b|05|,b|FOO|", &blob_id
, &blob_id
);
625 build_test_tree(&c2
, g_repo
, "t|D|,t|d|", &d1
, &d2
);
626 build_test_tree(&b1
, g_repo
, "t|C|,t|c|", &c1
, &c2
);
628 build_test_tree(&d1
, g_repo
, "b|04|,b|foo|", &blob_id
, &blob_id
);
629 build_test_tree(&d2
, g_repo
, "b|03|,b|FOO|", &blob_id
, &blob_id
);
630 build_test_tree(&c1
, g_repo
, "t|D|,t|d|", &d1
, &d2
);
631 build_test_tree(&d1
, g_repo
, "b|02|,b|foo|", &blob_id
, &blob_id
);
632 build_test_tree(&d2
, g_repo
, "b|01|,b|FOO|", &blob_id
, &blob_id
);
633 build_test_tree(&c2
, g_repo
, "t|D|,t|d|", &d1
, &d2
);
634 build_test_tree(&b2
, g_repo
, "t|C|,t|c|", &c1
, &c2
);
636 build_test_tree(&a2
, g_repo
, "t|B|,t|b|", &b1
, &b2
);
638 build_test_tree(&tree_id
, g_repo
, "t/A/,t/a/", &a1
, &a2
);
640 cl_git_pass(git_tree_lookup(&tree
, g_repo
, &tree_id
));
642 cl_git_pass(git_iterator_for_tree(
643 &i
, tree
, GIT_ITERATOR_DONT_IGNORE_CASE
, NULL
, NULL
));
644 expect_iterator_items(i
, 32, expect_cs
, 32, expect_cs
);
645 git_iterator_free(i
);
647 cl_git_pass(git_iterator_for_tree(
648 &i
, tree
, GIT_ITERATOR_IGNORE_CASE
, NULL
, NULL
));
649 expect_iterator_items(i
, 17, expect_ci
, 17, expect_ci
);
650 git_iterator_free(i
);
652 cl_git_pass(git_iterator_for_tree(
653 &i
, tree
, GIT_ITERATOR_IGNORE_CASE
|
654 GIT_ITERATOR_INCLUDE_TREES
, NULL
, NULL
));
655 expect_iterator_items(i
, 21, expect_ci_trees
, 21, expect_ci_trees
);
656 git_iterator_free(i
);
661 void test_repo_iterator__workdir(void)
665 g_repo
= cl_git_sandbox_init("icase");
667 /* auto expand with no tree entries */
668 cl_git_pass(git_iterator_for_workdir(&i
, g_repo
, NULL
, NULL
, 0, NULL
, NULL
));
669 expect_iterator_items(i
, 20, NULL
, 20, NULL
);
670 git_iterator_free(i
);
672 /* auto expand with tree entries */
673 cl_git_pass(git_iterator_for_workdir(
674 &i
, g_repo
, NULL
, NULL
, GIT_ITERATOR_INCLUDE_TREES
, NULL
, NULL
));
675 expect_iterator_items(i
, 22, NULL
, 22, NULL
);
676 git_iterator_free(i
);
678 /* no auto expand (implies trees included) */
679 cl_git_pass(git_iterator_for_workdir(
680 &i
, g_repo
, NULL
, NULL
, GIT_ITERATOR_DONT_AUTOEXPAND
, NULL
, NULL
));
681 expect_iterator_items(i
, 12, NULL
, 22, NULL
);
682 git_iterator_free(i
);
685 void test_repo_iterator__workdir_icase(void)
688 git_iterator_flag_t flag
;
690 g_repo
= cl_git_sandbox_init("icase");
692 flag
= GIT_ITERATOR_DONT_IGNORE_CASE
;
694 /* auto expand with no tree entries */
695 cl_git_pass(git_iterator_for_workdir(&i
, g_repo
, NULL
, NULL
, flag
, "c", "k/D"));
696 expect_iterator_items(i
, 7, NULL
, 7, NULL
);
697 git_iterator_free(i
);
699 cl_git_pass(git_iterator_for_workdir(&i
, g_repo
, NULL
, NULL
, flag
, "k", "k/Z"));
700 expect_iterator_items(i
, 3, NULL
, 3, NULL
);
701 git_iterator_free(i
);
703 /* auto expand with tree entries */
704 cl_git_pass(git_iterator_for_workdir(
705 &i
, g_repo
, NULL
, NULL
, flag
| GIT_ITERATOR_INCLUDE_TREES
, "c", "k/D"));
706 expect_iterator_items(i
, 8, NULL
, 8, NULL
);
707 git_iterator_free(i
);
709 cl_git_pass(git_iterator_for_workdir(
710 &i
, g_repo
, NULL
, NULL
, flag
| GIT_ITERATOR_INCLUDE_TREES
, "k", "k/Z"));
711 expect_iterator_items(i
, 4, NULL
, 4, NULL
);
712 git_iterator_free(i
);
714 /* no auto expand (implies trees included) */
715 cl_git_pass(git_iterator_for_workdir(
716 &i
, g_repo
, NULL
, NULL
, flag
| GIT_ITERATOR_DONT_AUTOEXPAND
, "c", "k/D"));
717 expect_iterator_items(i
, 5, NULL
, 8, NULL
);
718 git_iterator_free(i
);
720 cl_git_pass(git_iterator_for_workdir(
721 &i
, g_repo
, NULL
, NULL
, flag
| GIT_ITERATOR_DONT_AUTOEXPAND
, "k", "k/Z"));
722 expect_iterator_items(i
, 1, NULL
, 4, NULL
);
723 git_iterator_free(i
);
725 flag
= GIT_ITERATOR_IGNORE_CASE
;
727 /* auto expand with no tree entries */
728 cl_git_pass(git_iterator_for_workdir(&i
, g_repo
, NULL
, NULL
, flag
, "c", "k/D"));
729 expect_iterator_items(i
, 13, NULL
, 13, NULL
);
730 git_iterator_free(i
);
732 cl_git_pass(git_iterator_for_workdir(&i
, g_repo
, NULL
, NULL
, flag
, "k", "k/Z"));
733 expect_iterator_items(i
, 5, NULL
, 5, NULL
);
734 git_iterator_free(i
);
736 /* auto expand with tree entries */
737 cl_git_pass(git_iterator_for_workdir(
738 &i
, g_repo
, NULL
, NULL
, flag
| GIT_ITERATOR_INCLUDE_TREES
, "c", "k/D"));
739 expect_iterator_items(i
, 14, NULL
, 14, NULL
);
740 git_iterator_free(i
);
742 cl_git_pass(git_iterator_for_workdir(
743 &i
, g_repo
, NULL
, NULL
, flag
| GIT_ITERATOR_INCLUDE_TREES
, "k", "k/Z"));
744 expect_iterator_items(i
, 6, NULL
, 6, NULL
);
745 git_iterator_free(i
);
747 /* no auto expand (implies trees included) */
748 cl_git_pass(git_iterator_for_workdir(
749 &i
, g_repo
, NULL
, NULL
, flag
| GIT_ITERATOR_DONT_AUTOEXPAND
, "c", "k/D"));
750 expect_iterator_items(i
, 9, NULL
, 14, NULL
);
751 git_iterator_free(i
);
753 cl_git_pass(git_iterator_for_workdir(
754 &i
, g_repo
, NULL
, NULL
, flag
| GIT_ITERATOR_DONT_AUTOEXPAND
, "k", "k/Z"));
755 expect_iterator_items(i
, 1, NULL
, 6, NULL
);
756 git_iterator_free(i
);
759 static void build_workdir_tree(const char *root
, int dirs
, int subs
)
762 char buf
[64], sub
[64];
764 for (i
= 0; i
< dirs
; ++i
) {
766 p_snprintf(buf
, sizeof(buf
), "%s/dir%02d", root
, i
);
767 cl_git_pass(git_futils_mkdir(buf
, NULL
, 0775, GIT_MKDIR_PATH
));
769 p_snprintf(buf
, sizeof(buf
), "%s/dir%02d/file", root
, i
);
770 cl_git_mkfile(buf
, buf
);
771 buf
[strlen(buf
) - 5] = '\0';
773 p_snprintf(buf
, sizeof(buf
), "%s/DIR%02d", root
, i
);
774 cl_git_pass(git_futils_mkdir(buf
, NULL
, 0775, GIT_MKDIR_PATH
));
777 for (j
= 0; j
< subs
; ++j
) {
779 case 0: p_snprintf(sub
, sizeof(sub
), "%s/sub%02d", buf
, j
); break;
780 case 1: p_snprintf(sub
, sizeof(sub
), "%s/sUB%02d", buf
, j
); break;
781 case 2: p_snprintf(sub
, sizeof(sub
), "%s/Sub%02d", buf
, j
); break;
782 case 3: p_snprintf(sub
, sizeof(sub
), "%s/SUB%02d", buf
, j
); break;
784 cl_git_pass(git_futils_mkdir(sub
, NULL
, 0775, GIT_MKDIR_PATH
));
787 size_t sublen
= strlen(sub
);
788 memcpy(&sub
[sublen
], "/file", sizeof("/file"));
789 cl_git_mkfile(sub
, sub
);
796 void test_repo_iterator__workdir_depth(void)
800 g_repo
= cl_git_sandbox_init("icase");
802 build_workdir_tree("icase", 10, 10);
803 build_workdir_tree("icase/DIR01/sUB01", 50, 0);
804 build_workdir_tree("icase/dir02/sUB01", 50, 0);
806 /* auto expand with no tree entries */
807 cl_git_pass(git_iterator_for_workdir(&iter
, g_repo
, NULL
, NULL
, 0, NULL
, NULL
));
808 expect_iterator_items(iter
, 125, NULL
, 125, NULL
);
809 git_iterator_free(iter
);
811 /* auto expand with tree entries (empty dirs silently skipped) */
812 cl_git_pass(git_iterator_for_workdir(
813 &iter
, g_repo
, NULL
, NULL
, GIT_ITERATOR_INCLUDE_TREES
, NULL
, NULL
));
814 expect_iterator_items(iter
, 337, NULL
, 337, NULL
);
815 git_iterator_free(iter
);
818 void test_repo_iterator__fs(void)
821 static const char *expect_base
[] = {
832 static const char *expect_trees
[] = {
853 static const char *expect_noauto
[] = {
862 g_repo
= cl_git_sandbox_init("status");
864 build_workdir_tree("status/subdir", 2, 4);
866 cl_git_pass(git_iterator_for_filesystem(
867 &i
, "status/subdir", 0, NULL
, NULL
));
868 expect_iterator_items(i
, 8, expect_base
, 8, expect_base
);
869 git_iterator_free(i
);
871 cl_git_pass(git_iterator_for_filesystem(
872 &i
, "status/subdir", GIT_ITERATOR_INCLUDE_TREES
, NULL
, NULL
));
873 expect_iterator_items(i
, 18, expect_trees
, 18, expect_trees
);
874 git_iterator_free(i
);
876 cl_git_pass(git_iterator_for_filesystem(
877 &i
, "status/subdir", GIT_ITERATOR_DONT_AUTOEXPAND
, NULL
, NULL
));
878 expect_iterator_items(i
, 5, expect_noauto
, 18, expect_trees
);
879 git_iterator_free(i
);
881 git__tsort((void **)expect_base
, 8, (git__tsort_cmp
)git__strcasecmp
);
882 git__tsort((void **)expect_trees
, 18, (git__tsort_cmp
)git__strcasecmp
);
883 git__tsort((void **)expect_noauto
, 5, (git__tsort_cmp
)git__strcasecmp
);
885 cl_git_pass(git_iterator_for_filesystem(
886 &i
, "status/subdir", GIT_ITERATOR_IGNORE_CASE
, NULL
, NULL
));
887 expect_iterator_items(i
, 8, expect_base
, 8, expect_base
);
888 git_iterator_free(i
);
890 cl_git_pass(git_iterator_for_filesystem(
891 &i
, "status/subdir", GIT_ITERATOR_IGNORE_CASE
|
892 GIT_ITERATOR_INCLUDE_TREES
, NULL
, NULL
));
893 expect_iterator_items(i
, 18, expect_trees
, 18, expect_trees
);
894 git_iterator_free(i
);
896 cl_git_pass(git_iterator_for_filesystem(
897 &i
, "status/subdir", GIT_ITERATOR_IGNORE_CASE
|
898 GIT_ITERATOR_DONT_AUTOEXPAND
, NULL
, NULL
));
899 expect_iterator_items(i
, 5, expect_noauto
, 18, expect_trees
);
900 git_iterator_free(i
);
903 void test_repo_iterator__fs2(void)
906 static const char *expect_base
[] = {
909 "heads/long-file-name",
917 "tags/point_to_blob",
922 g_repo
= cl_git_sandbox_init("testrepo");
924 cl_git_pass(git_iterator_for_filesystem(
925 &i
, "testrepo/.git/refs", 0, NULL
, NULL
));
926 expect_iterator_items(i
, 12, expect_base
, 12, expect_base
);
927 git_iterator_free(i
);
930 void test_repo_iterator__fs_preserves_error(void)
933 const git_index_entry
*e
;
935 if (!cl_is_chmod_supported())
938 g_repo
= cl_git_sandbox_init("empty_standard_repo");
940 cl_must_pass(p_mkdir("empty_standard_repo/r", 0777));
941 cl_git_mkfile("empty_standard_repo/r/a", "hello");
942 cl_must_pass(p_mkdir("empty_standard_repo/r/b", 0777));
943 cl_git_mkfile("empty_standard_repo/r/b/problem", "not me");
944 cl_must_pass(p_chmod("empty_standard_repo/r/b", 0000));
945 cl_must_pass(p_mkdir("empty_standard_repo/r/c", 0777));
946 cl_git_mkfile("empty_standard_repo/r/d", "final");
948 cl_git_pass(git_iterator_for_filesystem(
949 &i
, "empty_standard_repo/r", 0, NULL
, NULL
));
951 cl_git_pass(git_iterator_advance(&e
, i
)); /* a */
952 cl_git_fail(git_iterator_advance(&e
, i
)); /* b */
953 cl_assert(giterr_last());
954 cl_assert(giterr_last()->message
!= NULL
);
955 /* skip 'c/' empty directory */
956 cl_git_pass(git_iterator_advance(&e
, i
)); /* d */
957 cl_assert_equal_i(GIT_ITEROVER
, git_iterator_advance(&e
, i
));
959 cl_must_pass(p_chmod("empty_standard_repo/r/b", 0777));
961 git_iterator_free(i
);
964 void test_repo_iterator__skips_fifos_and_such(void)
968 const git_index_entry
*e
;
970 g_repo
= cl_git_sandbox_init("empty_standard_repo");
972 cl_must_pass(p_mkdir("empty_standard_repo/dir", 0777));
973 cl_git_mkfile("empty_standard_repo/file", "not me");
975 cl_assert(!mkfifo("empty_standard_repo/fifo", 0777));
976 cl_assert(!access("empty_standard_repo/fifo", F_OK
));
978 cl_git_pass(git_iterator_for_filesystem(
979 &i
, "empty_standard_repo", GIT_ITERATOR_INCLUDE_TREES
|
980 GIT_ITERATOR_DONT_AUTOEXPAND
, NULL
, NULL
));
982 cl_git_pass(git_iterator_advance(&e
, i
)); /* .git */
983 cl_assert(S_ISDIR(e
->mode
));
984 cl_git_pass(git_iterator_advance(&e
, i
)); /* dir */
985 cl_assert(S_ISDIR(e
->mode
));
987 cl_git_pass(git_iterator_advance(&e
, i
)); /* file */
988 cl_assert(S_ISREG(e
->mode
));
990 cl_assert_equal_i(GIT_ITEROVER
, git_iterator_advance(&e
, i
));
992 git_iterator_free(i
);