Commit bad68c0a by Russell Belfer

Add iterator for git_index object

The index iterator could previously only be created from a repo
object, but this allows creating an iterator from a `git_index`
object instead (while keeping, though renaming, the old function).
parent 5735bf5e
...@@ -777,6 +777,19 @@ int git_diff_tree_to_tree( ...@@ -777,6 +777,19 @@ int git_diff_tree_to_tree(
); );
} }
int git_diff__tree_to_index(
git_diff_list **diff,
git_tree *tree,
git_index *index,
const git_diff_options *opts)
{
DIFF_FROM_ITERATORS(
git_repository *repo = git_index_owner(index),
git_iterator_for_index_range(&a, index, pfx, pfx),
git_iterator_for_tree_range(&b, repo, tree, pfx, pfx)
);
}
int git_diff_index_to_tree( int git_diff_index_to_tree(
git_diff_list **diff, git_diff_list **diff,
git_repository *repo, git_repository *repo,
...@@ -786,7 +799,7 @@ int git_diff_index_to_tree( ...@@ -786,7 +799,7 @@ int git_diff_index_to_tree(
DIFF_FROM_ITERATORS( DIFF_FROM_ITERATORS(
assert(repo && diff), assert(repo && diff),
git_iterator_for_tree_range(&a, repo, old_tree, pfx, pfx), git_iterator_for_tree_range(&a, repo, old_tree, pfx, pfx),
git_iterator_for_index_range(&b, repo, pfx, pfx) git_iterator_for_repo_index_range(&b, repo, pfx, pfx)
); );
} }
...@@ -797,7 +810,7 @@ int git_diff_workdir_to_index( ...@@ -797,7 +810,7 @@ int git_diff_workdir_to_index(
{ {
DIFF_FROM_ITERATORS( DIFF_FROM_ITERATORS(
assert(repo && diff), assert(repo && diff),
git_iterator_for_index_range(&a, repo, pfx, pfx), git_iterator_for_repo_index_range(&a, repo, pfx, pfx),
git_iterator_for_workdir_range(&b, repo, pfx, pfx) git_iterator_for_workdir_range(&b, repo, pfx, pfx)
); );
} }
......
...@@ -61,5 +61,11 @@ extern bool git_diff_delta__should_skip( ...@@ -61,5 +61,11 @@ extern bool git_diff_delta__should_skip(
extern int git_diff__oid_for_file( extern int git_diff__oid_for_file(
git_repository *, const char *, uint16_t, git_off_t, git_oid *); git_repository *, const char *, uint16_t, git_off_t, git_oid *);
extern int git_diff__tree_to_index(
git_diff_list **diff,
git_tree *tree,
git_index *index,
const git_diff_options *opts);
#endif #endif
...@@ -835,7 +835,9 @@ unsigned int git_index__prefix_position(git_index *index, const char *path) ...@@ -835,7 +835,9 @@ unsigned int git_index__prefix_position(git_index *index, const char *path)
srch_key.path = path; srch_key.path = path;
srch_key.stage = 0; srch_key.stage = 0;
git_vector_bsearch3(&pos, &index->entries, index->entries_search, &srch_key); git_vector_sort(&index->entries);
git_vector_bsearch3(
&pos, &index->entries, index->entries_search, &srch_key);
return pos; return pos;
} }
......
...@@ -330,6 +330,7 @@ typedef struct { ...@@ -330,6 +330,7 @@ typedef struct {
git_iterator base; git_iterator base;
git_index *index; git_index *index;
unsigned int current; unsigned int current;
bool free_index;
} index_iterator; } index_iterator;
static int index_iterator__current( static int index_iterator__current(
...@@ -387,32 +388,47 @@ static int index_iterator__reset(git_iterator *self) ...@@ -387,32 +388,47 @@ static int index_iterator__reset(git_iterator *self)
static void index_iterator__free(git_iterator *self) static void index_iterator__free(git_iterator *self)
{ {
index_iterator *ii = (index_iterator *)self; index_iterator *ii = (index_iterator *)self;
git_index_free(ii->index); if (ii->free_index)
git_index_free(ii->index);
ii->index = NULL; ii->index = NULL;
} }
int git_iterator_for_index_range( int git_iterator_for_index_range(
git_iterator **iter, git_iterator **iter,
git_repository *repo, git_index *index,
const char *start, const char *start,
const char *end) const char *end)
{ {
int error;
index_iterator *ii; index_iterator *ii;
ITERATOR_BASE_INIT(ii, index, INDEX); ITERATOR_BASE_INIT(ii, index, INDEX);
if ((error = git_repository_index(&ii->index, repo)) < 0) ii->index = index;
git__free(ii); ii->base.ignore_case = ii->index->ignore_case;
else { ii->current = start ? git_index__prefix_position(ii->index, start) : 0;
ii->base.ignore_case = ii->index->ignore_case;
ii->current = start ? git_index__prefix_position(ii->index, start) : 0;
*iter = (git_iterator *)ii;
}
return error; *iter = (git_iterator *)ii;
return 0;
} }
int git_iterator_for_repo_index_range(
git_iterator **iter,
git_repository *repo,
const char *start,
const char *end)
{
int error;
git_index *index;
if ((error = git_repository_index(&index, repo)) < 0)
return error;
if (!(error = git_iterator_for_index_range(iter, index, start, end)))
((index_iterator *)(*iter))->free_index = true;
return error;
}
typedef struct workdir_iterator_frame workdir_iterator_frame; typedef struct workdir_iterator_frame workdir_iterator_frame;
struct workdir_iterator_frame { struct workdir_iterator_frame {
...@@ -690,24 +706,21 @@ int git_iterator_for_workdir_range( ...@@ -690,24 +706,21 @@ int git_iterator_for_workdir_range(
assert(iter && repo); assert(iter && repo);
if ((error = git_repository__ensure_not_bare(repo, "scan working directory")) < 0) if ((error = git_repository__ensure_not_bare(
repo, "scan working directory")) < 0)
return error; return error;
ITERATOR_BASE_INIT(wi, workdir, WORKDIR); ITERATOR_BASE_INIT(wi, workdir, WORKDIR);
wi->repo = repo; wi->repo = repo;
if ((error = git_repository_index(&index, repo)) < 0) { if ((error = git_repository_index__weakptr(&index, repo)) < 0) {
git__free(wi); git__free(wi);
return error; return error;
} }
/* Set the ignore_case flag for the workdir iterator to match /* Match ignore_case flag for iterator to that of the index */
* that of the index. */
wi->base.ignore_case = index->ignore_case; wi->base.ignore_case = index->ignore_case;
git_index_free(index);
if (git_buf_sets(&wi->path, git_repository_workdir(repo)) < 0 || if (git_buf_sets(&wi->path, git_repository_workdir(repo)) < 0 ||
git_path_to_dir(&wi->path) < 0 || git_path_to_dir(&wi->path) < 0 ||
git_ignore__for_path(repo, "", &wi->ignores) < 0) git_ignore__for_path(repo, "", &wi->ignores) < 0)
......
...@@ -52,13 +52,23 @@ GIT_INLINE(int) git_iterator_for_tree( ...@@ -52,13 +52,23 @@ GIT_INLINE(int) git_iterator_for_tree(
} }
extern int git_iterator_for_index_range( extern int git_iterator_for_index_range(
git_iterator **iter, git_repository *repo, git_iterator **iter, git_index *index,
const char *start, const char *end); const char *start, const char *end);
GIT_INLINE(int) git_iterator_for_index( GIT_INLINE(int) git_iterator_for_index(
git_iterator **iter, git_index *index)
{
return git_iterator_for_index_range(iter, index, NULL, NULL);
}
extern int git_iterator_for_repo_index_range(
git_iterator **iter, git_repository *repo,
const char *start, const char *end);
GIT_INLINE(int) git_iterator_for_repo_index(
git_iterator **iter, git_repository *repo) git_iterator **iter, git_repository *repo)
{ {
return git_iterator_for_index_range(iter, repo, NULL, NULL); return git_iterator_for_repo_index_range(iter, repo, NULL, NULL);
} }
extern int git_iterator_for_workdir_range( extern int git_iterator_for_workdir_range(
......
...@@ -1118,7 +1118,7 @@ static int load_submodule_config_from_index( ...@@ -1118,7 +1118,7 @@ static int load_submodule_config_from_index(
git_iterator *i; git_iterator *i;
const git_index_entry *entry; const git_index_entry *entry;
if ((error = git_iterator_for_index(&i, repo)) < 0) if ((error = git_iterator_for_repo_index(&i, repo)) < 0)
return error; return error;
error = git_iterator_current(i, &entry); error = git_iterator_current(i, &entry);
......
...@@ -29,17 +29,26 @@ void git_vector_swap(git_vector *a, git_vector *b); ...@@ -29,17 +29,26 @@ void git_vector_swap(git_vector *a, git_vector *b);
void git_vector_sort(git_vector *v); void git_vector_sort(git_vector *v);
/** Linear search for matching entry using internal comparison function */
int git_vector_search(git_vector *v, const void *entry); int git_vector_search(git_vector *v, const void *entry);
/** Linear search for matching entry using explicit comparison function */
int git_vector_search2(git_vector *v, git_vector_cmp cmp, const void *key); int git_vector_search2(git_vector *v, git_vector_cmp cmp, const void *key);
/**
* Binary search for matching entry using explicit comparison function that
* returns position where item would go if not found.
*/
int git_vector_bsearch3( int git_vector_bsearch3(
unsigned int *at_pos, git_vector *v, git_vector_cmp cmp, const void *key); unsigned int *at_pos, git_vector *v, git_vector_cmp cmp, const void *key);
/** Binary search for matching entry using internal comparison function */
GIT_INLINE(int) git_vector_bsearch(git_vector *v, const void *key) GIT_INLINE(int) git_vector_bsearch(git_vector *v, const void *key)
{ {
return git_vector_bsearch3(NULL, v, v->_cmp, key); return git_vector_bsearch3(NULL, v, v->_cmp, key);
} }
/** Binary search for matching entry using explicit comparison function */
GIT_INLINE(int) git_vector_bsearch2( GIT_INLINE(int) git_vector_bsearch2(
git_vector *v, git_vector_cmp cmp, const void *key) git_vector *v, git_vector_cmp cmp, const void *key)
{ {
......
...@@ -350,7 +350,7 @@ static void index_iterator_test( ...@@ -350,7 +350,7 @@ static void index_iterator_test(
int count = 0; int count = 0;
git_repository *repo = cl_git_sandbox_init(sandbox); git_repository *repo = cl_git_sandbox_init(sandbox);
cl_git_pass(git_iterator_for_index_range(&i, repo, start, end)); cl_git_pass(git_iterator_for_repo_index_range(&i, repo, start, end));
cl_git_pass(git_iterator_current(i, &entry)); cl_git_pass(git_iterator_current(i, &entry));
while (entry != NULL) { while (entry != NULL) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment