Stefan Beller <[email protected]> writes:
> @@ -1086,8 +1100,25 @@ static void execute_commands(struct command *commands,
>
> if (cmd->skip_update)
> continue;
> -
> + if (!use_atomic) {
> + transaction = ref_transaction_begin(&err);
> + if (!transaction) {
> + rp_error("%s", err.buf);
> + strbuf_release(&err);
> + cmd->error_string = "failed to start
> transaction";
> + return;
> + }
> + }
> cmd->error_string = update(cmd, si);
> + if (!use_atomic)
> + if (ref_transaction_commit(transaction, &err)) {
> + ref_transaction_free(transaction);
> + rp_error("%s", err.buf);
> + strbuf_release(&err);
> + cmd->error_string = "failed to update ref";
> + return;
> + }
Hmm, should the code even attempt to commit if update() returned a
non NULL, signaling a failure?
Or would we want to do this instead?
if (cmd->error_string)
goto transaction_abort;
else if (!use_atomic) {
if (ref_transaction_commit(...)) {
...
cmd->error_string = "...";
return;
}
}
and then ...
> if (shallow_update && !cmd->error_string &&
> si->shallow_ref[cmd->index]) {
> error("BUG: connectivity check has not been run on ref
> %s",
> @@ -1096,10 +1127,32 @@ static void execute_commands(struct command *commands,
> }
> }
>
> + if (use_atomic) {
> + /*
> + * update(...) may abort early (i.e. because the hook refused to
> + * update that ref) which then doesn't even record a transaction
> + * regarding that ref. Make sure all commands are without error
> + * and then commit atomically.
> + */
> + for (cmd = commands; cmd; cmd = cmd->next)
> + if (cmd->error_string)
> + break;
> + if (cmd) {
> + for (cmd = commands; cmd; cmd = cmd->next)
> + if (!cmd->error_string)
> + cmd->error_string = "atomic push
> failure";
> + } else if (ref_transaction_commit(transaction, &err)) {
> + rp_error("%s", err.buf);
> + for (cmd = commands; cmd; cmd = cmd->next)
> + cmd->error_string = err.buf;
> + }
... have the label to jump to here:
transaction_abort:
> + ref_transaction_free(transaction);
I was confused by the fact that you did not have any call to
transaction-abort, until I realized that there is no such API
function and ref_transaction_free() serves that "don't commit,
roll it back" purpose.
> + }
> if (shallow_update && !checked_connectivity)
> error("BUG: run 'git fsck' for safety.\n"
> "If there are errors, try to remove "
> "the reported refs above");
> + strbuf_release(&err);
> }
>
> static struct command **queue_command(struct command **tail,
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html