Commit abeefbbe by Michael Schubert

push: properly handle tags

Currently, push doesn't really handle tags when queueing objects. Fix
it.
parent f85b6284
...@@ -124,7 +124,7 @@ GIT_EXTERN(int) git_reference_create(git_reference **out, git_repository *repo, ...@@ -124,7 +124,7 @@ GIT_EXTERN(int) git_reference_create(git_reference **out, git_repository *repo,
* not a symbolic one). * not a symbolic one).
* *
* To find the OID of a symbolic ref, call `git_reference_resolve()` and * To find the OID of a symbolic ref, call `git_reference_resolve()` and
* then this function (or maybe use `git_reference_name_to_oid()` to * then this function (or maybe use `git_reference_name_to_id()` to
* directly resolve a reference name all the way through to an OID). * directly resolve a reference name all the way through to an OID).
* *
* @param ref The reference * @param ref The reference
......
...@@ -85,15 +85,15 @@ static int check_lref(git_push *push, char *ref) ...@@ -85,15 +85,15 @@ static int check_lref(git_push *push, char *ref)
int error = git_revparse_single(&obj, push->repo, ref); int error = git_revparse_single(&obj, push->repo, ref);
if (error) { if (error) {
if(error == GIT_ENOTFOUND) if (error == GIT_ENOTFOUND)
giterr_set(GITERR_REFERENCE, "src refspec '%s' does not match any existing object", ref); giterr_set(GITERR_REFERENCE,
"src refspec '%s' does not match any existing object", ref);
else else
giterr_set(GITERR_INVALID, "Not a valid reference '%s'", ref); giterr_set(GITERR_INVALID, "Not a valid reference '%s'", ref);
return -1; return -1;
} else { } else
git_object_free(obj); git_object_free(obj);
}
return 0; return 0;
} }
...@@ -138,7 +138,8 @@ static int parse_refspec(git_push *push, push_spec **spec, const char *str) ...@@ -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 rref is ommitted, use the same ref name as lref */
if (!s->rref) { if (!s->rref) {
s->rref = git__strdup(s->lref); s->rref = git__strdup(s->lref);
check(s->rref); if (!s->rref || check_rref(s->rref) < 0)
goto on_error;
} }
*spec = s; *spec = s;
...@@ -175,6 +176,9 @@ static int revwalk(git_vector *commits, git_push *push) ...@@ -175,6 +176,9 @@ static int revwalk(git_vector *commits, git_push *push)
git_revwalk_sorting(rw, GIT_SORT_TIME); git_revwalk_sorting(rw, GIT_SORT_TIME);
git_vector_foreach(&push->specs, i, spec) { git_vector_foreach(&push->specs, i, spec) {
git_otype type;
size_t size;
if (git_oid_iszero(&spec->loid)) if (git_oid_iszero(&spec->loid))
/* /*
* Delete reference on remote side; * Delete reference on remote side;
...@@ -185,7 +189,39 @@ static int revwalk(git_vector *commits, git_push *push) ...@@ -185,7 +189,39 @@ static int revwalk(git_vector *commits, git_push *push)
if (git_oid_equal(&spec->loid, &spec->roid)) if (git_oid_equal(&spec->loid, &spec->roid))
continue; /* up-to-date */ 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; goto on_error;
if (!spec->force) { if (!spec->force) {
......
...@@ -22,6 +22,11 @@ static git_oid _oid_b3; ...@@ -22,6 +22,11 @@ static git_oid _oid_b3;
static git_oid _oid_b2; static git_oid _oid_b2;
static git_oid _oid_b1; static git_oid _oid_b1;
static git_oid _tag_commit;
static git_oid _tag_tree;
static git_oid _tag_blob;
static git_oid _tag_lightweight;
static int cred_acquire_cb(git_cred **cred, const char *url, unsigned int allowed_types, void *payload) static int cred_acquire_cb(git_cred **cred, const char *url, unsigned int allowed_types, void *payload)
{ {
GIT_UNUSED(url); GIT_UNUSED(url);
...@@ -154,6 +159,11 @@ void test_online_push__initialize(void) ...@@ -154,6 +159,11 @@ void test_online_push__initialize(void)
git_oid_fromstr(&_oid_b2, "a78705c3b2725f931d3ee05348d83cc26700f247"); git_oid_fromstr(&_oid_b2, "a78705c3b2725f931d3ee05348d83cc26700f247");
git_oid_fromstr(&_oid_b1, "a78705c3b2725f931d3ee05348d83cc26700f247"); git_oid_fromstr(&_oid_b1, "a78705c3b2725f931d3ee05348d83cc26700f247");
git_oid_fromstr(&_tag_commit, "805c54522e614f29f70d2413a0470247d8b424ac");
git_oid_fromstr(&_tag_tree, "ff83aa4c5e5d28e3bcba2f5c6e2adc61286a4e5e");
git_oid_fromstr(&_tag_blob, "b483ae7ba66decee9aee971f501221dea84b1498");
git_oid_fromstr(&_tag_lightweight, "951bbbb90e2259a4c8950db78946784fb53fcbce");
/* Remote URL environment variable must be set. User and password are optional. */ /* Remote URL environment variable must be set. User and password are optional. */
_remote_url = cl_getenv("GITTEST_REMOTE_URL"); _remote_url = cl_getenv("GITTEST_REMOTE_URL");
_remote_user = cl_getenv("GITTEST_REMOTE_USER"); _remote_user = cl_getenv("GITTEST_REMOTE_USER");
...@@ -404,6 +414,46 @@ void test_online_push__fast_fwd(void) ...@@ -404,6 +414,46 @@ void test_online_push__fast_fwd(void)
exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0); exp_refs_ff, ARRAY_SIZE(exp_refs_ff), 0);
} }
void test_online_push__tag_commit(void)
{
const char *specs[] = { "refs/tags/tag-commit:refs/tags/tag-commit" };
push_status exp_stats[] = { { "refs/tags/tag-commit", NULL } };
expected_ref exp_refs[] = { { "refs/tags/tag-commit", &_tag_commit } };
do_push(specs, ARRAY_SIZE(specs),
exp_stats, ARRAY_SIZE(exp_stats),
exp_refs, ARRAY_SIZE(exp_refs), 0);
}
void test_online_push__tag_tree(void)
{
const char *specs[] = { "refs/tags/tag-tree:refs/tags/tag-tree" };
push_status exp_stats[] = { { "refs/tags/tag-tree", NULL } };
expected_ref exp_refs[] = { { "refs/tags/tag-tree", &_tag_tree } };
do_push(specs, ARRAY_SIZE(specs),
exp_stats, ARRAY_SIZE(exp_stats),
exp_refs, ARRAY_SIZE(exp_refs), 0);
}
void test_online_push__tag_blob(void)
{
const char *specs[] = { "refs/tags/tag-blob:refs/tags/tag-blob" };
push_status exp_stats[] = { { "refs/tags/tag-blob", NULL } };
expected_ref exp_refs[] = { { "refs/tags/tag-blob", &_tag_blob } };
do_push(specs, ARRAY_SIZE(specs),
exp_stats, ARRAY_SIZE(exp_stats),
exp_refs, ARRAY_SIZE(exp_refs), 0);
}
void test_online_push__tag_lightweight(void)
{
const char *specs[] = { "refs/tags/tag-lightweight:refs/tags/tag-lightweight" };
push_status exp_stats[] = { { "refs/tags/tag-lightweight", NULL } };
expected_ref exp_refs[] = { { "refs/tags/tag-lightweight", &_tag_lightweight } };
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) void test_online_push__force(void)
{ {
const char *specs1[] = {"refs/heads/b3:refs/heads/tgt"}; const char *specs1[] = {"refs/heads/b3:refs/heads/tgt"};
...@@ -523,7 +573,7 @@ void test_online_push__expressions(void) ...@@ -523,7 +573,7 @@ void test_online_push__expressions(void)
NULL, 0, 0); NULL, 0, 0);
} }
void test_network_push__notes(void) void test_online_push__notes(void)
{ {
git_oid note_oid, *target_oid, expected_oid; git_oid note_oid, *target_oid, expected_oid;
git_signature *signature; git_signature *signature;
...@@ -536,7 +586,7 @@ void test_network_push__notes(void) ...@@ -536,7 +586,7 @@ void test_network_push__notes(void)
/* Create note to push */ /* Create note to push */
cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas@gmail.com", 1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */ cl_git_pass(git_signature_new(&signature, "nulltoken", "emeric.fermas@gmail.com", 1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */
cl_git_pass(git_note_create(&note_oid, _repo, signature, signature, NULL, target_oid, "hello world\n")); cl_git_pass(git_note_create(&note_oid, _repo, signature, signature, NULL, target_oid, "hello world\n", 0));
do_push(specs, ARRAY_SIZE(specs), do_push(specs, ARRAY_SIZE(specs),
exp_stats, ARRAY_SIZE(exp_stats), exp_stats, ARRAY_SIZE(exp_stats),
......
b483ae7ba66decee9aee971f501221dea84b1498
805c54522e614f29f70d2413a0470247d8b424ac
ff83aa4c5e5d28e3bcba2f5c6e2adc61286a4e5e
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment