summaryrefslogtreecommitdiff
path: root/transport.c
diff options
context:
space:
mode:
authorEmily Shaffer <emilyshaffer@google.com>2019-07-11 21:19:19 (GMT)
committerJunio C Hamano <gitster@pobox.com>2019-07-12 16:24:10 (GMT)
commit3bca1e7f9f9708b970035a641d21f8c5cec1cd88 (patch)
treedfc12425711865fdbf6e599ac696deb3ad289bea /transport.c
parentb697d92f56511e804b8ba20ccbe7bdc85dc66810 (diff)
downloadgit-3bca1e7f9f9708b970035a641d21f8c5cec1cd88.zip
git-3bca1e7f9f9708b970035a641d21f8c5cec1cd88.tar.gz
git-3bca1e7f9f9708b970035a641d21f8c5cec1cd88.tar.bz2
transport-helper: enforce atomic in push_refs_with_push
Teach transport-helper how to notice if skipping a ref during push would violate atomicity on the client side. We notice that a ref would be rejected, and choose not to send it, but don't notice that if the client has asked for --atomic we are violating atomicity if all the other pushes we are sending would succeed. Asking the server end to uphold atomicity wouldn't work here as the server doesn't have any idea that we tried to update a ref that's broken. The added test-case is a succinct way to reproduce this issue that fails today. The same steps work fine when we aren't using a transport-helper to get to the upstream, i.e. when we've added a local repository as a remote: git remote add ~/upstream upstream Signed-off-by: Emily Shaffer <emilyshaffer@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'transport.c')
-rw-r--r--transport.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/transport.c b/transport.c
index f1fcd2c..d768bc2 100644
--- a/transport.c
+++ b/transport.c
@@ -1226,6 +1226,19 @@ int transport_push(struct repository *r,
err = push_had_errors(remote_refs);
ret = push_ret | err;
+ if ((flags & TRANSPORT_PUSH_ATOMIC) && err) {
+ for (struct ref *it = remote_refs; it; it = it->next)
+ switch (it->status) {
+ case REF_STATUS_NONE:
+ case REF_STATUS_UPTODATE:
+ case REF_STATUS_OK:
+ it->status = REF_STATUS_ATOMIC_PUSH_FAILED;
+ break;
+ default:
+ break;
+ }
+ }
+
if (!quiet || err)
transport_print_push_status(transport->url, remote_refs,
verbose | porcelain, porcelain,