git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCHv8 5/9] receive-pack.c: move transaction handling in a central place

From
Stefan Beller <sbeller@google.com>
Date
Dec 30, 2014, 02:36 UTC
Message-ID
<1419907007-19387-6-git-send-email-sbeller@google.com>
In-Reply-To
<1419907007-19387-1-git-send-email-sbeller@google.com>

No functional changes intended. This moves all code related to transactions into the execute_commands_loop function which was factored out of execute_commands. This includes beginning and committing the transaction as well as dealing with the errors which may occur during the begin and commit phase of a transaction.

Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
Notes:
    v8:
     move execute_commands_loop before execute_commands, so it compiles/links
     without warnings.
    
    v7:
     new in v7, this is part of the previous "[PATCH 4/7]
     receive-pack.c: receive-pack.c: use a single ref_transaction for atomic pushes"
    
    This covers the suggestion of patch 2 and 3 by Eric
    > patch 2: Factor out the main 'for' loop of execute_commands() into a
    > new function. This new function will eventually become
    > execute_commands_non_atomic(). At this point, execute_commands() is
    > pretty much in its final form with the exception of the upcoming 'if
    > (use_atomic)' conditional.
    > patch 3: Morph the function extracted in patch 2 into
    > execute_commands_non_atomic() by adding transaction handling inside
    > the 'for' loop (and applying the changes from the early part of the
    > patch which go along with that).
 builtin/receive-pack.c | 69 ++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 50 insertions(+), 19 deletions(-)
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 06eb287..5f44466 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -67,6 +67,7 @@ static const char *NONCE_SLOP = "SLOP";
 static const char *nonce_status;
 static long nonce_stamp_slop;
 static unsigned long nonce_stamp_slop_limit;
+static struct ref_transaction *transaction;
 
 static enum deny_action parse_deny_action(const char *var, const char *value)
 {
@@ -822,6 +823,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
 	}
 
 	if (is_null_sha1(new_sha1)) {
+		struct strbuf err = STRBUF_INIT;
 		if (!parse_object(old_sha1)) {
 			old_sha1 = NULL;
 			if (ref_exists(name)) {
@@ -831,35 +833,36 @@ static const char *update(struct command *cmd, struct shallow_info *si)
 				cmd->did_not_exist = 1;
 			}
 		}
-		if (delete_ref(namespaced_name, old_sha1, 0)) {
-			rp_error("failed to delete %s", name);
+		if (ref_transaction_delete(transaction,
+					   namespaced_name,
+					   old_sha1,
+					   0, old_sha1 != NULL,
+					   "push", &err)) {
+			rp_error("%s", err.buf);
+			strbuf_release(&err);
 			return "failed to delete";
 		}
+		strbuf_release(&err);
 		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 "shallow error";
 
-		transaction = ref_transaction_begin(&err);
-		if (!transaction ||
-		    ref_transaction_update(transaction, namespaced_name,
-					   new_sha1, old_sha1, 0, 1, "push",
-					   &err) ||
-		    ref_transaction_commit(transaction, &err)) {
-			ref_transaction_free(transaction);
-
+		if (ref_transaction_update(transaction,
+					   namespaced_name,
+					   new_sha1, old_sha1,
+					   0, 1, "push",
+					   &err)) {
 			rp_error("%s", err.buf);
 			strbuf_release(&err);
+
 			return "failed to update ref";
 		}
-
-		ref_transaction_free(transaction);
 		strbuf_release(&err);
+
 		return NULL; /* good */
 	}
 }
@@ -1073,6 +1076,38 @@ static void check_shallow_bugs(struct command *commands,
 		      "the reported refs above");
 }
 
+static void execute_commands_loop(struct command *commands,
+				  struct shallow_info *si)
+{
+	struct command *cmd;
+	struct strbuf err = STRBUF_INIT;
+
+	for (cmd = commands; cmd; cmd = cmd->next) {
+		if (!should_process_cmd(cmd))
+			continue;
+
+		transaction = ref_transaction_begin(&err);
+		if (!transaction) {
+			rp_error("%s", err.buf);
+			strbuf_reset(&err);
+			cmd->error_string = "transaction failed to start";
+			continue;
+		}
+
+		cmd->error_string = update(cmd, si);
+
+		if (!cmd->error_string
+		    && ref_transaction_commit(transaction, &err)) {
+			rp_error("%s", err.buf);
+			strbuf_reset(&err);
+			cmd->error_string = "failed to update ref";
+		}
+		ref_transaction_free(transaction);
+	}
+
+	strbuf_release(&err);
+}
+
 static void execute_commands(struct command *commands,
 			     const char *unpacker_error,
 			     struct shallow_info *si)
@@ -1107,12 +1142,8 @@ static void execute_commands(struct command *commands,
 	free(head_name_to_free);
 	head_name = head_name_to_free = resolve_refdup("HEAD", 0, sha1, NULL);
 
-	for (cmd = commands; cmd; cmd = cmd->next) {
-		if (!should_process_cmd(cmd))
-			continue;
+	execute_commands_loop(commands, si);
 
-		cmd->error_string = update(cmd, si);
-	}
 	check_shallow_bugs(commands, si);
 }
 
-- 
2.2.1.62.g3f15098
Previous: Eric SunshineNext: Eric Sunshine
Message 16 of 24 in “[PATCHv8 0/9] atomic pushes”
  1. Stefan BellerDec 30, 2014
  2. 1/9 receive-pack.c: add documentation for atomic push supportStefan Beller, Dec 30, 2014
  3. Eric SunshineDec 30, 2014
  4. Stefan BellerDec 30, 2014
  5. Eric SunshineDec 30, 2014
  6. 2/9 send-pack: rename ref_update_to_be_sent to check_to_send_updateStefan Beller, Dec 30, 2014
  7. 3/9 send-pack.c: add --atomic command line argumentStefan Beller, Dec 30, 2014
  8. 4/9 receive-pack.c: simplify execute_commandsStefan Beller, Dec 30, 2014
  9. Eric SunshineDec 30, 2014
  10. Stefan BellerDec 30, 2014
  11. Stefan BellerDec 30, 2014
  12. Eric SunshineDec 30, 2014
  13. Eric SunshineDec 30, 2014
  14. Stefan BellerDec 30, 2014
  15. Eric SunshineDec 30, 2014
  16. 5/9 receive-pack.c: move transaction handling in a central placeStefan Beller, Dec 30, 2014
  17. Eric SunshineDec 30, 2014
  18. Stefan BellerDec 30, 2014
  19. Eric SunshineDec 30, 2014
  20. 6/9 receive-pack.c: add execute_commands_atomic functionStefan Beller, Dec 30, 2014
  21. Eric SunshineDec 30, 2014
  22. 7/9 receive-pack.c: enable atomic push protocol supportStefan Beller, Dec 30, 2014
  23. 8/9 push.c: add an --atomic argumentStefan Beller, Dec 30, 2014
  24. 9/9 t5543-atomic-push.sh: add basic tests for atomic pushesStefan Beller, Dec 30, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.