summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVicent Martí <vicent@github.com>2013-08-16 16:22:37 -0700
committerVicent Martí <vicent@github.com>2013-08-16 16:22:37 -0700
commit51a5e13347a0f834e2d847b46d2f6002f03bd49f (patch)
tree0d981a359b03ae34156234571b24a6f509a9fdcb /src
parentb2be62fd23a9e39ce32725139bdeecf7e10aa2ac (diff)
parent5ce6c1e917a4282455fef6c7fd2236a7fb68653a (diff)
downloadlibgit2-51a5e13347a0f834e2d847b46d2f6002f03bd49f.tar.gz
Merge pull request #1778 from libgit2/push_tag_to_tag_test
push: handle tag chains correctly
Diffstat (limited to 'src')
-rw-r--r--src/push.c43
1 files changed, 32 insertions, 11 deletions
diff --git a/src/push.c b/src/push.c
index 452d71789..eaaa46248 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);