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>
This commit is contained in:
parent
222368c645
commit
68deed298a
@ -40,6 +40,7 @@ static int transfer_unpack_limit = -1;
|
|||||||
static int unpack_limit = 100;
|
static int unpack_limit = 100;
|
||||||
static int report_status;
|
static int report_status;
|
||||||
static int use_sideband;
|
static int use_sideband;
|
||||||
|
static int use_atomic;
|
||||||
static int quiet;
|
static int quiet;
|
||||||
static int prefer_ofs_delta = 1;
|
static int prefer_ofs_delta = 1;
|
||||||
static int auto_update_server_info;
|
static int auto_update_server_info;
|
||||||
@ -1095,7 +1096,48 @@ static void execute_commands_non_atomic(struct command *commands,
|
|||||||
}
|
}
|
||||||
ref_transaction_free(transaction);
|
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);
|
strbuf_release(&err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1133,7 +1175,10 @@ static void execute_commands(struct command *commands,
|
|||||||
free(head_name_to_free);
|
free(head_name_to_free);
|
||||||
head_name = head_name_to_free = resolve_refdup("HEAD", 0, sha1, NULL);
|
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)
|
if (shallow_update)
|
||||||
warn_if_skipped_connectivity_check(commands, si);
|
warn_if_skipped_connectivity_check(commands, si);
|
||||||
|
Loading…
Reference in New Issue
Block a user