diff options
author | Ronnie Sahlberg <sahlberg@google.com> | 2014-05-15 10:29:40 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2014-05-15 14:11:50 -0700 |
commit | 9e70afe421ffb20ec35ff37953b76c41e767b22f (patch) | |
tree | ebc1782c5a13655112d788ba2fd3ed54b8aebc8e | |
parent | 938750f54e47b3a4cd8b06e161c28402885d4462 (diff) | |
download | git-9e70afe421ffb20ec35ff37953b76c41e767b22f.tar.gz |
receive-pack.c: use a reference transaction for updating the refs
Wrap all the ref updates inside a transaction to make the update atomic.
Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | builtin/receive-pack.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index c3230817db..d5801765a7 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -46,6 +46,8 @@ static void *head_name_to_free; static int sent_capabilities; static int shallow_update; static const char *alt_shallow_file; +struct strbuf err = STRBUF_INIT; +struct ref_transaction *transaction; static enum deny_action parse_deny_action(const char *var, const char *value) { @@ -475,7 +477,6 @@ static const char *update(struct command *cmd, struct shallow_info *si) const char *namespaced_name; unsigned char *old_sha1 = cmd->old_sha1; unsigned char *new_sha1 = cmd->new_sha1; - struct ref_lock *lock; /* only refs/... are allowed */ if (!starts_with(name, "refs/") || check_refname_format(name + 5, 0)) { @@ -580,15 +581,9 @@ static const char *update(struct command *cmd, struct shallow_info *si) update_shallow_ref(cmd, si)) return "shallow error"; - lock = lock_any_ref_for_update(namespaced_name, old_sha1, - 0, NULL); - if (!lock) { - rp_error("failed to lock %s", name); - return "failed to lock"; - } - if (write_ref_sha1(lock, new_sha1, "push")) { - return "failed to write"; /* error() already called */ - } + if (ref_transaction_update(transaction, namespaced_name, + new_sha1, old_sha1, 0, 1)) + return "failed to update"; return NULL; /* good */ } } @@ -812,6 +807,7 @@ static void execute_commands(struct command *commands, head_name = head_name_to_free = resolve_refdup("HEAD", sha1, 0, NULL); checked_connectivity = 1; + transaction = ref_transaction_begin(); for (cmd = commands; cmd; cmd = cmd->next) { if (cmd->error_string) continue; @@ -827,6 +823,10 @@ static void execute_commands(struct command *commands, checked_connectivity = 0; } } + if (ref_transaction_commit(transaction, "push", &err)) + error("%s", err.buf); + ref_transaction_free(transaction); + strbuf_release(&err); if (shallow_update && !checked_connectivity) error("BUG: run 'git fsck' for safety.\n" |