diff options
author | Sven Over <sven@cord.com> | 2022-07-18 15:42:20 +0100 |
---|---|---|
committer | Sven Over <sven@cord.com> | 2022-07-20 08:29:37 +0100 |
commit | 211c97195e2ebcf68e27782715eb756823ad5a91 (patch) | |
tree | 0eeb512c5f0ea4b6e3d860c6b8cf98b37698dab2 | |
parent | 22f382539d78f69aa91721ad62bbd7229750a043 (diff) | |
download | libgit2-211c97195e2ebcf68e27782715eb756823ad5a91.tar.gz |
push: revparse refspec source, so you can push things that are not refs
I want to push a commit by OID to a remote branch. Currently, push parses the refspecs such that the source must be the name of a ref (it uses git_reference_name_to_id to resolve it). This commit changes it so push uses git_revparse_single to resolve the source of the refspec. This allows for OIDs or other revs (e.g. `HEAD~2`) to be pushed.
-rw-r--r-- | src/libgit2/push.c | 13 | ||||
-rw-r--r-- | tests/libgit2/online/push.c | 25 |
2 files changed, 30 insertions, 8 deletions
diff --git a/src/libgit2/push.c b/src/libgit2/push.c index d477b4f0d..e1502d337 100644 --- a/src/libgit2/push.c +++ b/src/libgit2/push.c @@ -385,11 +385,18 @@ static int calculate_work(git_push *push) git_vector_foreach(&push->specs, i, spec) { if (spec->refspec.src && spec->refspec.src[0]!= '\0') { /* This is a create or update. Local ref must exist. */ - if (git_reference_name_to_id( - &spec->loid, push->repo, spec->refspec.src) < 0) { - git_error_set(GIT_ERROR_REFERENCE, "no such reference '%s'", spec->refspec.src); + + git_object *obj; + int error = git_revparse_single(&obj, push->repo, spec->refspec.src); + + if (error < 0) { + git_object_free(obj); + git_error_set(GIT_ERROR_REFERENCE, "src refspec %s does not match any", spec->refspec.src); return -1; } + + git_oid_cpy(git_object_id(obj), &spec->loid); + git_object_free(obj); } /* Remote ref may or may not (e.g. during create) already exist. */ diff --git a/tests/libgit2/online/push.c b/tests/libgit2/online/push.c index d9208d28a..204572cf5 100644 --- a/tests/libgit2/online/push.c +++ b/tests/libgit2/online/push.c @@ -841,13 +841,28 @@ void test_online_push__bad_refspecs(void) void test_online_push__expressions(void) { - /* TODO: Expressions in refspecs doesn't actually work yet */ - const char *specs_left_expr[] = { "refs/heads/b2~1:refs/heads/b2" }; + const char *specs_left_expr[] = { + "refs/heads/b3~1:refs/heads/b2", + "b4:refs/heads/b4", + "fa38b91f199934685819bea316186d8b008c52a2:refs/heads/b5", + "951bbbb:refs/heads/b6" + }; + push_status exp_stats[] = { + { "refs/heads/b2", 1 }, + { "refs/heads/b4", 1 }, + { "refs/heads/b5", 1 }, + { "refs/heads/b6", 1 } + }; + expected_ref exp_refs[] = { + { "refs/heads/b2", &_oid_b2 }, + { "refs/heads/b4", &_oid_b4 }, + { "refs/heads/b5", &_oid_b5 }, + { "refs/heads/b6", &_oid_b6 } + }; - /* TODO: Find a more precise way of checking errors than a exit code of -1. */ do_push(specs_left_expr, ARRAY_SIZE(specs_left_expr), - NULL, 0, - NULL, 0, -1, 0, 0); + exp_stats, ARRAY_SIZE(exp_stats), + exp_refs, ARRAY_SIZE(exp_refs), 0, 1, 1); } void test_online_push__notes(void) |