diff --git a/include/git2/tag.h b/include/git2/tag.h index c751a13c0..3fc6b4499 100644 --- a/include/git2/tag.h +++ b/include/git2/tag.h @@ -275,6 +275,23 @@ GIT_EXTERN(int) git_tag_delete( git_repository *repo, const char *tag_name); +/** + * Fill a list with all the tags in the Repository + * + * The string array will be filled with the names of the + * matching tags; these values are owned by the user and + * should be free'd manually when no longer needed, using + * `git_strarray_free`. + * + * @param array Pointer to a git_strarray structure where + * the tag names will be stored + * @param repo Repository where to find the tags + * @return 0 on success; error code otherwise + */ +GIT_EXTERN(int) git_tag_list( + git_strarray *tag_names, + git_repository *repo); + /** @} */ GIT_END_DECL #endif diff --git a/src/tag.c b/src/tag.c index a3400957f..148eb280c 100644 --- a/src/tag.c +++ b/src/tag.c @@ -377,3 +377,29 @@ int git_tag__parse(git_tag *tag, git_odb_object *obj) return parse_tag_buffer(tag, obj->raw.data, (char *)obj->raw.data + obj->raw.len); } +static int tag_list_cb(const char *tag_name, void *payload) +{ + if (git__prefixcmp(tag_name, GIT_REFS_TAGS_DIR) == 0) + return git_vector_insert((git_vector *)payload, git__strdup(tag_name)); + + return GIT_SUCCESS; +} + +int git_tag_list(git_strarray *tag_names, git_repository *repo) +{ + int error; + git_vector taglist; + + if (git_vector_init(&taglist, 8, NULL) < GIT_SUCCESS) + return GIT_ENOMEM; + + error = git_reference_listcb(repo, GIT_REF_OID|GIT_REF_PACKED, &tag_list_cb, (void *)&taglist); + if (error < GIT_SUCCESS) { + git_vector_free(&taglist); + return error; + } + + tag_names->strings = (char **)taglist.contents; + tag_names->count = taglist.length; + return GIT_SUCCESS; +} diff --git a/tests/t08-tag.c b/tests/t08-tag.c index de67fdd93..fae2e99db 100644 --- a/tests/t08-tag.c +++ b/tests/t08-tag.c @@ -64,6 +64,19 @@ BEGIN_TEST(read0, "read and parse a tag from the repository") git_repository_free(repo); END_TEST +BEGIN_TEST(read1, "list all tag names from the repository") + git_repository *repo; + git_strarray tag_list; + + must_pass(git_repository_open(&repo, REPOSITORY_FOLDER)); + must_pass(git_tag_list(&tag_list, repo)); + + must_be_true(tag_list.count == 3); + + git_strarray_free(&tag_list); + git_repository_free(repo); +END_TEST + #define TAGGER_NAME "Vicent Marti" #define TAGGER_EMAIL "vicent@github.com" @@ -227,6 +240,7 @@ END_TEST BEGIN_SUITE(tag) ADD_TEST(read0); + ADD_TEST(read1); ADD_TEST(write0); ADD_TEST(write1); ADD_TEST(write2);