diff options
author | Michael Schubert <schu@schu.io> | 2012-12-26 22:16:23 +0400 |
---|---|---|
committer | Michael Schubert <schu@schu.io> | 2013-01-09 20:05:21 +0400 |
commit | abeefbbe18710f86077eb4c5b825255256b8b6bc (patch) | |
tree | c148f738f71d8a9472e3c455096de76221b62ac5 /src | |
parent | f85b62840a079fb4bee1838da50421a178850bd3 (diff) |
push: properly handle tags
Currently, push doesn't really handle tags when queueing objects. Fix
it.
Diffstat (limited to 'src')
-rw-r--r-- | src/push.c | 48 |
1 files changed, 42 insertions, 6 deletions
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) { |