summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2015-09-08 11:50:08 -0400
committerEdward Thomson <ethomson@edwardthomson.com>2015-09-08 11:50:08 -0400
commit2964cbeae14f52a42f82b5bf6fbb22cfcb5bd4c9 (patch)
tree0544ede140e628e85691d3a8a6886cb97c38cddc
parente1d27bcaafaadf4ef5eeae19c96835c6663c4289 (diff)
parentc097f7173daced0f86fd816a72ad5fc0f636484a (diff)
downloadlibgit2-2964cbeae14f52a42f82b5bf6fbb22cfcb5bd4c9.tar.gz
Merge pull request #3381 from leoyanggit/index_directory_iterator
New feature: add the ablility to iterate through a directory in index
-rw-r--r--include/git2/index.h11
-rw-r--r--src/index.c24
-rw-r--r--tests/index/tests.c21
3 files changed, 56 insertions, 0 deletions
diff --git a/include/git2/index.h b/include/git2/index.h
index 7caf3ed78..176ba301e 100644
--- a/include/git2/index.h
+++ b/include/git2/index.h
@@ -643,6 +643,17 @@ GIT_EXTERN(int) git_index_update_all(
*/
GIT_EXTERN(int) git_index_find(size_t *at_pos, git_index *index, const char *path);
+/**
+ * Find the first position of any entries matching a prefix. To find the first position
+ * of a path inside a given folder, suffix the prefix with a '/'.
+ *
+ * @param at_pos the address to which the position of the index entry is written (optional)
+ * @param index an existing index object
+ * @param prefix the prefix to search for
+ * @return 0 with valid value in at_pos; an error code otherwise
+ */
+GIT_EXTERN(int) git_index_find_prefix(size_t *at_pos, git_index *index, const char *prefix);
+
/**@}*/
/** @name Conflict Index Entry Functions
diff --git a/src/index.c b/src/index.c
index 6be73d2c7..20a6c934b 100644
--- a/src/index.c
+++ b/src/index.c
@@ -1466,6 +1466,30 @@ int git_index_remove_directory(git_index *index, const char *dir, int stage)
return error;
}
+int git_index_find_prefix(size_t *at_pos, git_index *index, const char *prefix)
+{
+ int error = 0;
+ size_t pos;
+ const git_index_entry *entry;
+
+ if (git_mutex_lock(&index->lock) < 0) {
+ giterr_set(GITERR_OS, "Failed to lock index");
+ return -1;
+ }
+
+ index_find(&pos, index, prefix, strlen(prefix), GIT_INDEX_STAGE_ANY, false);
+ entry = git_vector_get(&index->entries, pos);
+ if (!entry || git__prefixcmp(entry->path, prefix) != 0)
+ error = GIT_ENOTFOUND;
+
+ if (!error && at_pos)
+ *at_pos = pos;
+
+ git_mutex_unlock(&index->lock);
+
+ return error;
+}
+
int git_index__find_pos(
size_t *out, git_index *index, const char *path, size_t path_len, int stage)
{
diff --git a/tests/index/tests.c b/tests/index/tests.c
index f1a057853..2a416fc7b 100644
--- a/tests/index/tests.c
+++ b/tests/index/tests.c
@@ -155,6 +155,27 @@ void test_index_tests__find_in_empty(void)
git_index_free(index);
}
+void test_index_tests__find_prefix(void)
+{
+ git_index *index;
+ const git_index_entry *entry;
+ size_t pos;
+
+ cl_git_pass(git_index_open(&index, TEST_INDEX_PATH));
+
+ cl_git_pass(git_index_find_prefix(&pos, index, "src"));
+ entry = git_index_get_byindex(index, pos);
+ cl_assert(git__strcmp(entry->path, "src/block-sha1/sha1.c") == 0);
+
+ cl_git_pass(git_index_find_prefix(&pos, index, "src/co"));
+ entry = git_index_get_byindex(index, pos);
+ cl_assert(git__strcmp(entry->path, "src/commit.c") == 0);
+
+ cl_assert(GIT_ENOTFOUND == git_index_find_prefix(NULL, index, "blah"));
+
+ git_index_free(index);
+}
+
void test_index_tests__write(void)
{
git_index *index;