Merge pull request #3381 from leoyanggit/index_directory_iterator New feature: add the ablility to iterate through a directory in index
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
diff --git a/include/git2/index.h b/include/git2/index.h
index 7caf3ed..176ba30 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 6be73d2..20a6c93 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 f1a0578..2a416fc 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;