Commit 51a5e13347a0f834e2d847b46d2f6002f03bd49f

Vicent Martí 2013-08-16T16:22:37

Merge pull request #1778 from libgit2/push_tag_to_tag_test push: handle tag chains correctly

diff --git a/src/push.c b/src/push.c
index 452d717..eaaa462 100644
--- a/src/push.c
+++ b/src/push.c
@@ -233,6 +233,37 @@ on_error:
 	return error;
 }
 
+/**
+ * Insert all tags until we find a non-tag object, which is returned
+ * in `out`.
+ */
+static int enqueue_tag(git_object **out, git_push *push, git_oid *id)
+{
+	git_object *obj = NULL, *target = NULL;
+	int error;
+
+	if ((error = git_object_lookup(&obj, push->repo, id, GIT_OBJ_TAG)) < 0)
+		return error;
+
+	while (git_object_type(obj) == GIT_OBJ_TAG) {
+		if ((error = git_packbuilder_insert(push->pb, git_object_id(obj), NULL)) < 0)
+			break;
+
+		if ((error = git_tag_target(&target, (git_tag *) obj)) < 0)
+			break;
+
+		git_object_free(obj);
+		obj = target;
+	}
+
+	if (error < 0)
+		git_object_free(obj);
+	else
+		*out = obj;
+
+	return error;
+}
+
 static int revwalk(git_vector *commits, git_push *push)
 {
 	git_remote_head *head;
@@ -265,21 +296,11 @@ static int revwalk(git_vector *commits, git_push *push)
 			goto on_error;
 
 		if (type == GIT_OBJ_TAG) {
-			git_tag *tag;
 			git_object *target;
 
-			if (git_packbuilder_insert(push->pb, &spec->loid, NULL) < 0)
+			if ((error = enqueue_tag(&target, push, &spec->loid)) < 0)
 				goto on_error;
 
-			if (git_tag_lookup(&tag, push->repo, &spec->loid) < 0)
-				goto on_error;
-
-			if (git_tag_peel(&target, tag) < 0) {
-				git_tag_free(tag);
-				goto on_error;
-			}
-			git_tag_free(tag);
-
 			if (git_object_type(target) == GIT_OBJ_COMMIT) {
 				if (git_revwalk_push(rw, git_object_id(target)) < 0) {
 					git_object_free(target);
diff --git a/tests-clar/online/push.c b/tests-clar/online/push.c
index 8b9602b..4c0a28c 100644
--- a/tests-clar/online/push.c
+++ b/tests-clar/online/push.c
@@ -33,6 +33,7 @@ static git_oid _tag_commit;
 static git_oid _tag_tree;
 static git_oid _tag_blob;
 static git_oid _tag_lightweight;
+static git_oid _tag_tag;
 
 static int cred_acquire_cb(
 		git_cred **cred,
@@ -279,6 +280,7 @@ void test_online_push__initialize(void)
 	git_oid_fromstr(&_tag_tree, "ff83aa4c5e5d28e3bcba2f5c6e2adc61286a4e5e");
 	git_oid_fromstr(&_tag_blob, "b483ae7ba66decee9aee971f501221dea84b1498");
 	git_oid_fromstr(&_tag_lightweight, "951bbbb90e2259a4c8950db78946784fb53fcbce");
+	git_oid_fromstr(&_tag_tag, "eea4f2705eeec2db3813f2430829afce99cd00b5");
 
 	/* Remote URL environment variable must be set.  User and password are optional.  */
 	_remote_url = cl_getenv("GITTEST_REMOTE_URL");
@@ -579,6 +581,16 @@ void test_online_push__tag_lightweight(void)
 		exp_refs, ARRAY_SIZE(exp_refs), 0);
 }
 
+void test_online_push__tag_to_tag(void)
+{
+	const char *specs[] = { "refs/tags/tag-tag:refs/tags/tag-tag" };
+	push_status exp_stats[] = { { "refs/tags/tag-tag", NULL } };
+	expected_ref exp_refs[] = { { "refs/tags/tag-tag", &_tag_tag } };
+	do_push(specs, ARRAY_SIZE(specs),
+		exp_stats, ARRAY_SIZE(exp_stats),
+		exp_refs, ARRAY_SIZE(exp_refs), 0);
+}
+
 void test_online_push__force(void)
 {
 	const char *specs1[] = {"refs/heads/b3:refs/heads/tgt"};
diff --git a/tests-clar/resources/push_src/.gitted/objects/36/f79b2846017d3761e0a02d0bccd573e0f90c57 b/tests-clar/resources/push_src/.gitted/objects/36/f79b2846017d3761e0a02d0bccd573e0f90c57
new file mode 100644
index 0000000..0bc57f2
--- /dev/null
+++ b/tests-clar/resources/push_src/.gitted/objects/36/f79b2846017d3761e0a02d0bccd573e0f90c57
@@ -0,0 +1,2 @@
+x%]
+0S͏B)}
@bnf`f`>3(nibC0hQ6BMv2&-M0Q)+
tNsE*;}JϲN픹(th@#B˺C?TÅoyk7
\ No newline at end of file
diff --git a/tests-clar/resources/push_src/.gitted/objects/ee/a4f2705eeec2db3813f2430829afce99cd00b5 b/tests-clar/resources/push_src/.gitted/objects/ee/a4f2705eeec2db3813f2430829afce99cd00b5
new file mode 100644
index 0000000..b7b81d5
Binary files /dev/null and b/tests-clar/resources/push_src/.gitted/objects/ee/a4f2705eeec2db3813f2430829afce99cd00b5 differ
diff --git a/tests-clar/resources/push_src/.gitted/refs/tags/tag-commit-two b/tests-clar/resources/push_src/.gitted/refs/tags/tag-commit-two
new file mode 100644
index 0000000..abb3650
--- /dev/null
+++ b/tests-clar/resources/push_src/.gitted/refs/tags/tag-commit-two
@@ -0,0 +1 @@
+36f79b2846017d3761e0a02d0bccd573e0f90c57
diff --git a/tests-clar/resources/push_src/.gitted/refs/tags/tag-tag b/tests-clar/resources/push_src/.gitted/refs/tags/tag-tag
new file mode 100644
index 0000000..d6cd748
--- /dev/null
+++ b/tests-clar/resources/push_src/.gitted/refs/tags/tag-tag
@@ -0,0 +1 @@
+eea4f2705eeec2db3813f2430829afce99cd00b5