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

[PATCH v6 17/25] refs: move transaction functions to the common code

From
Michael Haggerty <mhagger@alum.mit.edu>
Date
Nov 3, 2015, 07:40 UTC
Message-ID
<69658d718bd300009c5ae17388b548937b9751fb.1446534991.git.mhagger@alum.mit.edu>
In-Reply-To
<cover.1446534991.git.mhagger@alum.mit.edu>
From: David Turner <dturner@twopensource.com>

The common ref code will build up a ref transaction. Backends will then commit it. So the transaction creation and update functions should be in the common code.

The backends will also need access to some constants and structs that, until now, were defined within refs.c and treated as private. So move those into a new header file, refs/refs-internal.h, that is intended for internal use only within the refs module.

Later, we will modify struct ref_update to support alternate backends.
Signed-off-by: David Turner <dturner@twopensource.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 refs/files-backend.c | 200 +--------------------------------------------------
 refs/refs-internal.h | 102 ++++++++++++++++++++++++++
 refs/refs.c          | 110 +++++++++++++++++++++++++++-
 3 files changed, 212 insertions(+), 200 deletions(-)
 create mode 100644 refs/refs-internal.h
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 728e646..1719720 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -1,5 +1,5 @@
 #include "../cache.h"
-#include "../refs.h"
+#include "refs-internal.h"
 #include "../lockfile.h"
 #include "../object.h"
 #include "../tag.h"
@@ -13,41 +13,6 @@ struct ref_lock {
 	struct object_id old_oid;
 };
 
