Commit 3f46f313 by nulltoken

tag: Add git_tag_peel() which recursively peel a tag until a non tag git_object is met

parent 09719c50
......@@ -274,6 +274,21 @@ GIT_EXTERN(int) git_tag_list_match(
const char *pattern,
git_repository *repo);
/**
* Recursively peel a tag until a non tag git_object
* is met
*
* The retrieved `tag_target` object is owned by the repository
* and should be closed with the `git_object_free` method.
*
* @param tag_target Pointer to the peeled git_object
* @param tag The tag to be processed
* @return GIT_SUCCESS or an error code
*/
GIT_EXTERN(int) git_tag_peel(
git_object **tag_target,
git_tag *tag);
/** @} */
GIT_END_DECL
#endif
......@@ -451,3 +451,23 @@ int git_tag_list(git_strarray *tag_names, git_repository *repo)
{
return git_tag_list_match(tag_names, "", repo);
}
int git_tag_peel(git_object **tag_target, git_tag *tag)
{
int error;
git_object *target;
assert(tag_target && tag);
if (git_tag_target(&target, tag) < 0)
return -1;
if (git_object_type(target) == GIT_OBJ_TAG) {
error = git_tag_peel(tag_target, (git_tag *)target);
git_object_free(target);
return error;
}
*tag_target = target;
return 0;
}
......@@ -88,7 +88,7 @@ void test_network_remotelocal__retrieve_advertised_references(void)
cl_git_pass(git_remote_ls(remote, &count_ref__cb, &how_many_refs));
cl_assert(how_many_refs == 12); /* 1 HEAD + 9 refs + 2 peeled tags */
cl_assert(how_many_refs == 14); /* 1 HEAD + 6 heads + 1 lightweight tag + 3 annotated tags + 3 peeled target */
}
void test_network_remotelocal__retrieve_advertised_references_from_spaced_repository(void)
......@@ -102,7 +102,7 @@ void test_network_remotelocal__retrieve_advertised_references_from_spaced_reposi
cl_git_pass(git_remote_ls(remote, &count_ref__cb, &how_many_refs));
cl_assert(how_many_refs == 12); /* 1 HEAD */
cl_assert(how_many_refs == 14); /* 1 HEAD + 6 heads + 1 lightweight tag + 3 annotated tags + 3 peeled target */
cl_fixture_cleanup("spaced testrepo.git");
}
#include "clar_libgit2.h"
#include "tag.h"
static git_repository *repo;
static git_tag *tag;
static git_object *target;
void test_object_tag_peel__initialize(void)
{
cl_fixture_sandbox("testrepo.git");
cl_git_pass(git_repository_open(&repo, "testrepo.git"));
}
void test_object_tag_peel__cleanup(void)
{
git_tag_free(tag);
git_object_free(target);
git_repository_free(repo);
cl_fixture_cleanup("testrepo.git");
}
static void retrieve_tag_from_oid(git_tag **tag_out, git_repository *repo, const char *sha)
{
git_oid oid;
cl_git_pass(git_oid_fromstr(&oid, sha));
cl_git_pass(git_tag_lookup(tag_out, repo, &oid));
}
void test_object_tag_peel__can_peel_to_a_commit(void)
{
retrieve_tag_from_oid(&tag, repo, "7b4384978d2493e851f9cca7858815fac9b10980");
cl_git_pass(git_tag_peel(&target, tag));
cl_assert(git_object_type(target) == GIT_OBJ_COMMIT);
cl_git_pass(git_oid_streq(git_object_id(target), "e90810b8df3e80c413d903f631643c716887138d"));
}
void test_object_tag_peel__can_peel_several_nested_tags_to_a_commit(void)
{
retrieve_tag_from_oid(&tag, repo, "b25fa35b38051e4ae45d4222e795f9df2e43f1d1");
cl_git_pass(git_tag_peel(&target, tag));
cl_assert(git_object_type(target) == GIT_OBJ_COMMIT);
cl_git_pass(git_oid_streq(git_object_id(target), "e90810b8df3e80c413d903f631643c716887138d"));
}
void test_object_tag_peel__can_peel_to_a_non_commit(void)
{
retrieve_tag_from_oid(&tag, repo, "521d87c1ec3aef9824daf6d96cc0ae3710766d91");
cl_git_pass(git_tag_peel(&target, tag));
cl_assert(git_object_type(target) == GIT_OBJ_BLOB);
cl_git_pass(git_oid_streq(git_object_id(target), "1385f264afb75a56a5bec74243be9b367ba4ca08"));
}
......@@ -73,7 +73,7 @@ BEGIN_TEST(read1, "list all tag names from the repository")
must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));
must_pass(git_tag_list(&tag_list, repo));
must_be_true(tag_list.count == 3);
must_be_true(tag_list.count == 4);
git_strarray_free(&tag_list);
git_repository_free(repo);
......@@ -98,10 +98,10 @@ exit:
BEGIN_TEST(read2, "list all tag names from the repository matching a specified pattern")
git_repository *repo;
must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));
must_pass(ensure_tag_pattern_match(repo, "", 3));
must_pass(ensure_tag_pattern_match(repo, "*", 3));
must_pass(ensure_tag_pattern_match(repo, "", 4));
must_pass(ensure_tag_pattern_match(repo, "*", 4));
must_pass(ensure_tag_pattern_match(repo, "t*", 1));
must_pass(ensure_tag_pattern_match(repo, "*b", 2));
must_pass(ensure_tag_pattern_match(repo, "*b", 3));
must_pass(ensure_tag_pattern_match(repo, "e", 0));
must_pass(ensure_tag_pattern_match(repo, "e90810b", 1));
must_pass(ensure_tag_pattern_match(repo, "e90810[ab]", 1));
......
......@@ -1164,10 +1164,10 @@ BEGIN_TEST(list0, "try to list all the references in our test repo")
printf("# %s\n", ref_list.strings[i]);
}*/
/* We have exactly 9 refs in total if we include the packed ones:
/* We have exactly 10 refs in total if we include the packed ones:
* there is a reference that exists both in the packfile and as
* loose, but we only list it once */
must_be_true(ref_list.count == 9);
must_be_true(ref_list.count == 10);
git_strarray_free(&ref_list);
git_repository_free(repo);
......
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