summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2012-12-06 13:26:58 -0800
committerRussell Belfer <rb@github.com>2012-12-10 15:38:28 -0800
commit9950d27ab62cc31a3ebf1944fd33dd65432be790 (patch)
treeca7c8efe8b4a5d6e2adc0ae66e26d22a03c76155 /src
parent4cbe9a1be18338b7e223b42e6019c58181204123 (diff)
downloadlibgit2-9950d27ab62cc31a3ebf1944fd33dd65432be790.tar.gz
Clean up iterator APIs
This removes the need to explicitly pass the repo into iterators where the repo is implied by the other parameters. This moves the repo to be owned by the parent struct. Also, this has some iterator related updates to the internal diff API to lay the groundwork for checkout improvements.
Diffstat (limited to 'src')
-rw-r--r--src/checkout.c3
-rw-r--r--src/diff.c21
-rw-r--r--src/diff.h6
-rw-r--r--src/index.c3
-rw-r--r--src/iterator.c14
-rw-r--r--src/iterator.h21
-rw-r--r--src/notes.c2
-rw-r--r--src/submodule.c2
-rw-r--r--src/tree.c9
9 files changed, 48 insertions, 33 deletions
diff --git a/src/checkout.c b/src/checkout.c
index 33de7adf3..d9f0f8fad 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -448,8 +448,7 @@ static int checkout_get_actions(
!(error == GIT_ENOTFOUND || error == GIT_EORPHANEDHEAD))
return -1;
- if ((error = git_iterator_for_tree_range(
- &hiter, data->repo, head, pfx, pfx)) < 0)
+ if ((error = git_iterator_for_tree_range(&hiter, head, pfx, pfx)) < 0)
goto fail;
if ((diff->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) != 0 &&
diff --git a/src/diff.c b/src/diff.c
index c4bfc3687..822ae5b09 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -570,7 +570,7 @@ static int diff_list_init_from_iterators(
return 0;
}
-static int diff_from_iterators(
+int git_diff__from_iterators(
git_diff_list **diff_ptr,
git_repository *repo,
git_iterator *old_iter,
@@ -610,9 +610,10 @@ static int diff_from_iterators(
/* run iterators building diffs */
while (oitem || nitem) {
+ int cmp = oitem ? (nitem ? diff->entrycomp(oitem, nitem) : -1) : 1;
/* create DELETED records for old items not matched in new */
- if (oitem && (!nitem || diff->entrycomp(oitem, nitem) < 0)) {
+ if (cmp < 0) {
if (diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem) < 0)
goto fail;
@@ -637,7 +638,7 @@ static int diff_from_iterators(
/* create ADDED, TRACKED, or IGNORED records for new items not
* matched in old (and/or descend into directories as needed)
*/
- else if (nitem && (!oitem || diff->entrycomp(oitem, nitem) > 0)) {
+ else if (cmp > 0) {
git_delta_t delta_type = GIT_DELTA_UNTRACKED;
/* check if contained in ignored parent directory */
@@ -733,7 +734,7 @@ static int diff_from_iterators(
* (or ADDED and DELETED pair if type changed)
*/
else {
- assert(oitem && nitem && diff->entrycomp(oitem, nitem) == 0);
+ assert(oitem && nitem && cmp == 0);
if (maybe_modified(old_iter, oitem, new_iter, nitem, diff) < 0 ||
git_iterator_advance(old_iter, &oitem) < 0 ||
@@ -759,8 +760,8 @@ fail:
git_iterator *a = NULL, *b = NULL; \
char *pfx = opts ? git_pathspec_prefix(&opts->pathspec) : NULL; \
GITERR_CHECK_VERSION(opts, GIT_DIFF_OPTIONS_VERSION, "git_diff_options"); \
- if (!(error = MAKE_FIRST) && !(error = MAKE_SECOND)) \
- error = diff_from_iterators(diff, repo, a, b, opts); \
+ if (!(error = MAKE_FIRST) && !(error = MAKE_SECOND)) \
+ error = git_diff__from_iterators(diff, repo, a, b, opts); \
git__free(pfx); git_iterator_free(a); git_iterator_free(b); \
} while (0)
@@ -776,8 +777,8 @@ int git_diff_tree_to_tree(
assert(diff && repo);
DIFF_FROM_ITERATORS(
- git_iterator_for_tree_range(&a, repo, old_tree, pfx, pfx),
- git_iterator_for_tree_range(&b, repo, new_tree, pfx, pfx)
+ git_iterator_for_tree_range(&a, old_tree, pfx, pfx),
+ git_iterator_for_tree_range(&b, new_tree, pfx, pfx)
);
return error;
@@ -798,7 +799,7 @@ int git_diff_index_to_tree(
return error;
DIFF_FROM_ITERATORS(
- git_iterator_for_tree_range(&a, repo, old_tree, pfx, pfx),
+ git_iterator_for_tree_range(&a, old_tree, pfx, pfx),
git_iterator_for_index_range(&b, index, pfx, pfx)
);
@@ -838,7 +839,7 @@ int git_diff_workdir_to_tree(
assert(diff && repo);
DIFF_FROM_ITERATORS(
- git_iterator_for_tree_range(&a, repo, old_tree, pfx, pfx),
+ git_iterator_for_tree_range(&a, old_tree, pfx, pfx),
git_iterator_for_workdir_range(&b, repo, pfx, pfx)
);
diff --git a/src/diff.h b/src/diff.h
index f93bab18d..8f5ea3485 100644
--- a/src/diff.h
+++ b/src/diff.h
@@ -61,6 +61,12 @@ extern bool git_diff_delta__should_skip(
extern int git_diff__oid_for_file(
git_repository *, const char *, uint16_t, git_off_t, git_oid *);
+extern int git_diff__from_iterators(
+ git_diff_list **diff_ptr,
+ git_repository *repo,
+ git_iterator *old_iter,
+ git_iterator *new_iter,
+ const git_diff_options *opts);
#endif
diff --git a/src/index.c b/src/index.c
index f3ced9e39..1e5b28002 100644
--- a/src/index.c
+++ b/src/index.c
@@ -1641,8 +1641,7 @@ int git_index_read_tree_match(
pfx = git_pathspec_prefix(strspec);
- if ((error = git_iterator_for_tree_range(
- &iter, INDEX_OWNER(index), tree, pfx, pfx)) < 0 ||
+ if ((error = git_iterator_for_tree_range(&iter, tree, pfx, pfx)) < 0 ||
(error = git_iterator_current(iter, &entry)) < 0)
goto cleanup;
diff --git a/src/iterator.c b/src/iterator.c
index 0fdf0c69d..e2bf4cfdb 100644
--- a/src/iterator.c
+++ b/src/iterator.c
@@ -18,7 +18,7 @@
(P)->base.type = GIT_ITERATOR_ ## NAME_UC; \
(P)->base.start = start ? git__strdup(start) : NULL; \
(P)->base.end = end ? git__strdup(end) : NULL; \
- (P)->base.ignore_case = 0; \
+ (P)->base.ignore_case = false; \
(P)->base.current = NAME_LC ## _iterator__current; \
(P)->base.at_end = NAME_LC ## _iterator__at_end; \
(P)->base.advance = NAME_LC ## _iterator__advance; \
@@ -91,7 +91,6 @@ struct tree_iterator_frame {
typedef struct {
git_iterator base;
- git_repository *repo;
tree_iterator_frame *stack, *tail;
git_index_entry entry;
git_buf path;
@@ -205,7 +204,7 @@ static int tree_iterator__expand_tree(tree_iterator *ti)
git__prefixcmp(ti->path.ptr, ti->base.end) > 0)
return tree_iterator__to_end(ti);
- if ((error = git_tree_lookup(&subtree, ti->repo, &te->oid)) < 0)
+ if ((error = git_tree_lookup(&subtree, ti->base.repo, &te->oid)) < 0)
return error;
relpath = NULL;
@@ -302,7 +301,6 @@ static int tree_iterator__reset(git_iterator *self)
int git_iterator_for_tree_range(
git_iterator **iter,
- git_repository *repo,
git_tree *tree,
const char *start,
const char *end)
@@ -315,7 +313,7 @@ int git_iterator_for_tree_range(
ITERATOR_BASE_INIT(ti, tree, TREE);
- ti->repo = repo;
+ ti->base.repo = git_tree_owner(tree);
ti->stack = ti->tail = tree_iterator__alloc_frame(tree, ti->base.start);
if ((error = tree_iterator__expand_tree(ti)) < 0)
@@ -424,6 +422,7 @@ int git_iterator_for_index_range(
ITERATOR_BASE_INIT(ii, index, INDEX);
ii->index = index;
+ ii->base.repo = git_index_owner(index);
ii->base.ignore_case = ii->index->ignore_case;
index_iterator__reset((git_iterator *)ii);
@@ -461,7 +460,6 @@ struct workdir_iterator_frame {
typedef struct {
git_iterator base;
- git_repository *repo;
size_t root_len;
workdir_iterator_frame *stack;
git_ignores ignores;
@@ -716,7 +714,7 @@ static int workdir_iterator__update_entry(workdir_iterator *wi)
/* detect submodules */
if (S_ISDIR(wi->entry.mode)) {
- int res = git_submodule_lookup(NULL, wi->repo, wi->entry.path);
+ int res = git_submodule_lookup(NULL, wi->base.repo, wi->entry.path);
bool is_submodule = (res == 0);
if (res == GIT_ENOTFOUND)
giterr_clear();
@@ -750,7 +748,7 @@ int git_iterator_for_workdir_range(
return error;
ITERATOR_BASE_INIT(wi, workdir, WORKDIR);
- wi->repo = repo;
+ wi->base.repo = repo;
if ((error = git_repository_index__weakptr(&index, repo)) < 0) {
git__free(wi);
diff --git a/src/iterator.h b/src/iterator.h
index 77ead76cc..07cce5a5a 100644
--- a/src/iterator.h
+++ b/src/iterator.h
@@ -28,32 +28,33 @@ typedef enum {
struct git_iterator {
git_iterator_type_t type;
+ git_repository *repo;
char *start;
char *end;
+ bool ignore_case;
+
int (*current)(git_iterator *, const git_index_entry **);
int (*at_end)(git_iterator *);
int (*advance)(git_iterator *, const git_index_entry **);
int (*seek)(git_iterator *, const char *prefix);
int (*reset)(git_iterator *);
void (*free)(git_iterator *);
- unsigned int ignore_case:1;
};
extern int git_iterator_for_nothing(git_iterator **iter);
extern int git_iterator_for_tree_range(
- git_iterator **iter, git_repository *repo, git_tree *tree,
+ git_iterator **iter, git_tree *tree,
const char *start, const char *end);
GIT_INLINE(int) git_iterator_for_tree(
- git_iterator **iter, git_repository *repo, git_tree *tree)
+ git_iterator **iter, git_tree *tree)
{
- return git_iterator_for_tree_range(iter, repo, tree, NULL, NULL);
+ return git_iterator_for_tree_range(iter, tree, NULL, NULL);
}
extern int git_iterator_for_index_range(
- git_iterator **iter, git_index *index,
- const char *start, const char *end);
+ git_iterator **iter, git_index *index, const char *start, const char *end);
GIT_INLINE(int) git_iterator_for_index(
git_iterator **iter, git_index *index)
@@ -90,7 +91,8 @@ GIT_INLINE(int) git_iterator_spoolandsort(
git_iterator **iter, git_iterator *towrap,
git_vector_cmp comparer, bool ignore_case)
{
- return git_iterator_spoolandsort_range(iter, towrap, comparer, ignore_case, NULL, NULL);
+ return git_iterator_spoolandsort_range(
+ iter, towrap, comparer, ignore_case, NULL, NULL);
}
/* Entry is not guaranteed to be fully populated. For a tree iterator,
@@ -149,6 +151,11 @@ GIT_INLINE(git_iterator_type_t) git_iterator_type(git_iterator *iter)
return iter->type;
}
+GIT_INLINE(git_repository *) git_iterator_owner(git_iterator *iter)
+{
+ return iter->repo;
+}
+
extern int git_iterator_current_tree_entry(
git_iterator *iter, const git_tree_entry **tree_entry);
diff --git a/src/notes.c b/src/notes.c
index f96b5b139..8a27bdbf5 100644
--- a/src/notes.c
+++ b/src/notes.c
@@ -593,7 +593,7 @@ int git_note_foreach(
if (!(error = retrieve_note_tree_and_commit(
&tree, &commit, repo, &notes_ref)) &&
- !(error = git_iterator_for_tree(&iter, repo, tree)))
+ !(error = git_iterator_for_tree(&iter, tree)))
error = git_iterator_current(iter, &item);
while (!error && item) {
diff --git a/src/submodule.c b/src/submodule.c
index 21a1875c2..3d9950d58 100644
--- a/src/submodule.c
+++ b/src/submodule.c
@@ -1156,7 +1156,7 @@ 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, repo, head)) < 0) {
+ if ((error = git_iterator_for_tree(&i, head)) < 0) {
git_tree_free(head);
return error;
}
diff --git a/src/tree.c b/src/tree.c
index efb991df1..944992fea 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -207,9 +207,14 @@ void git_tree__free(git_tree *tree)
git__free(tree);
}
-const git_oid *git_tree_id(const git_tree *c)
+const git_oid *git_tree_id(const git_tree *t)
{
- return git_object_id((const git_object *)c);
+ return git_object_id((const git_object *)t);
+}
+
+git_repository *git_tree_owner(const git_tree *t)
+{
+ return git_object_owner((const git_object *)t);
}
git_filemode_t git_tree_entry_filemode(const git_tree_entry *entry)