Skip to content

Commit 68deed2

Browse files
stefanbellergitster
authored andcommitted
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 <[email protected]> Helped-by: Eric Sunshine <[email protected]> Signed-off-by: Stefan Beller <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 222368c commit 68deed2

File tree

1 file changed

+46
-1
lines changed

1 file changed

+46
-1
lines changed

builtin/receive-pack.c

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ static int transfer_unpack_limit = -1;
4040
static int unpack_limit = 100;
4141
static int report_status;
4242
static int use_sideband;
43+
static int use_atomic;
4344
static int quiet;
4445
static int prefer_ofs_delta = 1;
4546
static int auto_update_server_info;
@@ -1095,7 +1096,48 @@ static void execute_commands_non_atomic(struct command *commands,
10951096
}
10961097
ref_transaction_free(transaction);
10971098
}
1099+
strbuf_release(&err);
1100+
}
1101+
1102+
static void execute_commands_atomic(struct command *commands,
1103+
struct shallow_info *si)
1104+
{
1105+
struct command *cmd;
1106+
struct strbuf err = STRBUF_INIT;
1107+
const char *reported_error = "atomic push failure";
1108+
1109+
transaction = ref_transaction_begin(&err);
1110+
if (!transaction) {
1111+
rp_error("%s", err.buf);
1112+
strbuf_reset(&err);
1113+
reported_error = "transaction failed to start";
1114+
goto failure;
1115+
}
1116+
1117+
for (cmd = commands; cmd; cmd = cmd->next) {
1118+
if (!should_process_cmd(cmd))
1119+
continue;
1120+
1121+
cmd->error_string = update(cmd, si);
1122+
1123+
if (cmd->error_string)
1124+
goto failure;
1125+
}
10981126

1127+
if (ref_transaction_commit(transaction, &err)) {
1128+
rp_error("%s", err.buf);
1129+
reported_error = "atomic transaction failed";
1130+
goto failure;
1131+
}
1132+
goto cleanup;
1133+
1134+
failure:
1135+
for (cmd = commands; cmd; cmd = cmd->next)
1136+
if (!cmd->error_string)
1137+
cmd->error_string = reported_error;
1138+
1139+
cleanup:
1140+
ref_transaction_free(transaction);
10991141
strbuf_release(&err);
11001142
}
11011143

@@ -1133,7 +1175,10 @@ static void execute_commands(struct command *commands,
11331175
free(head_name_to_free);
11341176
head_name = head_name_to_free = resolve_refdup("HEAD", 0, sha1, NULL);
11351177

1136-
execute_commands_non_atomic(commands, si);
1178+
if (use_atomic)
1179+
execute_commands_atomic(commands, si);
1180+
else
1181+
execute_commands_non_atomic(commands, si);
11371182

11381183
if (shallow_update)
11391184
warn_if_skipped_connectivity_check(commands, si);

0 commit comments

Comments
 (0)