diff --git a/src/remote.c b/src/remote.c index 0b00733dc..531912c64 100644 --- a/src/remote.c +++ b/src/remote.c @@ -2166,7 +2166,8 @@ int git_remote_push(git_remote *remote, git_strarray *refspecs, const git_push_o goto cleanup; } - if ((error = git_push_status_foreach(push, cbs->push_update_reference, cbs->payload)) < 0) + if (cbs->push_update_reference && + (error = git_push_status_foreach(push, cbs->push_update_reference, cbs->payload)) < 0) goto cleanup; error = git_push_update_tips(push, signature, reflog_message); diff --git a/src/transports/local.c b/src/transports/local.c index c544fa935..3846f06d0 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -339,14 +339,11 @@ static int local_push_update_remote_ref( int error; git_reference *remote_ref = NULL; - /* rref will be NULL if it is implicit in the pushspec (e.g. 'b1:') */ - rref = rref ? rref : lref; - - if (lref) { + /* check for lhs, if it's empty it means to delete */ + if (lref[0] != '\0') { /* Create or update a ref */ - if ((error = git_reference_create(NULL, remote_repo, rref, loid, - !git_oid_iszero(roid), NULL, NULL)) < 0) - return error; + error = git_reference_create(NULL, remote_repo, rref, loid, + !git_oid_iszero(roid), NULL, NULL); } else { /* Delete a ref */ if ((error = git_reference_lookup(&remote_ref, remote_repo, rref)) < 0) { @@ -355,13 +352,11 @@ static int local_push_update_remote_ref( return error; } - if ((error = git_reference_delete(remote_ref)) < 0) - return error; - + error = git_reference_delete(remote_ref); git_reference_free(remote_ref); } - return 0; + return error; } static int local_push( diff --git a/tests/network/remote/local.c b/tests/network/remote/local.c index fd755b8c8..1132d95a1 100644 --- a/tests/network/remote/local.c +++ b/tests/network/remote/local.c @@ -466,3 +466,37 @@ void test_network_remote_local__update_tips_for_new_remote(void) { git_repository_free(src_repo); cl_fixture_cleanup("testrepo.git"); } + +void test_network_remote_local__push_delete(void) +{ + git_repository *src_repo; + git_repository *dst_repo; + git_remote *remote; + git_reference *ref; + char *spec_push[] = { "refs/heads/master" }; + char *spec_delete[] = { ":refs/heads/master" }; + git_strarray specs = { + spec_push, + 1, + }; + + src_repo = cl_git_sandbox_init("testrepo.git"); + cl_git_pass(git_repository_init(&dst_repo, "target.git", 1)); + + cl_git_pass(git_remote_create(&remote, src_repo, "origin", "./target.git")); + + /* Push the master branch and verify it's there */ + cl_git_pass(git_remote_push(remote, &specs, NULL, NULL, NULL)); + cl_git_pass(git_reference_lookup(&ref, dst_repo, "refs/heads/master")); + git_reference_free(ref); + + specs.strings = spec_delete; + cl_git_pass(git_remote_push(remote, &specs, NULL, NULL, NULL)); + cl_git_fail(git_reference_lookup(&ref, dst_repo, "refs/heads/master")); + + cl_fixture_cleanup("target.git"); + + git_remote_free(remote); + git_repository_free(dst_repo); + git_repository_free(src_repo); +}