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

[PATCH v12 31/41] refs.c: make prune_ref use a transaction to delete the ref

From
Ronnie Sahlberg <sahlberg@google.com>
Date
May 29, 2014, 16:07 UTC
Message-ID
<1401379676-9307-8-git-send-email-sahlberg@google.com>
In-Reply-To
<1401379676-9307-1-git-send-email-sahlberg@google.com>

Change prune_ref to delete the ref using a ref transaction. To do this we also need to add a new flag REF_ISPRUNING that will tell the transaction that we do not want to delete this ref from the packed refs. This flag is private to refs.c and not exposed to external callers.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
---
 refs.c | 28 +++++++++++++++++++++-------
 refs.h | 11 ++++++++++-
 2 files changed, 31 insertions(+), 8 deletions(-)
diff --git a/refs.c b/refs.c
index 7cea694..60593d7 100644
--- a/refs.c
+++ b/refs.c
@@ -30,6 +30,12 @@ static inline int bad_ref_char(int ch)
 }
 
 /*
+ * Used as a flag to ref_transaction_delete when a loose ref is being
+ * pruned.
+ */
+#define REF_ISPRUNING	0x0100
+
+/*
  * Try to read one refname component from the front of refname.  Return
  * the length of the component found, or -1 if the component is not
  * legal.
@@ -2328,17 +2334,24 @@ static void try_remove_empty_parents(char *name)
 /* make sure nobody touched the ref, and unlink */
 static void prune_ref(struct ref_to_prune *r)
 {
-	struct ref_lock *lock;
+	struct ref_transaction *transaction;
+	struct strbuf err = STRBUF_INIT;
 
 	if (check_refname_format(r->name + 5, 0))
 		return;
 
-	lock = lock_ref_sha1_basic(r->name, r->sha1, 0, NULL);
-	if (lock) {
-		unlink_or_warn(git_path("%s", r->name));
-		unlock_ref(lock);
-		try_remove_empty_parents(r->name);
+	transaction = ref_transaction_begin(&err);
+	if (!transaction ||
+	    ref_transaction_delete(transaction, r->name, r->sha1,
+				   REF_ISPRUNING, 1, &err) ||
+	    ref_transaction_commit(transaction, NULL, &err)) {
+		ref_transaction_free(transaction);
+		error("%s", err.buf);
+		strbuf_release(&err);
+		return;
 	}
+	ref_transaction_free(transaction);
+	try_remove_empty_parents(r->name);
 }
 
 static void prune_refs(struct ref_to_prune *r)
@@ -3536,9 +3549,10 @@ int ref_transaction_commit(struct ref_transaction *transaction,
 		struct ref_update *update = updates[i];
 
 		if (update->lock) {
-			delnames[delnum++] = update->lock->ref_name;
 			ret |= delete_ref_loose(update->lock, update->type,
 						err);
+			if (!(update->flags & REF_ISPRUNING))
+				delnames[delnum++] = update->lock->ref_name;
 		}
 	}
 
diff --git a/refs.h b/refs.h
index c38ee09..dee7c8f 100644
--- a/refs.h
+++ b/refs.h
@@ -171,8 +171,17 @@ extern int ref_exists(const char *);
  */
 extern int peel_ref(const char *refname, unsigned char *sha1);
 
-/** Locks any ref (for 'HEAD' type refs). */
+/*
+ * Flags controlling lock_any_ref_for_update(), ref_transaction_update(),
+ * ref_transaction_create(), etc.
+ * REF_NODEREF: act on the ref directly, instead of dereferencing
+ *              symbolic references.
+ *
+ * Flags >= 0x100 are reserved for internal use.
+ */
 #define REF_NODEREF	0x01
+
+/** Locks any ref (for 'HEAD' type refs). */
 extern struct ref_lock *lock_any_ref_for_update(const char *refname,
 						const unsigned char *old_sha1,
 						int flags, int *type_p);
-- 
2.0.0.rc3.474.g3833130
Previous: Ronnie SahlbergNext: Ronnie Sahlberg
Message 10 of 18 in “Use ref transactions for all ref updates”
  1. 00/44 Use ref transactions for all ref updatesRonnie Sahlberg, May 29, 2014
  2. 06/41 refs.c: add an err argument to repack_without_refsRonnie Sahlberg, May 29, 2014
  3. Jonathan NiederMay 29, 2014
  4. Ronnie SahlbergJun 3, 2014
  5. 08/41 refs.c: add an err argument to delete_ref_looseRonnie Sahlberg, May 29, 2014
  6. 16/41 refs.c: add transaction.status and track OPEN/CLOSED/ERRORRonnie Sahlberg, May 29, 2014
  7. 24/41 receive-pack.c: use a reference transaction for updating the refsRonnie Sahlberg, May 29, 2014
  8. 25/41 fast-import.c: use a ref transaction when dumping tagsRonnie Sahlberg, May 29, 2014
  9. 26/41 walker.c: use ref transaction for ref updatesRonnie Sahlberg, May 29, 2014
  10. 31/41 refs.c: make prune_ref use a transaction to delete the refRonnie Sahlberg, May 29, 2014
  11. 32/41 refs.c: make delete_ref use a transactionRonnie Sahlberg, May 29, 2014
  12. 33/41 refs.c: pass the ref log message to _create/delete/update instead of _commitRonnie Sahlberg, May 29, 2014
  13. 36/41 refs.c: move the check for valid refname to lock_ref_sha1_basicRonnie Sahlberg, May 29, 2014
  14. 38/41 refs.c: pass a skip list to name_conflict_fnRonnie Sahlberg, May 29, 2014
  15. 39/41 refs.c: propagate any errno==ENOTDIR from _commit back to the callersRonnie Sahlberg, May 29, 2014
  16. 40/41 fetch.c: change s_update_ref to use a ref transactionRonnie Sahlberg, May 29, 2014
  17. 41/41 refs.c: make write_ref_sha1 staticRonnie Sahlberg, May 29, 2014
  18. Ronnie SahlbergMay 29, 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.