Skip to content

Commit

Permalink
receive-pack.c: add execute_commands_atomic function
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Stefan Beller authored and Junio C Hamano committed Jan 8, 2015
1 parent 222368c commit 68deed2
Showing 1 changed file with 46 additions and 1 deletion.
47 changes: 46 additions & 1 deletion builtin/receive-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 68deed2

Please sign in to comment.