mirror of
https://git.proxmox.com/git/libgit2
synced 2026-02-01 19:03:40 +00:00
Make iterator APIs consistent with standards
The iterator APIs are not currently consistent with the parameter ordering of the rest of the codebase. This rearranges the order of parameters, simplifies the naming of a number of functions, and makes somewhat better use of macros internally to clean up the iterator code. This also expands the test coverage of iterator functionality, making sure that case sensitive range-limited iteration works correctly.
This commit is contained in:
parent
ed4f95e5d9
commit
169dc61607
@ -456,7 +456,7 @@ static int checkout_action(
|
||||
while (1) {
|
||||
if (!wd)
|
||||
return checkout_action_no_wd(data, delta);
|
||||
|
||||
|
||||
cmp = strcomp(wd->path, delta->old_file.path);
|
||||
|
||||
/* 1. wd before delta ("a/a" before "a/b")
|
||||
@ -473,9 +473,9 @@ static int checkout_action(
|
||||
if (cmp == 0) {
|
||||
if (wd->mode == GIT_FILEMODE_TREE) {
|
||||
/* case 2 - entry prefixed by workdir tree */
|
||||
if (git_iterator_advance_into_directory(workdir, &wd) < 0)
|
||||
if (git_iterator_advance_into(&wd, workdir) < 0)
|
||||
goto fail;
|
||||
|
||||
|
||||
*wditem_ptr = wd;
|
||||
continue;
|
||||
}
|
||||
@ -484,14 +484,14 @@ static int checkout_action(
|
||||
if (delta->old_file.path[strlen(wd->path)] == '/') {
|
||||
act = checkout_action_with_wd_blocker(data, delta, wd);
|
||||
*wditem_ptr =
|
||||
git_iterator_advance(workdir, &wd) ? NULL : wd;
|
||||
git_iterator_advance(&wd, workdir) ? NULL : wd;
|
||||
return act;
|
||||
}
|
||||
}
|
||||
|
||||
/* case 1 - handle wd item (if it matches pathspec) */
|
||||
if (checkout_action_wd_only(data, workdir, wd, pathspec) < 0 ||
|
||||
git_iterator_advance(workdir, &wd) < 0)
|
||||
git_iterator_advance(&wd, workdir) < 0)
|
||||
goto fail;
|
||||
|
||||
*wditem_ptr = wd;
|
||||
@ -501,7 +501,7 @@ static int checkout_action(
|
||||
if (cmp == 0) {
|
||||
/* case 4 */
|
||||
act = checkout_action_with_wd(data, delta, wd);
|
||||
*wditem_ptr = git_iterator_advance(workdir, &wd) ? NULL : wd;
|
||||
*wditem_ptr = git_iterator_advance(&wd, workdir) ? NULL : wd;
|
||||
return act;
|
||||
}
|
||||
|
||||
@ -514,7 +514,7 @@ static int checkout_action(
|
||||
if (delta->status == GIT_DELTA_TYPECHANGE) {
|
||||
if (delta->old_file.mode == GIT_FILEMODE_TREE) {
|
||||
act = checkout_action_with_wd(data, delta, wd);
|
||||
if (git_iterator_advance_into_directory(workdir, &wd) < 0)
|
||||
if (git_iterator_advance_into(&wd, workdir) < 0)
|
||||
wd = NULL;
|
||||
*wditem_ptr = wd;
|
||||
return act;
|
||||
@ -525,7 +525,7 @@ static int checkout_action(
|
||||
delta->old_file.mode == GIT_FILEMODE_COMMIT)
|
||||
{
|
||||
act = checkout_action_with_wd(data, delta, wd);
|
||||
if (git_iterator_advance(workdir, &wd) < 0)
|
||||
if (git_iterator_advance(&wd, workdir) < 0)
|
||||
wd = NULL;
|
||||
*wditem_ptr = wd;
|
||||
return act;
|
||||
@ -554,7 +554,7 @@ static int checkout_remaining_wd_items(
|
||||
|
||||
while (wd && !error) {
|
||||
if (!(error = checkout_action_wd_only(data, workdir, wd, spec)))
|
||||
error = git_iterator_advance(workdir, &wd);
|
||||
error = git_iterator_advance(&wd, workdir);
|
||||
}
|
||||
|
||||
return error;
|
||||
@ -578,7 +578,7 @@ static int checkout_get_actions(
|
||||
git_pathspec_init(&pathspec, &data->opts.paths, &pathpool) < 0)
|
||||
return -1;
|
||||
|
||||
if ((error = git_iterator_current(workdir, &wditem)) < 0)
|
||||
if ((error = git_iterator_current(&wditem, workdir)) < 0)
|
||||
goto fail;
|
||||
|
||||
deltas = &data->diff->deltas;
|
||||
@ -1134,16 +1134,17 @@ static int checkout_data_init(
|
||||
if ((error = git_config_refresh(cfg)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (git_iterator_inner_type(target) == GIT_ITERATOR_TYPE_INDEX) {
|
||||
/* if we are iterating over the index, don't reload */
|
||||
data->index = git_iterator_index_get_index(target);
|
||||
/* if we are checking out the index, don't reload,
|
||||
* otherwise get index and force reload
|
||||
*/
|
||||
if ((data->index = git_iterator_get_index(target)) != NULL) {
|
||||
GIT_REFCOUNT_INC(data->index);
|
||||
} else {
|
||||
/* otherwise, grab and reload the index */
|
||||
if ((error = git_repository_index(&data->index, data->repo)) < 0 ||
|
||||
(error = git_index_read(data->index)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
|
||||
/* clear the REUC when doing a tree or commit checkout */
|
||||
git_index_reuc_clear(data->index);
|
||||
}
|
||||
@ -1241,9 +1242,9 @@ int git_checkout_iterator(
|
||||
GIT_ITERATOR_IGNORE_CASE : GIT_ITERATOR_DONT_IGNORE_CASE;
|
||||
|
||||
if ((error = git_iterator_reset(target, data.pfx, data.pfx)) < 0 ||
|
||||
(error = git_iterator_for_workdir_range(
|
||||
(error = git_iterator_for_workdir(
|
||||
&workdir, data.repo, iterflags, data.pfx, data.pfx)) < 0 ||
|
||||
(error = git_iterator_for_tree_range(
|
||||
(error = git_iterator_for_tree(
|
||||
&baseline, data.opts.baseline, iterflags, data.pfx, data.pfx)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
@ -1321,7 +1322,7 @@ int git_checkout_index(
|
||||
return error;
|
||||
GIT_REFCOUNT_INC(index);
|
||||
|
||||
if (!(error = git_iterator_for_index(&index_i, index)))
|
||||
if (!(error = git_iterator_for_index(&index_i, index, 0, NULL, NULL)))
|
||||
error = git_checkout_iterator(index_i, opts);
|
||||
|
||||
git_iterator_free(index_i);
|
||||
@ -1348,7 +1349,7 @@ int git_checkout_tree(
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(error = git_iterator_for_tree(&tree_i, tree)))
|
||||
if (!(error = git_iterator_for_tree(&tree_i, tree, 0, NULL, NULL)))
|
||||
error = git_checkout_iterator(tree_i, opts);
|
||||
|
||||
git_iterator_free(tree_i);
|
||||
@ -1369,7 +1370,7 @@ int git_checkout_head(
|
||||
return error;
|
||||
|
||||
if (!(error = checkout_lookup_head_tree(&head, repo)) &&
|
||||
!(error = git_iterator_for_tree(&head_i, head)))
|
||||
!(error = git_iterator_for_tree(&head_i, head, 0, NULL, NULL)))
|
||||
error = git_checkout_iterator(head_i, opts);
|
||||
|
||||
git_iterator_free(head_i);
|
||||
|
||||
41
src/diff.c
41
src/diff.c
@ -630,8 +630,8 @@ int git_diff__from_iterators(
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (git_iterator_current(old_iter, &oitem) < 0 ||
|
||||
git_iterator_current(new_iter, &nitem) < 0)
|
||||
if (git_iterator_current(&oitem, old_iter) < 0 ||
|
||||
git_iterator_current(&nitem, new_iter) < 0)
|
||||
goto fail;
|
||||
|
||||
/* run iterators building diffs */
|
||||
@ -663,12 +663,12 @@ int git_diff__from_iterators(
|
||||
if (S_ISDIR(nitem->mode) &&
|
||||
!(diff->opts.flags & GIT_DIFF_RECURSE_UNTRACKED_DIRS))
|
||||
{
|
||||
if (git_iterator_advance(new_iter, &nitem) < 0)
|
||||
if (git_iterator_advance(&nitem, new_iter) < 0)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (git_iterator_advance(old_iter, &oitem) < 0)
|
||||
if (git_iterator_advance(&oitem, old_iter) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -696,7 +696,7 @@ int git_diff__from_iterators(
|
||||
/* do not advance into directories that contain a .git file */
|
||||
if (!contains_oitem && recurse_untracked) {
|
||||
git_buf *full = NULL;
|
||||
if (git_iterator_current_workdir_path(new_iter, &full) < 0)
|
||||
if (git_iterator_current_workdir_path(&full, new_iter) < 0)
|
||||
goto fail;
|
||||
if (git_path_contains_dir(full, DOT_GIT))
|
||||
recurse_untracked = false;
|
||||
@ -710,7 +710,7 @@ int git_diff__from_iterators(
|
||||
git_iterator_current_is_ignored(new_iter))
|
||||
git_buf_sets(&ignore_prefix, nitem->path);
|
||||
|
||||
if (git_iterator_advance_into_directory(new_iter, &nitem) < 0)
|
||||
if (git_iterator_advance_into(&nitem, new_iter) < 0)
|
||||
goto fail;
|
||||
|
||||
continue;
|
||||
@ -733,7 +733,7 @@ int git_diff__from_iterators(
|
||||
* skip the file.
|
||||
*/
|
||||
else if (delta_type == GIT_DELTA_IGNORED) {
|
||||
if (git_iterator_advance(new_iter, &nitem) < 0)
|
||||
if (git_iterator_advance(&nitem, new_iter) < 0)
|
||||
goto fail;
|
||||
continue; /* ignored parent directory, so skip completely */
|
||||
}
|
||||
@ -762,7 +762,7 @@ int git_diff__from_iterators(
|
||||
}
|
||||
}
|
||||
|
||||
if (git_iterator_advance(new_iter, &nitem) < 0)
|
||||
if (git_iterator_advance(&nitem, new_iter) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -772,11 +772,10 @@ int git_diff__from_iterators(
|
||||
else {
|
||||
assert(oitem && nitem && cmp == 0);
|
||||
|
||||
if (maybe_modified(
|
||||
old_iter, oitem, new_iter, nitem, diff) < 0 ||
|
||||
git_iterator_advance(old_iter, &oitem) < 0 ||
|
||||
git_iterator_advance(new_iter, &nitem) < 0)
|
||||
goto fail;
|
||||
if (maybe_modified(old_iter, oitem, new_iter, nitem, diff) < 0 ||
|
||||
git_iterator_advance(&oitem, old_iter) < 0 ||
|
||||
git_iterator_advance(&nitem, new_iter) < 0)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
@ -814,8 +813,8 @@ int git_diff_tree_to_tree(
|
||||
assert(diff && repo);
|
||||
|
||||
DIFF_FROM_ITERATORS(
|
||||
git_iterator_for_tree_range(&a, old_tree, 0, pfx, pfx),
|
||||
git_iterator_for_tree_range(&b, new_tree, 0, pfx, pfx)
|
||||
git_iterator_for_tree(&a, old_tree, 0, pfx, pfx),
|
||||
git_iterator_for_tree(&b, new_tree, 0, pfx, pfx)
|
||||
);
|
||||
|
||||
return error;
|
||||
@ -836,8 +835,8 @@ int git_diff_tree_to_index(
|
||||
return error;
|
||||
|
||||
DIFF_FROM_ITERATORS(
|
||||
git_iterator_for_tree_range(&a, old_tree, 0, pfx, pfx),
|
||||
git_iterator_for_index_range(&b, index, 0, pfx, pfx)
|
||||
git_iterator_for_tree(&a, old_tree, 0, pfx, pfx),
|
||||
git_iterator_for_index(&b, index, 0, pfx, pfx)
|
||||
);
|
||||
|
||||
return error;
|
||||
@ -857,8 +856,8 @@ int git_diff_index_to_workdir(
|
||||
return error;
|
||||
|
||||
DIFF_FROM_ITERATORS(
|
||||
git_iterator_for_index_range(&a, index, 0, pfx, pfx),
|
||||
git_iterator_for_workdir_range(&b, repo, 0, pfx, pfx)
|
||||
git_iterator_for_index(&a, index, 0, pfx, pfx),
|
||||
git_iterator_for_workdir(&b, repo, 0, pfx, pfx)
|
||||
);
|
||||
|
||||
return error;
|
||||
@ -876,8 +875,8 @@ int git_diff_tree_to_workdir(
|
||||
assert(diff && repo);
|
||||
|
||||
DIFF_FROM_ITERATORS(
|
||||
git_iterator_for_tree_range(&a, old_tree, 0, pfx, pfx),
|
||||
git_iterator_for_workdir_range(&b, repo, 0, pfx, pfx)
|
||||
git_iterator_for_tree(&a, old_tree, 0, pfx, pfx),
|
||||
git_iterator_for_workdir(&b, repo, 0, pfx, pfx)
|
||||
);
|
||||
|
||||
return error;
|
||||
|
||||
51
src/index.c
51
src/index.c
@ -1679,54 +1679,3 @@ git_repository *git_index_owner(const git_index *index)
|
||||
{
|
||||
return INDEX_OWNER(index);
|
||||
}
|
||||
|
||||
int git_index_read_tree_match(
|
||||
git_index *index, git_tree *tree, git_strarray *strspec)
|
||||
{
|
||||
#if 0
|
||||
git_iterator *iter = NULL;
|
||||
const git_index_entry *entry;
|
||||
char *pfx = NULL;
|
||||
git_vector pathspec = GIT_VECTOR_INIT;
|
||||
git_pool pathpool = GIT_POOL_INIT_STRINGPOOL;
|
||||
#endif
|
||||
|
||||
if (!git_pathspec_is_interesting(strspec))
|
||||
return git_index_read_tree(index, tree);
|
||||
|
||||
return git_index_read_tree(index, tree);
|
||||
|
||||
#if 0
|
||||
/* The following loads the matches into the index, but doesn't
|
||||
* erase obsoleted entries (e.g. you load a blob at "a/b" which
|
||||
* should obsolete a blob at "a/b/c/d" since b is no longer a tree)
|
||||
*/
|
||||
|
||||
if (git_pathspec_init(&pathspec, strspec, &pathpool) < 0)
|
||||
return -1;
|
||||
|
||||
pfx = git_pathspec_prefix(strspec);
|
||||
|
||||
if ((error = git_iterator_for_tree_range(&iter, tree, pfx, pfx)) < 0 ||
|
||||
(error = git_iterator_current(iter, &entry)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
while (entry != NULL) {
|
||||
if (git_pathspec_match_path(
|
||||
&pathspec, entry->path, false, false, NULL) &&
|
||||
(error = git_index_add(index, entry)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if ((error = git_iterator_advance(iter, &entry)) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
git_iterator_free(iter);
|
||||
git_pathspec_free(&pathspec);
|
||||
git_pool_clear(&pathpool);
|
||||
git__free(pfx);
|
||||
|
||||
return error;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -50,7 +50,4 @@ extern int git_index_entry__cmp_icase(const void *a, const void *b);
|
||||
|
||||
extern void git_index__set_ignore_case(git_index *index, bool ignore_case);
|
||||
|
||||
extern int git_index_read_tree_match(
|
||||
git_index *index, git_tree *tree, git_strarray *strspec);
|
||||
|
||||
#endif
|
||||
|
||||
259
src/iterator.c
259
src/iterator.c
@ -14,13 +14,16 @@
|
||||
|
||||
#define ITERATOR_SET_CB(P,NAME_LC) do { \
|
||||
(P)->cb.current = NAME_LC ## _iterator__current; \
|
||||
(P)->cb.at_end = NAME_LC ## _iterator__at_end; \
|
||||
(P)->cb.advance = NAME_LC ## _iterator__advance; \
|
||||
(P)->cb.seek = NAME_LC ## _iterator__seek; \
|
||||
(P)->cb.reset = NAME_LC ## _iterator__reset; \
|
||||
(P)->cb.at_end = NAME_LC ## _iterator__at_end; \
|
||||
(P)->cb.free = NAME_LC ## _iterator__free; \
|
||||
} while (0)
|
||||
|
||||
#define ITERATOR_CASE_FLAGS \
|
||||
(GIT_ITERATOR_IGNORE_CASE | GIT_ITERATOR_DONT_IGNORE_CASE)
|
||||
|
||||
#define ITERATOR_BASE_INIT(P,NAME_LC,NAME_UC) do { \
|
||||
(P) = git__calloc(1, sizeof(NAME_LC ## _iterator)); \
|
||||
GITERR_CHECK_ALLOC(P); \
|
||||
@ -32,8 +35,17 @@
|
||||
if ((start && !(P)->base.start) || (end && !(P)->base.end)) { \
|
||||
git__free(P); return -1; } \
|
||||
(P)->base.prefixcomp = git__prefixcmp; \
|
||||
(P)->base.flags = flags & ~ITERATOR_CASE_FLAGS; \
|
||||
} while (0)
|
||||
|
||||
#define iterator__flag(I,F) ((((git_iterator *)(I))->flags & (F)) != 0)
|
||||
#define iterator__ignore_case(I) iterator__flag(I,GIT_ITERATOR_IGNORE_CASE)
|
||||
|
||||
#define iterator__end(I) ((git_iterator *)(I))->end
|
||||
#define iterator__past_end(I,PATH) \
|
||||
(iterator__end(I) && ((git_iterator *)(I))->prefixcomp((PATH),iterator__end(I)) > 0)
|
||||
|
||||
|
||||
static int iterator__reset_range(
|
||||
git_iterator *iter, const char *start, const char *end)
|
||||
{
|
||||
@ -82,18 +94,13 @@ static int iterator_update_ignore_case(
|
||||
return error;
|
||||
}
|
||||
|
||||
static int empty_iterator__no_item(
|
||||
git_iterator *iter, const git_index_entry **entry)
|
||||
{
|
||||
GIT_UNUSED(iter);
|
||||
*entry = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int empty_iterator__at_end(git_iterator *iter)
|
||||
static int empty_iterator__noop(
|
||||
const git_index_entry **entry, git_iterator *iter)
|
||||
{
|
||||
GIT_UNUSED(iter);
|
||||
return 1;
|
||||
if (entry) *entry = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int empty_iterator__reset(
|
||||
@ -109,6 +116,12 @@ static int empty_iterator__seek(git_iterator *iter, const char *prefix)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int empty_iterator__at_end(git_iterator *iter)
|
||||
{
|
||||
GIT_UNUSED(iter);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void empty_iterator__free(git_iterator *iter)
|
||||
{
|
||||
GIT_UNUSED(iter);
|
||||
@ -119,20 +132,22 @@ typedef struct {
|
||||
git_iterator_callbacks cb;
|
||||
} empty_iterator;
|
||||
|
||||
int git_iterator_for_nothing(git_iterator **iter, git_iterator_flag_t flags)
|
||||
int git_iterator_for_nothing(
|
||||
git_iterator **iter,
|
||||
git_iterator_flag_t flags,
|
||||
const char *start,
|
||||
const char *end)
|
||||
{
|
||||
empty_iterator *i = git__calloc(1, sizeof(empty_iterator));
|
||||
GITERR_CHECK_ALLOC(i);
|
||||
|
||||
i->base.type = GIT_ITERATOR_TYPE_EMPTY;
|
||||
i->base.cb = &i->cb;
|
||||
i->base.flags = flags;
|
||||
i->cb.current = empty_iterator__no_item;
|
||||
i->cb.at_end = empty_iterator__at_end;
|
||||
i->cb.advance = empty_iterator__no_item;
|
||||
i->cb.seek = empty_iterator__seek;
|
||||
i->cb.reset = empty_iterator__reset;
|
||||
i->cb.free = empty_iterator__free;
|
||||
#define empty_iterator__current empty_iterator__noop
|
||||
#define empty_iterator__advance empty_iterator__noop
|
||||
|
||||
ITERATOR_BASE_INIT(i, empty, EMPTY);
|
||||
|
||||
if ((flags & GIT_ITERATOR_IGNORE_CASE) != 0)
|
||||
i->base.flags |= GIT_ITERATOR_IGNORE_CASE;
|
||||
|
||||
*iter = (git_iterator *)i;
|
||||
|
||||
@ -144,9 +159,10 @@ typedef struct tree_iterator_frame tree_iterator_frame;
|
||||
struct tree_iterator_frame {
|
||||
tree_iterator_frame *next, *prev;
|
||||
git_tree *tree;
|
||||
char *start;
|
||||
const char *start;
|
||||
size_t startlen;
|
||||
size_t index;
|
||||
/* secondary tree index for case-insensitive sort */
|
||||
void **icase_map;
|
||||
void *icase_data[GIT_FLEX_ARRAY];
|
||||
};
|
||||
@ -163,12 +179,15 @@ typedef struct {
|
||||
GIT_INLINE(const git_tree_entry *)tree_iterator__tree_entry(tree_iterator *ti)
|
||||
{
|
||||
tree_iterator_frame *tf = ti->stack;
|
||||
size_t entries = git_tree_entrycount(tf->tree), idx = tf->index;
|
||||
|
||||
if (tf->index >= git_tree_entrycount(tf->tree))
|
||||
if (idx >= entries)
|
||||
return NULL;
|
||||
|
||||
return git_tree_entry_byindex(
|
||||
tf->tree, tf->icase_map ? (size_t)tf->icase_map[tf->index] : tf->index);
|
||||
if (tf->icase_map)
|
||||
idx = (size_t)tf->icase_map[idx];
|
||||
|
||||
return git_tree_entry_byindex(tf->tree, idx);
|
||||
}
|
||||
|
||||
static char *tree_iterator__current_filename(
|
||||
@ -218,7 +237,7 @@ static int tree_iterator__to_end(tree_iterator *ti)
|
||||
}
|
||||
|
||||
static int tree_iterator__current(
|
||||
git_iterator *self, const git_index_entry **entry)
|
||||
const git_index_entry **entry, git_iterator *self)
|
||||
{
|
||||
tree_iterator *ti = (tree_iterator *)self;
|
||||
const git_tree_entry *te = tree_iterator__tree_entry(ti);
|
||||
@ -236,7 +255,7 @@ static int tree_iterator__current(
|
||||
if (ti->entry.path == NULL)
|
||||
return -1;
|
||||
|
||||
if (ti->base.end && ti->base.prefixcomp(ti->entry.path, ti->base.end) > 0)
|
||||
if (iterator__past_end(ti, ti->entry.path))
|
||||
return tree_iterator__to_end(ti);
|
||||
|
||||
if (entry)
|
||||
@ -290,26 +309,35 @@ static void tree_iterator__frame_seek_start(tree_iterator_frame *tf)
|
||||
}
|
||||
}
|
||||
|
||||
static tree_iterator_frame *tree_iterator__alloc_frame(
|
||||
tree_iterator *ti, git_tree *tree, char *start)
|
||||
static int tree_iterator__push_frame(
|
||||
tree_iterator *ti, git_tree *tree, const char *start)
|
||||
{
|
||||
size_t i, max_i = git_tree_entrycount(tree);
|
||||
tree_iterator_frame *tf =
|
||||
git__calloc(1, sizeof(tree_iterator_frame) + max_i * sizeof(void *));
|
||||
if (!tf)
|
||||
return NULL;
|
||||
GITERR_CHECK_ALLOC(tf);
|
||||
|
||||
tf->tree = tree;
|
||||
tf->tree = tree;
|
||||
|
||||
tf->next = ti->stack;
|
||||
ti->stack = tf;
|
||||
if (tf->next)
|
||||
tf->next->prev = tf;
|
||||
else
|
||||
ti->tail = tf;
|
||||
|
||||
if (start && *start) {
|
||||
tf->start = start;
|
||||
tf->start = start;
|
||||
tf->startlen = strlen(start);
|
||||
}
|
||||
|
||||
if (!max_i)
|
||||
return tf;
|
||||
ti->path_has_filename = false;
|
||||
|
||||
if ((ti->base.flags & GIT_ITERATOR_IGNORE_CASE) != 0) {
|
||||
if (!max_i)
|
||||
return 0;
|
||||
|
||||
/* build secondary index if iterator is case-insensitive */
|
||||
if (iterator__ignore_case(ti)) {
|
||||
tf->icase_map = tf->icase_data;
|
||||
|
||||
for (i = 0; i < max_i; ++i)
|
||||
@ -321,7 +349,7 @@ static tree_iterator_frame *tree_iterator__alloc_frame(
|
||||
|
||||
tree_iterator__frame_seek_start(tf);
|
||||
|
||||
return tf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tree_iterator__expand_tree(tree_iterator *ti)
|
||||
@ -329,16 +357,13 @@ static int tree_iterator__expand_tree(tree_iterator *ti)
|
||||
int error;
|
||||
git_tree *subtree;
|
||||
const git_tree_entry *te = tree_iterator__tree_entry(ti);
|
||||
tree_iterator_frame *tf;
|
||||
char *relpath;
|
||||
const char *relpath;
|
||||
|
||||
while (te != NULL && git_tree_entry__is_tree(te)) {
|
||||
if (git_buf_joinpath(&ti->path, ti->path.ptr, te->filename) < 0)
|
||||
return -1;
|
||||
relpath = tree_iterator__current_filename(ti, te);
|
||||
|
||||
/* check that we have not passed the range end */
|
||||
if (ti->base.end != NULL &&
|
||||
ti->base.prefixcomp(ti->path.ptr, ti->base.end) > 0)
|
||||
if (iterator__past_end(ti, relpath))
|
||||
return tree_iterator__to_end(ti);
|
||||
|
||||
if ((error = git_tree_lookup(&subtree, ti->base.repo, &te->oid)) < 0)
|
||||
@ -354,12 +379,8 @@ static int tree_iterator__expand_tree(tree_iterator *ti)
|
||||
relpath = ti->stack->start + te->filename_len + 1;
|
||||
}
|
||||
|
||||
if ((tf = tree_iterator__alloc_frame(ti, subtree, relpath)) == NULL)
|
||||
return -1;
|
||||
|
||||
tf->next = ti->stack;
|
||||
ti->stack = tf;
|
||||
tf->next->prev = tf;
|
||||
if ((error = tree_iterator__push_frame(ti, subtree, relpath)) < 0)
|
||||
return error;
|
||||
|
||||
te = tree_iterator__tree_entry(ti);
|
||||
}
|
||||
@ -368,9 +389,8 @@ static int tree_iterator__expand_tree(tree_iterator *ti)
|
||||
}
|
||||
|
||||
static int tree_iterator__advance(
|
||||
git_iterator *self, const git_index_entry **entry)
|
||||
const git_index_entry **entry, git_iterator *self)
|
||||
{
|
||||
int error = 0;
|
||||
tree_iterator *ti = (tree_iterator *)self;
|
||||
const git_tree_entry *te = NULL;
|
||||
|
||||
@ -394,13 +414,13 @@ static int tree_iterator__advance(
|
||||
git_buf_rtruncate_at_char(&ti->path, '/');
|
||||
}
|
||||
|
||||
if (te && git_tree_entry__is_tree(te))
|
||||
error = tree_iterator__expand_tree(ti);
|
||||
if (te && git_tree_entry__is_tree(te)) {
|
||||
int error = tree_iterator__expand_tree(ti);
|
||||
if (error < 0)
|
||||
return error;
|
||||
}
|
||||
|
||||
if (!error)
|
||||
error = tree_iterator__current(self, entry);
|
||||
|
||||
return error;
|
||||
return tree_iterator__current(entry, self);
|
||||
}
|
||||
|
||||
static int tree_iterator__seek(git_iterator *self, const char *prefix)
|
||||
@ -444,7 +464,7 @@ static int tree_iterator__reset(
|
||||
return tree_iterator__expand_tree(ti);
|
||||
}
|
||||
|
||||
int git_iterator_for_tree_range(
|
||||
int git_iterator_for_tree(
|
||||
git_iterator **iter,
|
||||
git_tree *tree,
|
||||
git_iterator_flag_t flags,
|
||||
@ -455,7 +475,7 @@ int git_iterator_for_tree_range(
|
||||
tree_iterator *ti;
|
||||
|
||||
if (tree == NULL)
|
||||
return git_iterator_for_nothing(iter, flags);
|
||||
return git_iterator_for_nothing(iter, flags, start, end);
|
||||
|
||||
if ((error = git_tree__dup(&tree, tree)) < 0)
|
||||
return error;
|
||||
@ -464,11 +484,10 @@ int git_iterator_for_tree_range(
|
||||
|
||||
ti->base.repo = git_tree_owner(tree);
|
||||
|
||||
if ((error = iterator_update_ignore_case((git_iterator *)ti, flags)) < 0)
|
||||
if ((error = iterator_update_ignore_case((git_iterator *)ti, flags)) < 0 ||
|
||||
(error = tree_iterator__push_frame(ti, tree, ti->base.start)) < 0)
|
||||
goto fail;
|
||||
|
||||
ti->stack = ti->tail = tree_iterator__alloc_frame(ti, tree, ti->base.start);
|
||||
|
||||
if ((error = tree_iterator__expand_tree(ti)) < 0)
|
||||
goto fail;
|
||||
|
||||
@ -489,7 +508,7 @@ typedef struct {
|
||||
} index_iterator;
|
||||
|
||||
static int index_iterator__current(
|
||||
git_iterator *self, const git_index_entry **entry)
|
||||
const git_index_entry **entry, git_iterator *self)
|
||||
{
|
||||
index_iterator *ii = (index_iterator *)self;
|
||||
const git_index_entry *ie = git_index_get_byindex(ii->index, ii->current);
|
||||
@ -506,18 +525,15 @@ static int index_iterator__at_end(git_iterator *self)
|
||||
return (ii->current >= git_index_entrycount(ii->index));
|
||||
}
|
||||
|
||||
static void index_iterator__skip_conflicts(
|
||||
index_iterator *ii)
|
||||
static void index_iterator__skip_conflicts(index_iterator *ii)
|
||||
{
|
||||
size_t entrycount = git_index_entrycount(ii->index);
|
||||
const git_index_entry *ie;
|
||||
const git_index_entry *ie = NULL;
|
||||
|
||||
while (ii->current < entrycount) {
|
||||
ie = git_index_get_byindex(ii->index, ii->current);
|
||||
|
||||
if (ie == NULL ||
|
||||
(ii->base.end != NULL &&
|
||||
ii->base.prefixcomp(ie->path, ii->base.end) > 0)) {
|
||||
if (ie != NULL && iterator__past_end(ii, ie->path)) {
|
||||
ii->current = entrycount;
|
||||
break;
|
||||
}
|
||||
@ -530,7 +546,7 @@ static void index_iterator__skip_conflicts(
|
||||
}
|
||||
|
||||
static int index_iterator__advance(
|
||||
git_iterator *self, const git_index_entry **entry)
|
||||
const git_index_entry **entry, git_iterator *self)
|
||||
{
|
||||
index_iterator *ii = (index_iterator *)self;
|
||||
|
||||
@ -539,7 +555,7 @@ static int index_iterator__advance(
|
||||
|
||||
index_iterator__skip_conflicts(ii);
|
||||
|
||||
return index_iterator__current(self, entry);
|
||||
return index_iterator__current(entry, self);
|
||||
}
|
||||
|
||||
static int index_iterator__seek(git_iterator *self, const char *prefix)
|
||||
@ -554,11 +570,15 @@ static int index_iterator__reset(
|
||||
git_iterator *self, const char *start, const char *end)
|
||||
{
|
||||
index_iterator *ii = (index_iterator *)self;
|
||||
|
||||
if (iterator__reset_range(self, start, end) < 0)
|
||||
return -1;
|
||||
|
||||
ii->current = ii->base.start ?
|
||||
git_index__prefix_position(ii->index, ii->base.start) : 0;
|
||||
|
||||
index_iterator__skip_conflicts(ii);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -569,7 +589,7 @@ static void index_iterator__free(git_iterator *self)
|
||||
ii->index = NULL;
|
||||
}
|
||||
|
||||
int git_iterator_for_index_range(
|
||||
int git_iterator_for_index(
|
||||
git_iterator **iter,
|
||||
git_index *index,
|
||||
git_iterator_flag_t flags,
|
||||
@ -583,10 +603,12 @@ int git_iterator_for_index_range(
|
||||
ITERATOR_BASE_INIT(ii, index, INDEX);
|
||||
|
||||
ii->base.repo = git_index_owner(index);
|
||||
|
||||
if (index->ignore_case) {
|
||||
ii->base.flags |= GIT_ITERATOR_IGNORE_CASE;
|
||||
ii->base.prefixcomp = git__prefixcmp_icase;
|
||||
}
|
||||
|
||||
ii->index = index;
|
||||
GIT_REFCOUNT_INC(index);
|
||||
|
||||
@ -643,7 +665,7 @@ static workdir_iterator_frame *workdir_iterator__alloc_frame(
|
||||
{
|
||||
workdir_iterator_frame *wf = git__calloc(1, sizeof(workdir_iterator_frame));
|
||||
git_vector_cmp entry_compare = CASESELECT(
|
||||
(wi->base.flags & GIT_ITERATOR_IGNORE_CASE) != 0,
|
||||
iterator__ignore_case(wi),
|
||||
git_path_with_stat_cmp_icase, git_path_with_stat_cmp);
|
||||
|
||||
if (wf == NULL)
|
||||
@ -706,7 +728,7 @@ static int workdir_iterator__expand_dir(workdir_iterator *wi)
|
||||
|
||||
error = git_path_dirload_with_stat(
|
||||
wi->path.ptr, wi->root_len,
|
||||
(wi->base.flags & GIT_ITERATOR_IGNORE_CASE) != 0,
|
||||
iterator__ignore_case(wi),
|
||||
wi->base.start, wi->base.end, &wf->entries);
|
||||
|
||||
if (error < 0 || wf->entries.length == 0) {
|
||||
@ -729,10 +751,11 @@ static int workdir_iterator__expand_dir(workdir_iterator *wi)
|
||||
}
|
||||
|
||||
static int workdir_iterator__current(
|
||||
git_iterator *self, const git_index_entry **entry)
|
||||
const git_index_entry **entry, git_iterator *self)
|
||||
{
|
||||
workdir_iterator *wi = (workdir_iterator *)self;
|
||||
*entry = (wi->entry.path == NULL) ? NULL : &wi->entry;
|
||||
if (entry)
|
||||
*entry = (wi->entry.path == NULL) ? NULL : &wi->entry;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -742,7 +765,7 @@ static int workdir_iterator__at_end(git_iterator *self)
|
||||
}
|
||||
|
||||
static int workdir_iterator__advance(
|
||||
git_iterator *self, const git_index_entry **entry)
|
||||
const git_index_entry **entry, git_iterator *self)
|
||||
{
|
||||
int error;
|
||||
workdir_iterator *wi = (workdir_iterator *)self;
|
||||
@ -781,7 +804,7 @@ static int workdir_iterator__advance(
|
||||
error = workdir_iterator__update_entry(wi);
|
||||
|
||||
if (!error && entry != NULL)
|
||||
error = workdir_iterator__current(self, entry);
|
||||
error = workdir_iterator__current(entry, self);
|
||||
|
||||
return error;
|
||||
}
|
||||
@ -832,6 +855,7 @@ static void workdir_iterator__free(git_iterator *self)
|
||||
|
||||
static int workdir_iterator__update_entry(workdir_iterator *wi)
|
||||
{
|
||||
int error = 0;
|
||||
git_path_with_stat *ps =
|
||||
git_vector_get(&wi->stack->entries, wi->stack->index);
|
||||
|
||||
@ -841,19 +865,18 @@ static int workdir_iterator__update_entry(workdir_iterator *wi)
|
||||
if (!ps)
|
||||
return 0;
|
||||
|
||||
/* skip over .git entries */
|
||||
if (path_is_dotgit(ps))
|
||||
return workdir_iterator__advance(NULL, (git_iterator *)wi);
|
||||
|
||||
if (git_buf_put(&wi->path, ps->path, ps->path_len) < 0)
|
||||
return -1;
|
||||
|
||||
if (wi->base.end &&
|
||||
wi->base.prefixcomp(wi->path.ptr + wi->root_len, wi->base.end) > 0)
|
||||
if (iterator__past_end(wi, wi->path.ptr + wi->root_len))
|
||||
return 0;
|
||||
|
||||
wi->entry.path = ps->path;
|
||||
|
||||
/* skip over .git entries */
|
||||
if (path_is_dotgit(ps))
|
||||
return workdir_iterator__advance((git_iterator *)wi, NULL);
|
||||
|
||||
wi->is_ignored = -1;
|
||||
|
||||
git_index_entry__init_from_stat(&wi->entry, &ps->st);
|
||||
@ -867,26 +890,28 @@ static int workdir_iterator__update_entry(workdir_iterator *wi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* detect submodules */
|
||||
if (S_ISDIR(wi->entry.mode)) {
|
||||
int res = git_submodule_lookup(NULL, wi->base.repo, wi->entry.path);
|
||||
bool is_submodule = (res == 0);
|
||||
if (res == GIT_ENOTFOUND)
|
||||
giterr_clear();
|
||||
/* if this isn't a tree, then we're done */
|
||||
if (wi->entry.mode != GIT_FILEMODE_TREE)
|
||||
return 0;
|
||||
|
||||
/* if submodule, mark as GITLINK and remove trailing slash */
|
||||
if (is_submodule) {
|
||||
size_t len = strlen(wi->entry.path);
|
||||
assert(wi->entry.path[len - 1] == '/');
|
||||
wi->entry.path[len - 1] = '\0';
|
||||
wi->entry.mode = S_IFGITLINK;
|
||||
}
|
||||
/* detect submodules */
|
||||
|
||||
error = git_submodule_lookup(NULL, wi->base.repo, wi->entry.path);
|
||||
if (error == GIT_ENOTFOUND)
|
||||
giterr_clear();
|
||||
|
||||
/* if submodule, mark as GITLINK and remove trailing slash */
|
||||
if (!error) {
|
||||
size_t len = strlen(wi->entry.path);
|
||||
assert(wi->entry.path[len - 1] == '/');
|
||||
wi->entry.path[len - 1] = '\0';
|
||||
wi->entry.mode = S_IFGITLINK;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_iterator_for_workdir_range(
|
||||
int git_iterator_for_workdir(
|
||||
git_iterator **iter,
|
||||
git_repository *repo,
|
||||
git_iterator_flag_t flags,
|
||||
@ -917,7 +942,7 @@ int git_iterator_for_workdir_range(
|
||||
}
|
||||
|
||||
wi->root_len = wi->path.size;
|
||||
wi->entrycmp = (wi->base.flags & GIT_ITERATOR_IGNORE_CASE) != 0 ?
|
||||
wi->entrycmp = iterator__ignore_case(wi) ?
|
||||
workdir_iterator__entry_cmp_icase : workdir_iterator__entry_cmp_case;
|
||||
|
||||
if ((error = workdir_iterator__expand_dir(wi)) < 0) {
|
||||
@ -949,7 +974,7 @@ typedef struct {
|
||||
} spoolandsort_callbacks;
|
||||
|
||||
static int spoolandsort_iterator__current(
|
||||
git_iterator *self, const git_index_entry **entry)
|
||||
const git_index_entry **entry, git_iterator *self)
|
||||
{
|
||||
spoolandsort_callbacks *scb = (spoolandsort_callbacks *)self->cb;
|
||||
|
||||
@ -967,7 +992,7 @@ static int spoolandsort_iterator__at_end(git_iterator *self)
|
||||
}
|
||||
|
||||
static int spoolandsort_iterator__advance(
|
||||
git_iterator *self, const git_index_entry **entry)
|
||||
const git_index_entry **entry, git_iterator *self)
|
||||
{
|
||||
spoolandsort_callbacks *scb = (spoolandsort_callbacks *)self->cb;
|
||||
|
||||
@ -1053,7 +1078,7 @@ int git_iterator_spoolandsort_push(git_iterator *iter, bool ignore_case)
|
||||
if (git_vector_init(&scb->entries, 16, entrycomp) < 0 ||
|
||||
git_pool_init(&scb->entry_pool, sizeof(git_index_entry), 0) < 0 ||
|
||||
git_pool_init(&scb->string_pool, 1, 0) < 0 ||
|
||||
git_iterator_current(iter, &item) < 0)
|
||||
git_iterator_current(&item, iter) < 0)
|
||||
goto fail;
|
||||
|
||||
while (item) {
|
||||
@ -1072,7 +1097,7 @@ int git_iterator_spoolandsort_push(git_iterator *iter, bool ignore_case)
|
||||
if (git_vector_insert(&scb->entries, clone) < 0)
|
||||
goto fail;
|
||||
|
||||
if (git_iterator_advance(iter, &item) < 0)
|
||||
if (git_iterator_advance(&item, iter) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -1105,7 +1130,7 @@ void git_iterator_free(git_iterator *iter)
|
||||
git__free(iter);
|
||||
}
|
||||
|
||||
git_index *git_iterator_index_get_index(git_iterator *iter)
|
||||
git_index *git_iterator_get_index(git_iterator *iter)
|
||||
{
|
||||
if (iter->type == GIT_ITERATOR_TYPE_INDEX)
|
||||
return ((index_iterator *)iter)->index;
|
||||
@ -1126,7 +1151,7 @@ git_iterator_type_t git_iterator_inner_type(git_iterator *iter)
|
||||
}
|
||||
|
||||
int git_iterator_current_tree_entry(
|
||||
git_iterator *iter, const git_tree_entry **tree_entry)
|
||||
const git_tree_entry **tree_entry, git_iterator *iter)
|
||||
{
|
||||
*tree_entry = (iter->type != GIT_ITERATOR_TYPE_TREE) ? NULL :
|
||||
tree_iterator__tree_entry((tree_iterator *)iter);
|
||||
@ -1134,9 +1159,9 @@ int git_iterator_current_tree_entry(
|
||||
}
|
||||
|
||||
int git_iterator_current_parent_tree(
|
||||
const git_tree **tree_ptr,
|
||||
git_iterator *iter,
|
||||
const char *parent_path,
|
||||
const git_tree **tree_ptr)
|
||||
const char *parent_path)
|
||||
{
|
||||
tree_iterator *ti = (tree_iterator *)iter;
|
||||
tree_iterator_frame *tf;
|
||||
@ -1177,24 +1202,24 @@ notfound:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_iterator_current_is_ignored(git_iterator *iter)
|
||||
bool git_iterator_current_is_ignored(git_iterator *iter)
|
||||
{
|
||||
workdir_iterator *wi = (workdir_iterator *)iter;
|
||||
|
||||
if (iter->type != GIT_ITERATOR_TYPE_WORKDIR)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
if (wi->is_ignored != -1)
|
||||
return wi->is_ignored;
|
||||
return (bool)(wi->is_ignored != 0);
|
||||
|
||||
if (git_ignore__lookup(&wi->ignores, wi->entry.path, &wi->is_ignored) < 0)
|
||||
wi->is_ignored = 1;
|
||||
wi->is_ignored = true;
|
||||
|
||||
return wi->is_ignored;
|
||||
return (bool)wi->is_ignored;
|
||||
}
|
||||
|
||||
int git_iterator_advance_into_directory(
|
||||
git_iterator *iter, const git_index_entry **entry)
|
||||
int git_iterator_advance_into(
|
||||
const git_index_entry **entry, git_iterator *iter)
|
||||
{
|
||||
workdir_iterator *wi = (workdir_iterator *)iter;
|
||||
|
||||
@ -1205,10 +1230,10 @@ int git_iterator_advance_into_directory(
|
||||
{
|
||||
if (workdir_iterator__expand_dir(wi) < 0)
|
||||
/* if error loading or if empty, skip the directory. */
|
||||
return workdir_iterator__advance(iter, entry);
|
||||
return workdir_iterator__advance(entry, iter);
|
||||
}
|
||||
|
||||
return entry ? git_iterator_current(iter, entry) : 0;
|
||||
return entry ? git_iterator_current(entry, iter) : 0;
|
||||
}
|
||||
|
||||
int git_iterator_cmp(git_iterator *iter, const char *path_prefix)
|
||||
@ -1216,7 +1241,7 @@ int git_iterator_cmp(git_iterator *iter, const char *path_prefix)
|
||||
const git_index_entry *entry;
|
||||
|
||||
/* a "done" iterator is after every prefix */
|
||||
if (git_iterator_current(iter, &entry) < 0 ||
|
||||
if (git_iterator_current(&entry, iter) < 0 ||
|
||||
entry == NULL)
|
||||
return 1;
|
||||
|
||||
@ -1227,7 +1252,7 @@ int git_iterator_cmp(git_iterator *iter, const char *path_prefix)
|
||||
return iter->prefixcomp(entry->path, path_prefix);
|
||||
}
|
||||
|
||||
int git_iterator_current_workdir_path(git_iterator *iter, git_buf **path)
|
||||
int git_iterator_current_workdir_path(git_buf **path, git_iterator *iter)
|
||||
{
|
||||
workdir_iterator *wi = (workdir_iterator *)iter;
|
||||
|
||||
|
||||
@ -12,11 +12,6 @@
|
||||
#include "vector.h"
|
||||
#include "buffer.h"
|
||||
|
||||
#define ITERATOR_PREFIXCMP(ITER, STR, PREFIX) \
|
||||
(((ITER).flags & GIT_ITERATOR_IGNORE_CASE) != 0 ? \
|
||||
git__prefixcmp_icase((STR), (PREFIX)) : \
|
||||
git__prefixcmp((STR), (PREFIX)))
|
||||
|
||||
typedef struct git_iterator git_iterator;
|
||||
|
||||
typedef enum {
|
||||
@ -28,16 +23,18 @@ typedef enum {
|
||||
} git_iterator_type_t;
|
||||
|
||||
typedef enum {
|
||||
GIT_ITERATOR_IGNORE_CASE = (1 << 0), /* ignore_case */
|
||||
GIT_ITERATOR_DONT_IGNORE_CASE = (1 << 1), /* force ignore_case off */
|
||||
/** ignore case for entry sort order */
|
||||
GIT_ITERATOR_IGNORE_CASE = (1 << 0),
|
||||
/** force case sensitivity for entry sort order */
|
||||
GIT_ITERATOR_DONT_IGNORE_CASE = (1 << 1),
|
||||
} git_iterator_flag_t;
|
||||
|
||||
typedef struct {
|
||||
int (*current)(git_iterator *, const git_index_entry **);
|
||||
int (*at_end)(git_iterator *);
|
||||
int (*advance)(git_iterator *, const git_index_entry **);
|
||||
int (*current)(const git_index_entry **, git_iterator *);
|
||||
int (*advance)(const git_index_entry **, git_iterator *);
|
||||
int (*seek)(git_iterator *, const char *prefix);
|
||||
int (*reset)(git_iterator *, const char *start, const char *end);
|
||||
int (*at_end)(git_iterator *);
|
||||
void (*free)(git_iterator *);
|
||||
} git_iterator_callbacks;
|
||||
|
||||
@ -52,53 +49,41 @@ struct git_iterator {
|
||||
};
|
||||
|
||||
extern int git_iterator_for_nothing(
|
||||
git_iterator **out, git_iterator_flag_t flags);
|
||||
git_iterator **out,
|
||||
git_iterator_flag_t flags,
|
||||
const char *start,
|
||||
const char *end);
|
||||
|
||||
/* tree iterators will match the ignore_case value from the index of the
|
||||
* repository, unless you override with a non-zero flag value
|
||||
*/
|
||||
extern int git_iterator_for_tree_range(
|
||||
extern int git_iterator_for_tree(
|
||||
git_iterator **out,
|
||||
git_tree *tree,
|
||||
git_iterator_flag_t flags,
|
||||
const char *start,
|
||||
const char *end);
|
||||
|
||||
GIT_INLINE(int) git_iterator_for_tree(git_iterator **out, git_tree *tree)
|
||||
{
|
||||
return git_iterator_for_tree_range(out, tree, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
/* index iterators will take the ignore_case value from the index; the
|
||||
* ignore_case flags are not used
|
||||
*/
|
||||
extern int git_iterator_for_index_range(
|
||||
extern int git_iterator_for_index(
|
||||
git_iterator **out,
|
||||
git_index *index,
|
||||
git_iterator_flag_t flags,
|
||||
const char *start,
|
||||
const char *end);
|
||||
|
||||
GIT_INLINE(int) git_iterator_for_index(git_iterator **out, git_index *index)
|
||||
{
|
||||
return git_iterator_for_index_range(out, index, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
/* workdir iterators will match the ignore_case value from the index of the
|
||||
* repository, unless you override with a non-zero flag value
|
||||
*/
|
||||
extern int git_iterator_for_workdir_range(
|
||||
extern int git_iterator_for_workdir(
|
||||
git_iterator **out,
|
||||
git_repository *repo,
|
||||
git_iterator_flag_t flags,
|
||||
const char *start,
|
||||
const char *end);
|
||||
|
||||
GIT_INLINE(int) git_iterator_for_workdir(git_iterator **out, git_repository *repo)
|
||||
{
|
||||
return git_iterator_for_workdir_range(out, repo, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
extern void git_iterator_free(git_iterator *iter);
|
||||
|
||||
/* Spool all iterator values, resort with alternative ignore_case value
|
||||
@ -109,29 +94,27 @@ extern int git_iterator_spoolandsort_push(git_iterator *iter, bool ignore_case);
|
||||
/* Restore original callbacks - not required in most circumstances */
|
||||
extern void git_iterator_spoolandsort_pop(git_iterator *iter);
|
||||
|
||||
/* Entry is not guaranteed to be fully populated. For a tree iterator,
|
||||
* we will only populate the mode, oid and path, for example. For a workdir
|
||||
* iterator, we will not populate the oid.
|
||||
/* Return a git_index_entry structure for the current value the iterator
|
||||
* is looking at or NULL if the iterator is at the end.
|
||||
*
|
||||
* The entry may noy be fully populated. Tree iterators will only have a
|
||||
* value mode, OID, and path. Workdir iterators will not have an OID (but
|
||||
* you can use `git_iterator_current_oid()` to calculate it on demand).
|
||||
*
|
||||
* You do not need to free the entry. It is still "owned" by the iterator.
|
||||
* Once you call `git_iterator_advance`, then content of the old entry is
|
||||
* no longer guaranteed to be valid.
|
||||
* Once you call `git_iterator_advance()` then the old entry is no longer
|
||||
* guaranteed to be valid - it may be freed or just overwritten in place.
|
||||
*/
|
||||
GIT_INLINE(int) git_iterator_current(
|
||||
git_iterator *iter, const git_index_entry **entry)
|
||||
const git_index_entry **entry, git_iterator *iter)
|
||||
{
|
||||
return iter->cb->current(iter, entry);
|
||||
}
|
||||
|
||||
GIT_INLINE(int) git_iterator_at_end(git_iterator *iter)
|
||||
{
|
||||
return iter->cb->at_end(iter);
|
||||
return iter->cb->current(entry, iter);
|
||||
}
|
||||
|
||||
GIT_INLINE(int) git_iterator_advance(
|
||||
git_iterator *iter, const git_index_entry **entry)
|
||||
const git_index_entry **entry, git_iterator *iter)
|
||||
{
|
||||
return iter->cb->advance(iter, entry);
|
||||
return iter->cb->advance(entry, iter);
|
||||
}
|
||||
|
||||
GIT_INLINE(int) git_iterator_seek(
|
||||
@ -146,6 +129,11 @@ GIT_INLINE(int) git_iterator_reset(
|
||||
return iter->cb->reset(iter, start, end);
|
||||
}
|
||||
|
||||
GIT_INLINE(int) git_iterator_at_end(git_iterator *iter)
|
||||
{
|
||||
return iter->cb->at_end(iter);
|
||||
}
|
||||
|
||||
GIT_INLINE(git_iterator_type_t) git_iterator_type(git_iterator *iter)
|
||||
{
|
||||
return iter->type;
|
||||
@ -167,15 +155,15 @@ GIT_INLINE(bool) git_iterator_ignore_case(git_iterator *iter)
|
||||
}
|
||||
|
||||
extern int git_iterator_current_tree_entry(
|
||||
git_iterator *iter, const git_tree_entry **tree_entry);
|
||||
const git_tree_entry **tree_entry, git_iterator *iter);
|
||||
|
||||
extern int git_iterator_current_parent_tree(
|
||||
git_iterator *iter, const char *parent_path, const git_tree **tree_ptr);
|
||||
const git_tree **tree_ptr, git_iterator *iter, const char *parent_path);
|
||||
|
||||
extern int git_iterator_current_is_ignored(git_iterator *iter);
|
||||
extern bool git_iterator_current_is_ignored(git_iterator *iter);
|
||||
|
||||
/**
|
||||
* Iterate into a workdir directory.
|
||||
* Iterate into a directory.
|
||||
*
|
||||
* Workdir iterators do not automatically descend into directories (so that
|
||||
* when comparing two iterator entries you can detect a newly created
|
||||
@ -191,21 +179,22 @@ extern int git_iterator_current_is_ignored(git_iterator *iter);
|
||||
* On non-workdir iterators or if not pointing at a directory, this is a
|
||||
* no-op and will not advance the iterator.
|
||||
*/
|
||||
extern int git_iterator_advance_into_directory(
|
||||
git_iterator *iter, const git_index_entry **entry);
|
||||
extern int git_iterator_advance_into(
|
||||
const git_index_entry **entry, git_iterator *iter);
|
||||
|
||||
extern int git_iterator_cmp(
|
||||
git_iterator *iter, const char *path_prefix);
|
||||
|
||||
/**
|
||||
* Get the full path of the current item from a workdir iterator.
|
||||
* This will return NULL for a non-workdir iterator.
|
||||
* Get full path of the current item from a workdir iterator. This will
|
||||
* return NULL for a non-workdir iterator. The git_buf is still owned by
|
||||
* the iterator; this is exposed just for efficiency.
|
||||
*/
|
||||
extern int git_iterator_current_workdir_path(
|
||||
git_iterator *iter, git_buf **path);
|
||||
git_buf **path, git_iterator *iter);
|
||||
|
||||
|
||||
extern git_index *git_iterator_index_get_index(git_iterator *iter);
|
||||
/* Return index pointer if index iterator, else NULL */
|
||||
extern git_index *git_iterator_get_index(git_iterator *iter);
|
||||
|
||||
extern git_iterator_type_t git_iterator_inner_type(git_iterator *iter);
|
||||
|
||||
|
||||
@ -625,7 +625,7 @@ int git_note_iterator_new(
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
||||
if ((error = git_iterator_for_tree(it, tree)) < 0)
|
||||
if ((error = git_iterator_for_tree(it, tree, 0, NULL, NULL)) < 0)
|
||||
git_iterator_free(*it);
|
||||
|
||||
cleanup:
|
||||
@ -643,7 +643,7 @@ int git_note_next(
|
||||
int error;
|
||||
const git_index_entry *item;
|
||||
|
||||
if ((error = git_iterator_current(it, &item)) < 0)
|
||||
if ((error = git_iterator_current(&item, it)) < 0)
|
||||
goto exit;
|
||||
|
||||
if (item != NULL) {
|
||||
@ -651,7 +651,7 @@ int git_note_next(
|
||||
error = process_entry_path(item->path, annotated_id);
|
||||
|
||||
if (error >= 0)
|
||||
error = git_iterator_advance(it, NULL);
|
||||
error = git_iterator_advance(NULL, it);
|
||||
} else {
|
||||
error = GIT_ITEROVER;
|
||||
}
|
||||
|
||||
@ -1135,10 +1135,10 @@ static int load_submodule_config_from_index(
|
||||
const git_index_entry *entry;
|
||||
|
||||
if ((error = git_repository_index__weakptr(&index, repo)) < 0 ||
|
||||
(error = git_iterator_for_index(&i, index)) < 0)
|
||||
(error = git_iterator_for_index(&i, index, 0, NULL, NULL)) < 0)
|
||||
return error;
|
||||
|
||||
error = git_iterator_current(i, &entry);
|
||||
error = git_iterator_current(&entry, i);
|
||||
|
||||
while (!error && entry != NULL) {
|
||||
|
||||
@ -1154,7 +1154,7 @@ static int load_submodule_config_from_index(
|
||||
git_oid_cpy(gitmodules_oid, &entry->oid);
|
||||
}
|
||||
|
||||
error = git_iterator_advance(i, &entry);
|
||||
error = git_iterator_advance(&entry, i);
|
||||
}
|
||||
|
||||
git_iterator_free(i);
|
||||
@ -1173,12 +1173,12 @@ static int load_submodule_config_from_head(
|
||||
if ((error = git_repository_head_tree(&head, repo)) < 0)
|
||||
return error;
|
||||
|
||||
if ((error = git_iterator_for_tree(&i, head)) < 0) {
|
||||
if ((error = git_iterator_for_tree(&i, head, 0, NULL, NULL)) < 0) {
|
||||
git_tree_free(head);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = git_iterator_current(i, &entry);
|
||||
error = git_iterator_current(&entry, i);
|
||||
|
||||
while (!error && entry != NULL) {
|
||||
|
||||
@ -1195,7 +1195,7 @@ static int load_submodule_config_from_head(
|
||||
git_oid_cpy(gitmodules_oid, &entry->oid);
|
||||
}
|
||||
|
||||
error = git_iterator_advance(i, &entry);
|
||||
error = git_iterator_advance(&entry, i);
|
||||
}
|
||||
|
||||
git_iterator_free(i);
|
||||
|
||||
@ -35,26 +35,26 @@ static void tree_iterator_test(
|
||||
git_repository *repo = cl_git_sandbox_init(sandbox);
|
||||
|
||||
cl_assert(t = resolve_commit_oid_to_tree(repo, treeish));
|
||||
cl_git_pass(git_iterator_for_tree_range(
|
||||
cl_git_pass(git_iterator_for_tree(
|
||||
&i, t, GIT_ITERATOR_DONT_IGNORE_CASE, start, end));
|
||||
|
||||
/* test loop */
|
||||
cl_git_pass(git_iterator_current(i, &entry));
|
||||
cl_git_pass(git_iterator_current(&entry, i));
|
||||
while (entry != NULL) {
|
||||
if (expected_values != NULL)
|
||||
cl_assert_equal_s(expected_values[count], entry->path);
|
||||
count++;
|
||||
cl_git_pass(git_iterator_advance(i, &entry));
|
||||
cl_git_pass(git_iterator_advance(&entry, i));
|
||||
}
|
||||
|
||||
/* test reset */
|
||||
cl_git_pass(git_iterator_reset(i, NULL, NULL));
|
||||
cl_git_pass(git_iterator_current(i, &entry));
|
||||
cl_git_pass(git_iterator_current(&entry, i));
|
||||
while (entry != NULL) {
|
||||
if (expected_values != NULL)
|
||||
cl_assert_equal_s(expected_values[count_post_reset], entry->path);
|
||||
count_post_reset++;
|
||||
cl_git_pass(git_iterator_advance(i, &entry));
|
||||
cl_git_pass(git_iterator_advance(&entry, i));
|
||||
}
|
||||
|
||||
git_iterator_free(i);
|
||||
@ -261,30 +261,30 @@ static void check_tree_entry(
|
||||
const git_tree *tree;
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
|
||||
cl_git_pass(git_iterator_current_tree_entry(i, &te));
|
||||
cl_git_pass(git_iterator_current_tree_entry(&te, i));
|
||||
cl_assert(te);
|
||||
cl_assert(git_oid_streq(&te->oid, oid) == 0);
|
||||
|
||||
cl_git_pass(git_iterator_current(i, &ie));
|
||||
cl_git_pass(git_iterator_current(&ie, i));
|
||||
cl_git_pass(git_buf_sets(&path, ie->path));
|
||||
|
||||
if (oid_p) {
|
||||
git_buf_rtruncate_at_char(&path, '/');
|
||||
cl_git_pass(git_iterator_current_parent_tree(i, path.ptr, &tree));
|
||||
cl_git_pass(git_iterator_current_parent_tree(&tree, i, path.ptr));
|
||||
cl_assert(tree);
|
||||
cl_assert(git_oid_streq(git_tree_id(tree), oid_p) == 0);
|
||||
}
|
||||
|
||||
if (oid_pp) {
|
||||
git_buf_rtruncate_at_char(&path, '/');
|
||||
cl_git_pass(git_iterator_current_parent_tree(i, path.ptr, &tree));
|
||||
cl_git_pass(git_iterator_current_parent_tree(&tree, i, path.ptr));
|
||||
cl_assert(tree);
|
||||
cl_assert(git_oid_streq(git_tree_id(tree), oid_pp) == 0);
|
||||
}
|
||||
|
||||
if (oid_ppp) {
|
||||
git_buf_rtruncate_at_char(&path, '/');
|
||||
cl_git_pass(git_iterator_current_parent_tree(i, path.ptr, &tree));
|
||||
cl_git_pass(git_iterator_current_parent_tree(&tree, i, path.ptr));
|
||||
cl_assert(tree);
|
||||
cl_assert(git_oid_streq(git_tree_id(tree), oid_ppp) == 0);
|
||||
}
|
||||
@ -305,9 +305,9 @@ void test_diff_iterator__tree_special_functions(void)
|
||||
repo, "24fa9a9fc4e202313e24b648087495441dab432b");
|
||||
cl_assert(t != NULL);
|
||||
|
||||
cl_git_pass(git_iterator_for_tree_range(
|
||||
cl_git_pass(git_iterator_for_tree(
|
||||
&i, t, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL));
|
||||
cl_git_pass(git_iterator_current(i, &entry));
|
||||
cl_git_pass(git_iterator_current(&entry, i));
|
||||
|
||||
while (entry != NULL) {
|
||||
if (strcmp(entry->path, "sub/file") == 0) {
|
||||
@ -339,7 +339,7 @@ void test_diff_iterator__tree_special_functions(void)
|
||||
rootoid, NULL);
|
||||
}
|
||||
|
||||
cl_git_pass(git_iterator_advance(i, &entry));
|
||||
cl_git_pass(git_iterator_advance(&entry, i));
|
||||
}
|
||||
|
||||
cl_assert_equal_i(4, cases);
|
||||
@ -364,8 +364,8 @@ static void index_iterator_test(
|
||||
git_repository *repo = cl_git_sandbox_init(sandbox);
|
||||
|
||||
cl_git_pass(git_repository_index(&index, repo));
|
||||
cl_git_pass(git_iterator_for_index_range(&i, index, 0, start, end));
|
||||
cl_git_pass(git_iterator_current(i, &entry));
|
||||
cl_git_pass(git_iterator_for_index(&i, index, 0, start, end));
|
||||
cl_git_pass(git_iterator_current(&entry, i));
|
||||
|
||||
while (entry != NULL) {
|
||||
if (expected_names != NULL)
|
||||
@ -378,7 +378,7 @@ static void index_iterator_test(
|
||||
}
|
||||
|
||||
count++;
|
||||
cl_git_pass(git_iterator_advance(i, &entry));
|
||||
cl_git_pass(git_iterator_advance(&entry, i));
|
||||
}
|
||||
|
||||
git_iterator_free(i);
|
||||
@ -538,14 +538,14 @@ static void workdir_iterator_test(
|
||||
int count = 0, count_all = 0, count_all_post_reset = 0;
|
||||
git_repository *repo = cl_git_sandbox_init(sandbox);
|
||||
|
||||
cl_git_pass(git_iterator_for_workdir_range(&i, repo, 0, start, end));
|
||||
cl_git_pass(git_iterator_current(i, &entry));
|
||||
cl_git_pass(git_iterator_for_workdir(&i, repo, 0, start, end));
|
||||
cl_git_pass(git_iterator_current(&entry, i));
|
||||
|
||||
while (entry != NULL) {
|
||||
int ignored = git_iterator_current_is_ignored(i);
|
||||
|
||||
if (S_ISDIR(entry->mode)) {
|
||||
cl_git_pass(git_iterator_advance_into_directory(i, &entry));
|
||||
cl_git_pass(git_iterator_advance_into(&entry, i));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -559,22 +559,22 @@ static void workdir_iterator_test(
|
||||
count++;
|
||||
count_all++;
|
||||
|
||||
cl_git_pass(git_iterator_advance(i, &entry));
|
||||
cl_git_pass(git_iterator_advance(&entry, i));
|
||||
}
|
||||
|
||||
cl_git_pass(git_iterator_reset(i, NULL, NULL));
|
||||
cl_git_pass(git_iterator_current(i, &entry));
|
||||
cl_git_pass(git_iterator_current(&entry, i));
|
||||
|
||||
while (entry != NULL) {
|
||||
if (S_ISDIR(entry->mode)) {
|
||||
cl_git_pass(git_iterator_advance_into_directory(i, &entry));
|
||||
cl_git_pass(git_iterator_advance_into(&entry, i));
|
||||
continue;
|
||||
}
|
||||
if (expected_names != NULL)
|
||||
cl_assert_equal_s(
|
||||
expected_names[count_all_post_reset], entry->path);
|
||||
count_all_post_reset++;
|
||||
cl_git_pass(git_iterator_advance(i, &entry));
|
||||
cl_git_pass(git_iterator_advance(&entry, i));
|
||||
}
|
||||
|
||||
git_iterator_free(i);
|
||||
@ -736,8 +736,8 @@ void test_diff_iterator__workdir_builtin_ignores(void)
|
||||
cl_git_mkfile("attr/sub/.git", "whatever");
|
||||
|
||||
cl_git_pass(
|
||||
git_iterator_for_workdir_range(&i, repo, 0, "dir", "sub/sub/file"));
|
||||
cl_git_pass(git_iterator_current(i, &entry));
|
||||
git_iterator_for_workdir(&i, repo, 0, "dir", "sub/sub/file"));
|
||||
cl_git_pass(git_iterator_current(&entry, i));
|
||||
|
||||
for (idx = 0; entry != NULL; ++idx) {
|
||||
int ignored = git_iterator_current_is_ignored(i);
|
||||
@ -746,9 +746,9 @@ void test_diff_iterator__workdir_builtin_ignores(void)
|
||||
cl_assert_(ignored == expected[idx].ignored, expected[idx].path);
|
||||
|
||||
if (!ignored && S_ISDIR(entry->mode))
|
||||
cl_git_pass(git_iterator_advance_into_directory(i, &entry));
|
||||
cl_git_pass(git_iterator_advance_into(&entry, i));
|
||||
else
|
||||
cl_git_pass(git_iterator_advance(i, &entry));
|
||||
cl_git_pass(git_iterator_advance(&entry, i));
|
||||
}
|
||||
|
||||
cl_assert(expected[idx].path == NULL);
|
||||
@ -764,17 +764,17 @@ static void check_wd_first_through_third_range(
|
||||
int idx;
|
||||
static const char *expected[] = { "FIRST", "second", "THIRD", NULL };
|
||||
|
||||
cl_git_pass(git_iterator_for_workdir_range(
|
||||
cl_git_pass(git_iterator_for_workdir(
|
||||
&i, repo, GIT_ITERATOR_IGNORE_CASE, start, end));
|
||||
cl_git_pass(git_iterator_current(i, &entry));
|
||||
cl_git_pass(git_iterator_current(&entry, i));
|
||||
|
||||
for (idx = 0; entry != NULL; ++idx) {
|
||||
cl_assert_equal_s(expected[idx], entry->path);
|
||||
|
||||
if (S_ISDIR(entry->mode))
|
||||
cl_git_pass(git_iterator_advance_into_directory(i, &entry));
|
||||
cl_git_pass(git_iterator_advance_into(&entry, i));
|
||||
else
|
||||
cl_git_pass(git_iterator_advance(i, &entry));
|
||||
cl_git_pass(git_iterator_advance(&entry, i));
|
||||
}
|
||||
|
||||
cl_assert(expected[idx] == NULL);
|
||||
@ -817,16 +817,16 @@ static void check_tree_range(
|
||||
|
||||
cl_git_pass(git_repository_head_tree(&head, repo));
|
||||
|
||||
cl_git_pass(git_iterator_for_tree_range(
|
||||
cl_git_pass(git_iterator_for_tree(
|
||||
&i, head,
|
||||
ignore_case ? GIT_ITERATOR_IGNORE_CASE : GIT_ITERATOR_DONT_IGNORE_CASE,
|
||||
start, end));
|
||||
|
||||
cl_git_pass(git_iterator_current(i, &entry));
|
||||
cl_git_pass(git_iterator_current(&entry, i));
|
||||
|
||||
for (count = 0; entry != NULL; ) {
|
||||
++count;
|
||||
cl_git_pass(git_iterator_advance(i, &entry));
|
||||
cl_git_pass(git_iterator_advance(&entry, i));
|
||||
}
|
||||
|
||||
cl_assert_equal_i(expected_count, count);
|
||||
@ -882,15 +882,15 @@ static void check_index_range(
|
||||
if (ignore_case != is_ignoring_case)
|
||||
cl_git_pass(git_index_set_caps(index, caps ^ GIT_INDEXCAP_IGNORE_CASE));
|
||||
|
||||
cl_git_pass(git_iterator_for_index_range(&i, index, 0, start, end));
|
||||
cl_git_pass(git_iterator_for_index(&i, index, 0, start, end));
|
||||
|
||||
cl_assert(git_iterator_ignore_case(i) == ignore_case);
|
||||
|
||||
cl_git_pass(git_iterator_current(i, &entry));
|
||||
cl_git_pass(git_iterator_current(&entry, i));
|
||||
|
||||
for (count = 0; entry != NULL; ) {
|
||||
++count;
|
||||
cl_git_pass(git_iterator_advance(i, &entry));
|
||||
cl_git_pass(git_iterator_advance(&entry, i));
|
||||
}
|
||||
|
||||
cl_assert_equal_i(expected_count, count);
|
||||
|
||||
210
tests-clar/repo/iterator.c
Normal file
210
tests-clar/repo/iterator.c
Normal file
@ -0,0 +1,210 @@
|
||||
#include "clar_libgit2.h"
|
||||
#include "iterator.h"
|
||||
#include "repository.h"
|
||||
|
||||
static git_repository *g_repo;
|
||||
|
||||
void test_repo_iterator__initialize(void)
|
||||
{
|
||||
g_repo = cl_git_sandbox_init("icase");
|
||||
}
|
||||
|
||||
void test_repo_iterator__cleanup(void)
|
||||
{
|
||||
cl_git_sandbox_cleanup();
|
||||
g_repo = NULL;
|
||||
}
|
||||
|
||||
static void expect_iterator_items(
|
||||
git_iterator *i, int expected_flat, int expected_total)
|
||||
{
|
||||
const git_index_entry *entry;
|
||||
int count;
|
||||
|
||||
count = 0;
|
||||
cl_git_pass(git_iterator_current(&entry, i));
|
||||
|
||||
while (entry != NULL) {
|
||||
count++;
|
||||
|
||||
cl_git_pass(git_iterator_advance(&entry, i));
|
||||
|
||||
if (count > expected_flat)
|
||||
break;
|
||||
}
|
||||
|
||||
cl_assert_equal_i(expected_flat, count);
|
||||
|
||||
cl_git_pass(git_iterator_reset(i, NULL, NULL));
|
||||
|
||||
count = 0;
|
||||
cl_git_pass(git_iterator_current(&entry, i));
|
||||
|
||||
while (entry != NULL) {
|
||||
count++;
|
||||
|
||||
if (entry->mode == GIT_FILEMODE_TREE)
|
||||
cl_git_pass(git_iterator_advance_into(&entry, i));
|
||||
else
|
||||
cl_git_pass(git_iterator_advance(&entry, i));
|
||||
|
||||
if (count > expected_total)
|
||||
break;
|
||||
}
|
||||
|
||||
cl_assert_equal_i(expected_total, count);
|
||||
}
|
||||
|
||||
/* Index contents (including pseudotrees):
|
||||
*
|
||||
* 0: a 5: F 10: k/ 16: L/
|
||||
* 1: B 6: g 11: k/1 17: L/1
|
||||
* 2: c 7: H 12: k/a 18: L/a
|
||||
* 3: D 8: i 13: k/B 19: L/B
|
||||
* 4: e 9: J 14: k/c 20: L/c
|
||||
* 15: k/D 21: L/D
|
||||
*
|
||||
* 0: B 5: L/ 11: a 16: k/
|
||||
* 1: D 6: L/1 12: c 17: k/1
|
||||
* 2: F 7: L/B 13: e 18: k/B
|
||||
* 3: H 8: L/D 14: g 19: k/D
|
||||
* 4: J 9: L/a 15: i 20: k/a
|
||||
* 10: L/c 21: k/c
|
||||
*/
|
||||
|
||||
void test_repo_iterator__index(void)
|
||||
{
|
||||
git_iterator *i;
|
||||
git_index *index;
|
||||
|
||||
cl_git_pass(git_repository_index(&index, g_repo));
|
||||
|
||||
/* normal index iteration */
|
||||
cl_git_pass(git_iterator_for_index(&i, index, 0, NULL, NULL));
|
||||
expect_iterator_items(i, 20, 20);
|
||||
git_iterator_free(i);
|
||||
|
||||
git_index_free(index);
|
||||
}
|
||||
|
||||
void test_repo_iterator__index_icase(void)
|
||||
{
|
||||
git_iterator *i;
|
||||
git_index *index;
|
||||
unsigned int caps;
|
||||
|
||||
cl_git_pass(git_repository_index(&index, g_repo));
|
||||
caps = git_index_caps(index);
|
||||
|
||||
/* force case sensitivity */
|
||||
cl_git_pass(git_index_set_caps(index, caps & ~GIT_INDEXCAP_IGNORE_CASE));
|
||||
|
||||
/* normal index iteration with range */
|
||||
cl_git_pass(git_iterator_for_index(&i, index, 0, "c", "k/D"));
|
||||
expect_iterator_items(i, 7, 7);
|
||||
git_iterator_free(i);
|
||||
|
||||
cl_git_pass(git_iterator_for_index(&i, index, 0, "k", "k/Z"));
|
||||
expect_iterator_items(i, 3, 3);
|
||||
git_iterator_free(i);
|
||||
|
||||
/* force case insensitivity */
|
||||
cl_git_pass(git_index_set_caps(index, caps | GIT_INDEXCAP_IGNORE_CASE));
|
||||
|
||||
/* normal index iteration with range */
|
||||
cl_git_pass(git_iterator_for_index(&i, index, 0, "c", "k/D"));
|
||||
expect_iterator_items(i, 13, 13);
|
||||
git_iterator_free(i);
|
||||
|
||||
cl_git_pass(git_iterator_for_index(&i, index, 0, "k", "k/Z"));
|
||||
expect_iterator_items(i, 5, 5);
|
||||
git_iterator_free(i);
|
||||
|
||||
cl_git_pass(git_index_set_caps(index, caps));
|
||||
git_index_free(index);
|
||||
}
|
||||
|
||||
void test_repo_iterator__tree(void)
|
||||
{
|
||||
git_iterator *i;
|
||||
git_tree *head;
|
||||
|
||||
cl_git_pass(git_repository_head_tree(&head, g_repo));
|
||||
|
||||
/* normal tree iteration */
|
||||
cl_git_pass(git_iterator_for_tree(&i, head, 0, NULL, NULL));
|
||||
expect_iterator_items(i, 20, 20);
|
||||
git_iterator_free(i);
|
||||
|
||||
git_tree_free(head);
|
||||
}
|
||||
|
||||
void test_repo_iterator__tree_icase(void)
|
||||
{
|
||||
git_iterator *i;
|
||||
git_tree *head;
|
||||
git_iterator_flag_t flag;
|
||||
|
||||
cl_git_pass(git_repository_head_tree(&head, g_repo));
|
||||
|
||||
flag = GIT_ITERATOR_DONT_IGNORE_CASE;
|
||||
|
||||
/* normal tree iteration with range */
|
||||
cl_git_pass(git_iterator_for_tree(&i, head, flag, "c", "k/D"));
|
||||
expect_iterator_items(i, 7, 7);
|
||||
git_iterator_free(i);
|
||||
|
||||
cl_git_pass(git_iterator_for_tree(&i, head, flag, "k", "k/Z"));
|
||||
expect_iterator_items(i, 3, 3);
|
||||
git_iterator_free(i);
|
||||
|
||||
flag = GIT_ITERATOR_IGNORE_CASE;
|
||||
|
||||
/* normal tree iteration with range */
|
||||
cl_git_pass(git_iterator_for_tree(&i, head, flag, "c", "k/D"));
|
||||
expect_iterator_items(i, 13, 13);
|
||||
git_iterator_free(i);
|
||||
|
||||
cl_git_pass(git_iterator_for_tree(&i, head, flag, "k", "k/Z"));
|
||||
expect_iterator_items(i, 5, 5);
|
||||
git_iterator_free(i);
|
||||
}
|
||||
|
||||
void test_repo_iterator__workdir(void)
|
||||
{
|
||||
git_iterator *i;
|
||||
|
||||
/* normal workdir iteration uses explicit tree expansion */
|
||||
cl_git_pass(git_iterator_for_workdir(
|
||||
&i, g_repo, 0, NULL, NULL));
|
||||
expect_iterator_items(i, 12, 22);
|
||||
git_iterator_free(i);
|
||||
}
|
||||
|
||||
void test_repo_iterator__workdir_icase(void)
|
||||
{
|
||||
git_iterator *i;
|
||||
git_iterator_flag_t flag;
|
||||
|
||||
flag = GIT_ITERATOR_DONT_IGNORE_CASE;
|
||||
|
||||
/* normal workdir iteration with range */
|
||||
cl_git_pass(git_iterator_for_workdir(&i, g_repo, flag, "c", "k/D"));
|
||||
expect_iterator_items(i, 5, 8);
|
||||
git_iterator_free(i);
|
||||
|
||||
cl_git_pass(git_iterator_for_workdir(&i, g_repo, flag, "k", "k/Z"));
|
||||
expect_iterator_items(i, 1, 4);
|
||||
git_iterator_free(i);
|
||||
|
||||
flag = GIT_ITERATOR_IGNORE_CASE;
|
||||
|
||||
/* normal workdir iteration with range */
|
||||
cl_git_pass(git_iterator_for_workdir(&i, g_repo, flag, "c", "k/D"));
|
||||
expect_iterator_items(i, 9, 14);
|
||||
git_iterator_free(i);
|
||||
|
||||
cl_git_pass(git_iterator_for_workdir(&i, g_repo, flag, "k", "k/Z"));
|
||||
expect_iterator_items(i, 1, 6);
|
||||
git_iterator_free(i);
|
||||
}
|
||||
1
tests-clar/resources/icase/.gitted/HEAD
Normal file
1
tests-clar/resources/icase/.gitted/HEAD
Normal file
@ -0,0 +1 @@
|
||||
ref: refs/heads/master
|
||||
7
tests-clar/resources/icase/.gitted/config
Normal file
7
tests-clar/resources/icase/.gitted/config
Normal file
@ -0,0 +1,7 @@
|
||||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = false
|
||||
logallrefupdates = true
|
||||
ignorecase = true
|
||||
precomposeunicode = false
|
||||
1
tests-clar/resources/icase/.gitted/description
Normal file
1
tests-clar/resources/icase/.gitted/description
Normal file
@ -0,0 +1 @@
|
||||
Unnamed repository; edit this file 'description' to name the repository.
|
||||
BIN
tests-clar/resources/icase/.gitted/index
Normal file
BIN
tests-clar/resources/icase/.gitted/index
Normal file
Binary file not shown.
6
tests-clar/resources/icase/.gitted/info/exclude
Normal file
6
tests-clar/resources/icase/.gitted/info/exclude
Normal file
@ -0,0 +1,6 @@
|
||||
# git ls-files --others --exclude-from=.git/info/exclude
|
||||
# Lines that start with '#' are comments.
|
||||
# For a project mostly in C, the following would be a good set of
|
||||
# exclude patterns (uncomment them if you want to use them):
|
||||
# *.[oa]
|
||||
# *~
|
||||
1
tests-clar/resources/icase/.gitted/logs/HEAD
Normal file
1
tests-clar/resources/icase/.gitted/logs/HEAD
Normal file
@ -0,0 +1 @@
|
||||
0000000000000000000000000000000000000000 76d6e1d231b1085fcce151427e9899335de74be6 Russell Belfer <rb@github.com> 1359157123 -0800 commit (initial): initial commit
|
||||
@ -0,0 +1 @@
|
||||
0000000000000000000000000000000000000000 76d6e1d231b1085fcce151427e9899335de74be6 Russell Belfer <rb@github.com> 1359157123 -0800 commit (initial): initial commit
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,3 @@
|
||||
x•ЌЫ 1EэNУЂ’cІ ‹X‚dЖ‰ИИ&э°/зњЛuЯsгсФ›8±и}2о
SH–‚,С
|
||||
am1Р‹EЕС·Ъа9ЋCJЃ‡”$
nЌопЬ·A®ы
|
||||
ЖбbРла¬ѓЦj®уЇOф_SеOо9ш%Ф)Њ9љ
|
||||
Binary file not shown.
1
tests-clar/resources/icase/.gitted/refs/heads/master
Normal file
1
tests-clar/resources/icase/.gitted/refs/heads/master
Normal file
@ -0,0 +1 @@
|
||||
76d6e1d231b1085fcce151427e9899335de74be6
|
||||
1
tests-clar/resources/icase/B
Normal file
1
tests-clar/resources/icase/B
Normal file
@ -0,0 +1 @@
|
||||
start
|
||||
1
tests-clar/resources/icase/D
Normal file
1
tests-clar/resources/icase/D
Normal file
@ -0,0 +1 @@
|
||||
start
|
||||
1
tests-clar/resources/icase/F
Normal file
1
tests-clar/resources/icase/F
Normal file
@ -0,0 +1 @@
|
||||
start
|
||||
1
tests-clar/resources/icase/H
Normal file
1
tests-clar/resources/icase/H
Normal file
@ -0,0 +1 @@
|
||||
start
|
||||
1
tests-clar/resources/icase/J
Normal file
1
tests-clar/resources/icase/J
Normal file
@ -0,0 +1 @@
|
||||
start
|
||||
1
tests-clar/resources/icase/L/1
Normal file
1
tests-clar/resources/icase/L/1
Normal file
@ -0,0 +1 @@
|
||||
sub
|
||||
1
tests-clar/resources/icase/L/B
Normal file
1
tests-clar/resources/icase/L/B
Normal file
@ -0,0 +1 @@
|
||||
sub
|
||||
1
tests-clar/resources/icase/L/D
Normal file
1
tests-clar/resources/icase/L/D
Normal file
@ -0,0 +1 @@
|
||||
sub
|
||||
1
tests-clar/resources/icase/L/a
Normal file
1
tests-clar/resources/icase/L/a
Normal file
@ -0,0 +1 @@
|
||||
sub
|
||||
1
tests-clar/resources/icase/L/c
Normal file
1
tests-clar/resources/icase/L/c
Normal file
@ -0,0 +1 @@
|
||||
sub
|
||||
1
tests-clar/resources/icase/a
Normal file
1
tests-clar/resources/icase/a
Normal file
@ -0,0 +1 @@
|
||||
start
|
||||
1
tests-clar/resources/icase/c
Normal file
1
tests-clar/resources/icase/c
Normal file
@ -0,0 +1 @@
|
||||
start
|
||||
1
tests-clar/resources/icase/e
Normal file
1
tests-clar/resources/icase/e
Normal file
@ -0,0 +1 @@
|
||||
start
|
||||
1
tests-clar/resources/icase/g
Normal file
1
tests-clar/resources/icase/g
Normal file
@ -0,0 +1 @@
|
||||
start
|
||||
1
tests-clar/resources/icase/i
Normal file
1
tests-clar/resources/icase/i
Normal file
@ -0,0 +1 @@
|
||||
start
|
||||
1
tests-clar/resources/icase/k/1
Normal file
1
tests-clar/resources/icase/k/1
Normal file
@ -0,0 +1 @@
|
||||
sub
|
||||
1
tests-clar/resources/icase/k/B
Normal file
1
tests-clar/resources/icase/k/B
Normal file
@ -0,0 +1 @@
|
||||
sub
|
||||
1
tests-clar/resources/icase/k/D
Normal file
1
tests-clar/resources/icase/k/D
Normal file
@ -0,0 +1 @@
|
||||
sub
|
||||
1
tests-clar/resources/icase/k/a
Normal file
1
tests-clar/resources/icase/k/a
Normal file
@ -0,0 +1 @@
|
||||
sub
|
||||
1
tests-clar/resources/icase/k/c
Normal file
1
tests-clar/resources/icase/k/c
Normal file
@ -0,0 +1 @@
|
||||
sub
|
||||
@ -274,6 +274,7 @@ void test_status_worktree__issue_592(void)
|
||||
repo = cl_git_sandbox_init("issue_592");
|
||||
cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "l.txt"));
|
||||
cl_git_pass(p_unlink(git_buf_cstr(&path)));
|
||||
cl_assert(!git_path_exists("issue_592/l.txt"));
|
||||
|
||||
cl_git_pass(git_status_foreach(repo, cb_status__check_592, "l.txt"));
|
||||
|
||||
@ -288,6 +289,7 @@ void test_status_worktree__issue_592_2(void)
|
||||
repo = cl_git_sandbox_init("issue_592");
|
||||
cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "c/a.txt"));
|
||||
cl_git_pass(p_unlink(git_buf_cstr(&path)));
|
||||
cl_assert(!git_path_exists("issue_592/c/a.txt"));
|
||||
|
||||
cl_git_pass(git_status_foreach(repo, cb_status__check_592, "c/a.txt"));
|
||||
|
||||
@ -303,6 +305,7 @@ void test_status_worktree__issue_592_3(void)
|
||||
|
||||
cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(repo), "c"));
|
||||
cl_git_pass(git_futils_rmdir_r(git_buf_cstr(&path), NULL, GIT_RMDIR_REMOVE_FILES));
|
||||
cl_assert(!git_path_exists("issue_592/c/a.txt"));
|
||||
|
||||
cl_git_pass(git_status_foreach(repo, cb_status__check_592, "c/a.txt"));
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user