diff options
author | Stefan Beller <sbeller@google.com> | 2015-01-07 19:23:19 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2015-01-07 19:56:43 -0800 |
commit | 68deed298ac4c257cd72d6bee543f651cb10d669 (patch) | |
tree | cc7b377b341e463b18c0a6efb76605f273819977 /builtin | |
parent | 222368c6456211a3b2054ce4651cb58703886965 (diff) | |
download | git-68deed298ac4c257cd72d6bee543f651cb10d669.tar.gz git-68deed298ac4c257cd72d6bee543f651cb10d669.tar.xz |
receive-pack.c: add execute_commands_atomic function
This introduces the new function execute_commands_atomic which will use
one atomic transaction for all updates. The default behavior is still
the old non atomic way, one ref at a time. This is to cause as little
disruption as possible to existing clients. It is unknown if there are
client scripts that depend on the old non-atomic behavior so we make it
opt-in for now.
A later patch will add the possibility to actually use the functionality
added by this patch. For now use_atomic is always 0.
Inspired-by: Ronnie Sahlberg <sahlberg@google.com>
Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin')
-rw-r--r-- | builtin/receive-pack.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 96e56a704..362d33f8e 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -40,6 +40,7 @@ static int transfer_unpack_limit = -1; static int unpack_limit = 100; static int report_status; static int use_sideband; +static int use_atomic; static int quiet; static int prefer_ofs_delta = 1; static int auto_update_server_info; @@ -1095,7 +1096,48 @@ static void execute_commands_non_atomic(struct command *commands, } ref_transaction_free(transaction); } + strbuf_release(&err); +} + +static void execute_commands_atomic(struct command *commands, + struct shallow_info *si) +{ + struct command *cmd; + struct strbuf err = STRBUF_INIT; + const char *reported_error = "atomic push failure"; + + transaction = ref_transaction_begin(&err); + if (!transaction) { + rp_error("%s", err.buf); + strbuf_reset(&err); + reported_error = "transaction failed to start"; + goto failure; + } + + for (cmd = commands; cmd; cmd = cmd->next) { + if (!should_process_cmd(cmd)) + continue; + + cmd->error_string = update(cmd, si); + + if (cmd->error_string) + goto failure; + } + if (ref_transaction_commit(transaction, &err)) { + rp_error("%s", err.buf); + reported_error = "atomic transaction failed"; + goto failure; + } + goto cleanup; + +failure: + for (cmd = commands; cmd; cmd = cmd->next) + if (!cmd->error_string) + cmd->error_string = reported_error; + +cleanup: + ref_transaction_free(transaction); strbuf_release(&err); } @@ -1133,7 +1175,10 @@ static void execute_commands(struct command *commands, free(head_name_to_free); head_name = head_name_to_free = resolve_refdup("HEAD", 0, sha1, NULL); - execute_commands_non_atomic(commands, si); + if (use_atomic) + execute_commands_atomic(commands, si); + else + execute_commands_non_atomic(commands, si); if (shallow_update) warn_if_skipped_connectivity_check(commands, si); |