Permalink
Browse files

tag: Add git_tag_peel() which recursively peel a tag until a non tag …

…git_object is met
  • Loading branch information...
nulltoken committed Apr 6, 2012
1 parent 09719c5 commit 3f46f313cbfcf57e5cbf3d7dc55b747568a21bef
View
@@ -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
View
@@ -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");
}
@@ -0,0 +1,56 @@
+#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"));
+}
@@ -0,0 +1 @@
+521d87c1ec3aef9824daf6d96cc0ae3710766d91
View
@@ -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 @@ static int ensure_tag_pattern_match(git_repository *repo, const char *pattern, c
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));
View
@@ -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);

0 comments on commit 3f46f31

Please sign in to comment.