From: Ronnie Sahlberg <sahlberg@google.com>
To: git@vger.kernel.org
Cc: Ronnie Sahlberg <sahlberg@google.com>
Subject: [PATCH 3/5] receive-pack.c: use a single transaction when atomic-push is negotiated
Date: Tue, 19 Aug 2014 09:24:49 -0700 [thread overview]
Message-ID: <1408465491-25488-4-git-send-email-sahlberg@google.com> (raw)
In-Reply-To: <1408465491-25488-1-git-send-email-sahlberg@google.com>
Update receive-pack to use an atomic transaction IFF the client negotiated
that it wanted atomic-push.
This leaves the default behaviour to be the old non-atomic one ref at a
time update. 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 behaviour so we make it opt-in for now.
Later patch in this series also adds a configuration variable where you can
override the atomic push behaviour on the receiving repo and force it
to use atomic updates always.
If it turns out over time that there are no client scripts that depend on the
old behaviour we can change git to default to use atomic pushes and instead
offer an opt-out argument for people that do not want atomic pushes.
Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
---
Documentation/technical/protocol-capabilities.txt | 7 +++
builtin/receive-pack.c | 55 ++++++++++++++++++-----
2 files changed, 51 insertions(+), 11 deletions(-)
diff --git a/Documentation/technical/protocol-capabilities.txt b/Documentation/technical/protocol-capabilities.txt
index e174343..93d99c5 100644
--- a/Documentation/technical/protocol-capabilities.txt
+++ b/Documentation/technical/protocol-capabilities.txt
@@ -250,3 +250,10 @@ allow-tip-sha1-in-want
If the upload-pack server advertises this capability, fetch-pack may
send "want" lines with SHA-1s that exist at the server but are not
advertised by upload-pack.
+
+atomic-push
+-----------
+
+If the receive-pack server advertises the 'atomic-push' capability, it means
+that it is capable of accepting atomic pushes. An atomic push is a push
+where the ref updates are done as a single atomic transaction.
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index f6b20cb..47f778d 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -47,6 +47,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)
{
@@ -577,26 +579,38 @@ static char *update(struct command *cmd, struct shallow_info *si)
return NULL; /* good */
}
else {
- struct strbuf err = STRBUF_INIT;
- struct ref_transaction *transaction;
-
if (shallow_update && si->shallow_ref[cmd->index] &&
update_shallow_ref(cmd, si))
return xstrdup("shallow error");
-
- transaction = transaction_begin(&err);
- if (!transaction ||
- transaction_update_sha1(transaction, namespaced_name,
+ if (!use_atomic_push) {
+ transaction = transaction_begin(&err);
+ if (!transaction) {
+ char *str = xstrdup(err.buf);
+
+ strbuf_release(&err);
+ transaction_free(transaction);
+ rp_error("%s", str);
+ return str;
+ }
+ }
+ if (transaction_update_sha1(transaction, namespaced_name,
new_sha1, old_sha1, 0, 1, "push",
- &err) ||
- transaction_commit(transaction, &err)) {
- char *str = strbuf_detach(&err, NULL);
- transaction_free(transaction);
+ &err)) {
+ char *str = xstrdup(err.buf);
+ strbuf_release(&err);
+ transaction_free(transaction);
rp_error("%s", str);
return str;
}
+ if (!use_atomic_push && transaction_commit(transaction, &err)) {
+ char *str = xstrdup(err.buf);
+ strbuf_release(&err);
+ transaction_free(transaction);
+ rp_error("%s", str);
+ return str;
+ }
transaction_free(transaction);
strbuf_release(&err);
return NULL; /* good */
@@ -810,6 +824,16 @@ static void execute_commands(struct command *commands,
return;
}
+ if (use_atomic_push) {
+ transaction = transaction_begin(&err);
+ if (!transaction) {
+ error("%s", err.buf);
+ strbuf_release(&err);
+ for (cmd = commands; cmd; cmd = cmd->next)
+ cmd->error_string = "transaction error";
+ return;
+ }
+ }
data.cmds = commands;
data.si = si;
if (check_everything_connected(iterate_receive_command_list, 0, &data))
@@ -848,6 +872,14 @@ static void execute_commands(struct command *commands,
}
}
+ if (use_atomic_push) {
+ if (transaction_commit(transaction, &err)) {
+ rp_error("%s", err.buf);
+ for (cmd = commands; cmd; cmd = cmd->next)
+ cmd->error_string = err.buf;
+ }
+ transaction_free(transaction);
+ }
if (shallow_update && !checked_connectivity)
error("BUG: run 'git fsck' for safety.\n"
"If there are errors, try to remove "
@@ -1250,5 +1282,6 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
sha1_array_clear(&shallow);
sha1_array_clear(&ref);
free_commands(commands);
+ strbuf_release(&err);
return 0;
}
--
2.0.1.556.ge8f7cba.dirty
next prev parent reply other threads:[~2014-08-19 16:25 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-19 16:24 [PATCH 0/5] ref-transactions-send-pack Ronnie Sahlberg
2014-08-19 16:24 ` [PATCH 1/5] receive-pack.c: add protocol support to negotiate atomic-push Ronnie Sahlberg
2014-08-19 16:24 ` [PATCH 2/5] send-pack.c: add an --atomic-push command line argument Ronnie Sahlberg
2014-08-19 16:24 ` Ronnie Sahlberg [this message]
2014-08-19 16:24 ` [PATCH 4/5] receive-pack.c: add receive.atomicpush configuration option Ronnie Sahlberg
2014-08-19 16:24 ` [PATCH 5/5] push.c: add an --atomic-push argument Ronnie Sahlberg
-- strict thread matches above, loose matches on Subject: below --
2014-07-31 21:39 [PATCH 0/5] ref-transactions-send-pack Ronnie Sahlberg
2014-07-31 21:39 ` [PATCH 3/5] receive-pack.c: use a single transaction when atomic-push is negotiated Ronnie Sahlberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1408465491-25488-4-git-send-email-sahlberg@google.com \
--to=sahlberg@google.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).