-/*
- * Flag passed to lock_ref_sha1_basic() telling it to tolerate broken
- * refs (i.e., because the reference is about to be deleted anyway).
- */
-#define REF_DELETING	0x02
-
-/*
- * Used as a flag in ref_update::flags when a loose ref is being
- * pruned.
- */
-#define REF_ISPRUNING	0x04
-
-/*
- * Used as a flag in ref_update::flags when the reference should be
- * updated to new_sha1.
- */
-#define REF_HAVE_NEW	0x08
-
-/*
- * Used as a flag in ref_update::flags when old_sha1 should be
- * checked.
- */
-#define REF_HAVE_OLD	0x10
-
-/*
- * Used as a flag in ref_update::flags when the lockfile needs to be
- * committed.
- */
-#define REF_NEEDS_COMMIT 0x20
-
-/*
- * 0x40 is REF_FORCE_CREATE_REFLOG, so skip it if you're adding a
- * value to ref_update::flags
- */
-
 struct ref_entry;
 
 /*
@@ -3289,169 +3254,6 @@ int for_each_reflog(each_ref_fn fn, void *cb_data)
 	return retval;
 }
 
-/**
- * Information needed for a single ref update. Set new_sha1 to the new
- * value or to null_sha1 to delete the ref. To check the old value
- * while the ref is locked, set (flags & REF_HAVE_OLD) and set
- * old_sha1 to the old value, or to null_sha1 to ensure the ref does
- * not exist before update.
- */
-struct ref_update {
-	/*
-	 * If (flags & REF_HAVE_NEW), set the reference to this value:
-	 */
-	unsigned char new_sha1[20];
-	/*
-	 * If (flags & REF_HAVE_OLD), check that the reference
-	 * previously had this value:
-	 */
-	unsigned char old_sha1[20];
-	/*
-	 * One or more of REF_HAVE_NEW, REF_HAVE_OLD, REF_NODEREF,
-	 * REF_DELETING, and REF_ISPRUNING:
-	 */
-	unsigned int flags;
-	struct ref_lock *lock;
-	int type;
-	char *msg;
-	const char refname[FLEX_ARRAY];
-};
-
-/*
- * Transaction states.
- * OPEN:   The transaction is in a valid state and can accept new updates.
- *         An OPEN transaction can be committed.
- * CLOSED: A closed transaction is no longer active and no other operations
- *         than free can be used on it in this state.
- *         A transaction can either become closed by successfully committing
- *         an active transaction or if there is a failure while building
- *         the transaction thus rendering it failed/inactive.
- */
-enum ref_transaction_state {
-	REF_TRANSACTION_OPEN   = 0,
-	REF_TRANSACTION_CLOSED = 1
-};
-
-/*
- * Data structure for holding a reference transaction, which can
- * consist of checks and updates to multiple references, carried out
- * as atomically as possible.  This structure is opaque to callers.
- */
-struct ref_transaction {
-	struct ref_update **updates;
-	size_t alloc;
-	size_t nr;
-	enum ref_transaction_state state;
-};
-
-struct ref_transaction *ref_transaction_begin(struct strbuf *err)
-{
-	assert(err);
-
-	return xcalloc(1, sizeof(struct ref_transaction));
-}
-
-void ref_transaction_free(struct ref_transaction *transaction)
-{
-	int i;
-
-	if (!transaction)
-		return;
-
-	for (i = 0; i < transaction->nr; i++) {
-		free(transaction->updates[i]->msg);
-		free(transaction->updates[i]);
-	}
-	free(transaction->updates);
-	free(transaction);
-}
-
-static struct ref_update *add_update(struct ref_transaction *transaction,
-				     const char *refname)
-{
-	size_t len = strlen(refname) + 1;
-	struct ref_update *update = xcalloc(1, sizeof(*update) + len);
-
-	memcpy((char *)update->refname, refname, len); /* includes NUL */
-	ALLOC_GROW(transaction->updates, transaction->nr + 1, transaction->alloc);
-	transaction->updates[transaction->nr++] = update;
-	return update;
-}
-
-int ref_transaction_update(struct ref_transaction *transaction,
-			   const char *refname,
-			   const unsigned char *new_sha1,
-			   const unsigned char *old_sha1,
-			   unsigned int flags, const char *msg,
-			   struct strbuf *err)
-{
-	struct ref_update *update;
-
-	assert(err);
-
-	if (transaction->state != REF_TRANSACTION_OPEN)
-		die("BUG: update called for transaction that is not open");
-
-	if (new_sha1 && !is_null_sha1(new_sha1) &&
-	    check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
-		strbuf_addf(err, "refusing to update ref with bad name %s",
-			    refname);
-		return -1;
-	}
-
-	update = add_update(transaction, refname);
-	if (new_sha1) {
-		hashcpy(update->new_sha1, new_sha1);
-		flags |= REF_HAVE_NEW;
-	}
-	if (old_sha1) {
-		hashcpy(update->old_sha1, old_sha1);
-		flags |= REF_HAVE_OLD;
-	}
-	update->flags = flags;
-	if (msg)
-		update->msg = xstrdup(msg);
-	return 0;
-}
-
-int ref_transaction_create(struct ref_transaction *transaction,
-			   const char *refname,
-			   const unsigned char *new_sha1,
-			   unsigned int flags, const char *msg,
-			   struct strbuf *err)
-{
-	if (!new_sha1 || is_null_sha1(new_sha1))
-		die("BUG: create called without valid new_sha1");
-	return ref_transaction_update(transaction, refname, new_sha1,
-				      null_sha1, flags, msg, err);
-}
-
-int ref_transaction_delete(struct ref_transaction *transaction,
-			   const char *refname,
-			   const unsigned char *old_sha1,
-			   unsigned int flags, const char *msg,
-			   struct strbuf *err)
-{
-	if (old_sha1 && is_null_sha1(old_sha1))
-		die("BUG: delete called with old_sha1 set to zeros");
-	return ref_transaction_update(transaction, refname,
-				      null_sha1, old_sha1,
-				      flags, msg, err);
-}
-
-int ref_transaction_verify(struct ref_transaction *transaction,
-			   const char *refname,
-			   const unsigned char *old_sha1,
-			   unsigned int flags,
-			   struct strbuf *err)
-{
-	if (!old_sha1)
-		die("BUG: verify called with old_sha1 set to NULL");
-	return ref_transaction_update(transaction, refname,
-				      NULL, old_sha1,
-				      flags, NULL, err);
-}
-
 static int ref_update_reject_duplicates(struct string_list *refnames,
 					struct strbuf *err)
 {
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
new file mode 100644
index 0000000..94f5dde
--- /dev/null
+++ b/refs/refs-internal.h
@@ -0,0 +1,102 @@
+#ifndef REFS_REFS_INTERNAL_H
+#define REFS_REFS_INTERNAL_H
+
+/*
+ * Data structures and functions for the internal use of the refs
+ * module. Code outside of the refs module should use only the public
+ * functions defined in "refs.h", and should *not* include this file.
+ */
+
+#include "../refs.h"
+
+/*
+ * Flag passed to lock_ref_sha1_basic() telling it to tolerate broken
+ * refs (i.e., because the reference is about to be deleted anyway).
+ */
+#define REF_DELETING	0x02
+
+/*
+ * Used as a flag in ref_update::flags when a loose ref is being
+ * pruned.
+ */
+#define REF_ISPRUNING	0x04
+
+/*
+ * Used as a flag in ref_update::flags when the reference should be
+ * updated to new_sha1.
+ */
+#define REF_HAVE_NEW	0x08
+
+/*
+ * Used as a flag in ref_update::flags when old_sha1 should be
+ * checked.
+ */
+#define REF_HAVE_OLD	0x10
+
+/*
+ * Used as a flag in ref_update::flags when the lockfile needs to be
+ * committed.
+ */
+#define REF_NEEDS_COMMIT 0x20
+
+/*
+ * 0x40 is REF_FORCE_CREATE_REFLOG, so skip it if you're adding a
+ * value to ref_update::flags
+ */
+
+/**
+ * Information needed for a single ref update. Set new_sha1 to the new
+ * value or to null_sha1 to delete the ref. To check the old value
+ * while the ref is locked, set (flags & REF_HAVE_OLD) and set
+ * old_sha1 to the old value, or to null_sha1 to ensure the ref does
+ * not exist before update.
+ */
+struct ref_update {
+	/*
+	 * If (flags & REF_HAVE_NEW), set the reference to this value:
+	 */
+	unsigned char new_sha1[20];
+	/*
+	 * If (flags & REF_HAVE_OLD), check that the reference
+	 * previously had this value:
+	 */
+	unsigned char old_sha1[20];
+	/*
+	 * One or more of REF_HAVE_NEW, REF_HAVE_OLD, REF_NODEREF,
+	 * REF_DELETING, and REF_ISPRUNING:
+	 */
+	unsigned int flags;
+	struct ref_lock *lock;
+	int type;
+	char *msg;
+	const char refname[FLEX_ARRAY];
+};
+
+/*
+ * Transaction states.
+ * OPEN:   The transaction is in a valid state and can accept new updates.
+ *         An OPEN transaction can be committed.
+ * CLOSED: A closed transaction is no longer active and no other operations
+ *         than free can be used on it in this state.
+ *         A transaction can either become closed by successfully committing
+ *         an active transaction or if there is a failure while building
+ *         the transaction thus rendering it failed/inactive.
+ */
+enum ref_transaction_state {
+	REF_TRANSACTION_OPEN   = 0,
+	REF_TRANSACTION_CLOSED = 1
+};
+
+/*
+ * Data structure for holding a reference transaction, which can
+ * consist of checks and updates to multiple references, carried out
+ * as atomically as possible.  This structure is opaque to callers.
+ */
+struct ref_transaction {
+	struct ref_update **updates;
+	size_t alloc;
+	size_t nr;
+	enum ref_transaction_state state;
+};
+
+#endif /* REFS_REFS_INTERNAL_H */
diff --git a/refs/refs.c b/refs/refs.c
index 6af5fd6..0d0579f 100644
--- a/refs/refs.c
+++ b/refs/refs.c
@@ -2,7 +2,7 @@
  * Common refs code for all backends.
  */
 #include "../cache.h"
-#include "../refs.h"
+#include "refs-internal.h"
 #include "../lockfile.h"
 
 static int is_per_worktree_ref(const char *refname)
@@ -841,3 +841,111 @@ int head_ref_namespaced(each_ref_fn fn, void *cb_data)
 
 	return ret;
 }
