diff options
Diffstat (limited to 'src/push.c')
| -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) {  | 
