From abeefbbe18710f86077eb4c5b825255256b8b6bc Mon Sep 17 00:00:00 2001 From: Michael Schubert Date: Wed, 26 Dec 2012 19:16:23 +0100 Subject: push: properly handle tags Currently, push doesn't really handle tags when queueing objects. Fix it. --- src/push.c | 48 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) (limited to 'src/push.c') diff --git a/src/push.c b/src/push.c index 6e856bd32..71223645a 100644 --- a/src/push.c +++ b/src/push.c @@ -85,15 +85,15 @@ static int check_lref(git_push *push, char *ref) int error = git_revparse_single(&obj, push->repo, ref); if (error) { - if(error == GIT_ENOTFOUND) - giterr_set(GITERR_REFERENCE, "src refspec '%s' does not match any existing object", ref); + if (error == GIT_ENOTFOUND) + giterr_set(GITERR_REFERENCE, + "src refspec '%s' does not match any existing object", ref); else giterr_set(GITERR_INVALID, "Not a valid reference '%s'", ref); return -1; - } else { + } else git_object_free(obj); - } return 0; } @@ -138,7 +138,8 @@ static int parse_refspec(git_push *push, push_spec **spec, const char *str) /* If rref is ommitted, use the same ref name as lref */ if (!s->rref) { s->rref = git__strdup(s->lref); - check(s->rref); + if (!s->rref || check_rref(s->rref) < 0) + goto on_error; } *spec = s; @@ -175,6 +176,9 @@ static int revwalk(git_vector *commits, git_push *push) git_revwalk_sorting(rw, GIT_SORT_TIME); git_vector_foreach(&push->specs, i, spec) { + git_otype type; + size_t size; + if (git_oid_iszero(&spec->loid)) /* * Delete reference on remote side; @@ -185,7 +189,39 @@ static int revwalk(git_vector *commits, git_push *push) if (git_oid_equal(&spec->loid, &spec->roid)) continue; /* up-to-date */ - if (git_revwalk_push(rw, &spec->loid) < 0) + if (git_odb_read_header(&size, &type, push->repo->_odb, &spec->loid) < 0) + goto on_error; + + if (type == GIT_OBJ_TAG) { + git_tag *tag; + git_object *target; + + if (git_packbuilder_insert(push->pb, &spec->loid, NULL) < 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); + goto on_error; + } + } else { + if (git_packbuilder_insert( + push->pb, git_object_id(target), NULL) < 0) { + git_object_free(target); + goto on_error; + } + } + git_object_free(target); + } else if (git_revwalk_push(rw, &spec->loid) < 0) goto on_error; if (!spec->force) { -- cgit v1.2.3