+
+struct ref_transaction *ref_transaction_begin(struct strbuf *err)
+{
+	assert(err);
+
+	return xcalloc(1, sizeof(struct ref_transaction));
+}
+
+void ref_transaction_free(struct ref_transaction *transaction)
+{
+	int i;
+
+	if (!transaction)
+		return;
+
+	for (i = 0; i < transaction->nr; i++) {
+		free(transaction->updates[i]->msg);
+		free(transaction->updates[i]);
+	}
+	free(transaction->updates);
+	free(transaction);
+}
+
+static struct ref_update *add_update(struct ref_transaction *transaction,
+				     const char *refname)
+{
+	size_t len = strlen(refname) + 1;
+	struct ref_update *update = xcalloc(1, sizeof(*update) + len);
+
+	memcpy((char *)update->refname, refname, len); /* includes NUL */
+	ALLOC_GROW(transaction->updates, transaction->nr + 1, transaction->alloc);
+	transaction->updates[transaction->nr++] = update;
+	return update;
+}
+
+int ref_transaction_update(struct ref_transaction *transaction,
+			   const char *refname,
+			   const unsigned char *new_sha1,
+			   const unsigned char *old_sha1,
+			   unsigned int flags, const char *msg,
+			   struct strbuf *err)
+{
+	struct ref_update *update;
+
+	assert(err);
+
+	if (transaction->state != REF_TRANSACTION_OPEN)
+		die("BUG: update called for transaction that is not open");
+
+	if (new_sha1 && !is_null_sha1(new_sha1) &&
+	    check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
+		strbuf_addf(err, "refusing to update ref with bad name %s",
+			    refname);
+		return -1;
+	}
+
+	update = add_update(transaction, refname);
+	if (new_sha1) {
+		hashcpy(update->new_sha1, new_sha1);
+		flags |= REF_HAVE_NEW;
+	}
+	if (old_sha1) {
+		hashcpy(update->old_sha1, old_sha1);
+		flags |= REF_HAVE_OLD;
+	}
+	update->flags = flags;
+	if (msg)
+		update->msg = xstrdup(msg);
+	return 0;
+}
+
+int ref_transaction_create(struct ref_transaction *transaction,
+			   const char *refname,
+			   const unsigned char *new_sha1,
+			   unsigned int flags, const char *msg,
+			   struct strbuf *err)
+{
+	if (!new_sha1 || is_null_sha1(new_sha1))
+		die("BUG: create called without valid new_sha1");
+	return ref_transaction_update(transaction, refname, new_sha1,
+				      null_sha1, flags, msg, err);
+}
+
+int ref_transaction_delete(struct ref_transaction *transaction,
+			   const char *refname,
+			   const unsigned char *old_sha1,
+			   unsigned int flags, const char *msg,
+			   struct strbuf *err)
+{
+	if (old_sha1 && is_null_sha1(old_sha1))
+		die("BUG: delete called with old_sha1 set to zeros");
+	return ref_transaction_update(transaction, refname,
+				      null_sha1, old_sha1,
+				      flags, msg, err);
+}
+
+int ref_transaction_verify(struct ref_transaction *transaction,
+			   const char *refname,
+			   const unsigned char *old_sha1,
+			   unsigned int flags,
+			   struct strbuf *err)
+{
+	if (!old_sha1)
+		die("BUG: verify called with old_sha1 set to NULL");
+	return ref_transaction_update(transaction, refname,
+				      NULL, old_sha1,
+				      flags, NULL, err);
+}
-- 
2.6.2
Previous: Michael HaggertyNext: Michael Haggerty
Message 50 of 67 in “refs backend pre-vtable”
  1. 00/26 refs backend pre-vtableDavid Turner, Oct 28, 2015
  2. 01/26 refs.c: create a public version of verify_refname_availableDavid Turner, Oct 28, 2015
  3. 02/26 refs: make is_branch publicDavid Turner, Oct 28, 2015
  4. 03/26 refs-be-files.c: rename refs to refs-be-filesDavid Turner, Oct 28, 2015
  5. 04/26 refs.c: add a new refs.c file to hold all common refs codeDavid Turner, Oct 28, 2015
  6. 05/26 refs.c: move update_ref to refs.cDavid Turner, Oct 28, 2015
  7. 06/26 refs.c: move delete_pseudoref and delete_ref to the common codeDavid Turner, Oct 28, 2015
  8. 07/26 refs.c: move read_ref_at to the common refs fileDavid Turner, Oct 28, 2015
  9. 08/26 refs.c: move the hidden refs functions to the common codeDavid Turner, Oct 28, 2015
  10. 09/26 refs.c: move dwim and friend functions to the common refs codeDavid Turner, Oct 28, 2015
  11. 10/26 refs.c: move warn_if_dangling_symref* to the common codeDavid Turner, Oct 28, 2015
  12. 11/26 refs.c: move read_ref, read_ref_full and ref_exists to the common codeDavid Turner, Oct 28, 2015
  13. 12/26 refs.c: move resolve_refdup to commonDavid Turner, Oct 28, 2015
  14. 13/26 refs.c: move check_refname_format to the common codeDavid Turner, Oct 28, 2015
  15. 14/26 refs.c: move is_branch to the common codeDavid Turner, Oct 28, 2015
  16. 15/26 refs.c: move prettify_refname to the common codeDavid Turner, Oct 28, 2015
  17. 16/26 refs.c: move ref iterators to the common codeDavid Turner, Oct 28, 2015
  18. Michael HaggertyNov 1, 2015
  19. 17/26 refs.c: move head_ref_namespaced to the common codeDavid Turner, Oct 28, 2015
  20. 18/26 refs: move transaction functions into common codeDavid Turner, Oct 28, 2015
  21. Michael HaggertyNov 1, 2015
  22. David TurnerNov 2, 2015
  23. 19/26 refs.c: move refname_is_safe to the common codeDavid Turner, Oct 28, 2015
  24. 20/26 refs.c: move copy_msg to the common codeDavid Turner, Oct 28, 2015
  25. 21/26 refs.c: move peel_object to the common codeDavid Turner, Oct 28, 2015
  26. 22/26 refs.c: move should_autocreate_reflog to common codeDavid Turner, Oct 28, 2015
  27. 23/26 initdb: move safe_create_dir into common codeDavid Turner, Oct 28, 2015
  28. 24/26 refs: make files_log_ref_write functions publicDavid Turner, Oct 28, 2015
  29. 25/26 refs: break out ref conflict checksDavid Turner, Oct 28, 2015
  30. Michael HaggertyNov 2, 2015
  31. 26/26 introduce "extensions" form of core.repositoryformatversionDavid Turner, Oct 28, 2015
  32. Michael HaggertyNov 3, 2015
  33. 00/25 refs backend pre-vtableMichael Haggerty, Nov 3, 2015
  34. 01/25 refs: make is_branch publicMichael Haggerty, Nov 3, 2015
  35. 02/25 refs/files-backend.c: new file, renamed from refs.cMichael Haggerty, Nov 3, 2015
  36. 03/25 refs: add a new file, refs/refs.c, to hold common refs codeMichael Haggerty, Nov 3, 2015
  37. 04/25 refs: move update_ref to refs/refs.cMichael Haggerty, Nov 3, 2015
  38. 05/25 refs: move delete_pseudoref and delete_ref to the common codeMichael Haggerty, Nov 3, 2015
  39. 06/25 refs: move read_ref_at to the common refs fileMichael Haggerty, Nov 3, 2015
  40. 07/25 refs: move the hidden refs functions to the common codeMichael Haggerty, Nov 3, 2015
  41. 08/25 refs: move dwim and friend functions to the common refs codeMichael Haggerty, Nov 3, 2015
  42. 09/25 refs: move warn_if_dangling_symref* to the common codeMichael Haggerty, Nov 3, 2015
  43. 10/25 refs: move read_ref, read_ref_full and ref_exists to the common codeMichael Haggerty, Nov 3, 2015
  44. 11/25 refs: move resolve_refdup to commonMichael Haggerty, Nov 3, 2015
  45. 12/25 refs: move check_refname_format to the common codeMichael Haggerty, Nov 3, 2015
  46. 13/25 refs: move is_branch to the common codeMichael Haggerty, Nov 3, 2015
  47. 14/25 refs: move prettify_refname to the common codeMichael Haggerty, Nov 3, 2015
  48. 15/25 refs: move ref iterators to the common codeMichael Haggerty, Nov 3, 2015
  49. 16/25 refs: move head_ref_namespaced to the common codeMichael Haggerty, Nov 3, 2015
  50. 17/25 refs: move transaction functions to the common codeMichael Haggerty, Nov 3, 2015
  51. 18/25 refs: move refname_is_safe to the common codeMichael Haggerty, Nov 3, 2015
  52. 19/25 refs: move copy_msg to the common codeMichael Haggerty, Nov 3, 2015
  53. 20/25 refs: move peel_object to the common codeMichael Haggerty, Nov 3, 2015
  54. 21/25 refs: move should_autocreate_reflog to common codeMichael Haggerty, Nov 3, 2015
  55. 22/25 initdb: make safe_create_dir publicMichael Haggerty, Nov 3, 2015
  56. 23/25 files_log_ref_write: new functionMichael Haggerty, Nov 3, 2015
  57. 24/25 refs: create a shared version of verify_refname_availableMichael Haggerty, Nov 3, 2015
  58. 25/25 refs: break out ref conflict checksMichael Haggerty, Nov 3, 2015
  59. David TurnerNov 4, 2015
  60. Michael HaggertyNov 5, 2015
  61. David TurnerNov 5, 2015
  62. Michael HaggertyNov 6, 2015
  63. Junio C HamanoNov 6, 2015
  64. Junio C HamanoNov 6, 2015
  65. Michael HaggertyNov 8, 2015
  66. Michael HaggertyNov 8, 2015
  67. Junio C HamanoNov 8, 2015

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.