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

[PATCH v10 2/8] refs: atomically record overwritten ref in update_symref

From
Bence Ferdinandy <bence@ferdinandy.com>
Date
Oct 21, 2024, 13:36 UTC
Message-ID
<20241021134354.705636-3-bence@ferdinandy.com>
In-Reply-To
<20241021134354.705636-1-bence@ferdinandy.com>

When updating a symref with update_symref it's currently not possible to know for sure what was the previous value that was overwritten. Extend refs_update_symref under a new function name, to record the value after the ref has been locked if the caller of refs_update_symref_extended requests it via a new variable in the function call. Keep the original refs_update_symref function with the same signature, but now as a wrapper around refs_update_symref_extended.

Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com>
---
Notes:
    v4: new patch
    
    v5: - added before_target to reftables backend
        - added an extra safety check for transaction's existence in refs.c
    
    v6: - no change
    
    v7: - remove the whole before_target concept from the backends and
          handle checking it in refs.c instead (thanks Karthik)
        - rename the before_target to referent which is how the same concept
          is called in the backends
        - change commit prefix to be more in line with project standards
    
    v8: no change
    
    v9: - instead of adding parameters to refs_update_symref, rename what
          was in v8 as refs_update_symref_extended and make refs_update_symref
          a wrapper for that. This significantly reduces the number of files
          that need to be touched, and avoids adding a lot of dummy NULL-s
          in unrelated places.
    
    v10: no change
 refs.c | 19 ++++++++++++++++---
 refs.h |  4 ++++
 2 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/refs.c b/refs.c
index 5f729ed412..24a4172cd2 100644
--- a/refs.c
+++ b/refs.c
@@ -2115,6 +2115,13 @@ int peel_iterated_oid(struct repository *r, const struct object_id *base, struct
 
 int refs_update_symref(struct ref_store *refs, const char *ref,
 		       const char *target, const char *logmsg)
+{
+	return refs_update_symref_extended(refs, ref, target, logmsg, NULL);
+}
+
+int refs_update_symref_extended(struct ref_store *refs, const char *ref,
+		       const char *target, const char *logmsg,
+		       struct strbuf *referent)
 {
 	struct ref_transaction *transaction;
 	struct strbuf err = STRBUF_INIT;
@@ -2122,13 +2129,20 @@ int refs_update_symref(struct ref_store *refs, const char *ref,
 
 	transaction = ref_store_transaction_begin(refs, &err);
 	if (!transaction ||
-	    ref_transaction_update(transaction, ref, NULL, NULL,
+		ref_transaction_update(transaction, ref, NULL, NULL,
 				   target, NULL, REF_NO_DEREF,
 				   logmsg, &err) ||
-	    ref_transaction_commit(transaction, &err)) {
+		ref_transaction_prepare(transaction, &err)) {
 		ret = error("%s", err.buf);
+		goto cleanup;
 	}
+	if (referent)
+		refs_read_symbolic_ref(refs, ref, referent);
 
+	if (ref_transaction_commit(transaction, &err))
+		ret = error("%s", err.buf);
+
+cleanup:
 	strbuf_release(&err);
 	if (transaction)
 		ref_transaction_free(transaction);
@@ -2948,4 +2962,3 @@ int ref_update_expects_existing_old_ref(struct ref_update *update)
 	return (update->flags & REF_HAVE_OLD) &&
 		(!is_null_oid(&update->old_oid) || update->old_target);
 }
-
diff --git a/refs.h b/refs.h
index 108dfc93b3..259191a485 100644
--- a/refs.h
+++ b/refs.h
@@ -573,6 +573,10 @@ int refs_copy_existing_ref(struct ref_store *refs, const char *oldref,
 int refs_update_symref(struct ref_store *refs, const char *refname,
 		       const char *target, const char *logmsg);
 
+int refs_update_symref_extended(struct ref_store *refs, const char *refname,
+		       const char *target, const char *logmsg,
+		       struct strbuf *referent);
+
 enum action_on_err {
 	UPDATE_REFS_MSG_ON_ERR,
 	UPDATE_REFS_DIE_ON_ERR,
-- 
2.47.0.94.g8861098b6d
Previous: Bence FerdinandyNext: Bence Ferdinandy
Message 3 of 15 in “set-head/fetch remote/HEAD updates”
  1. 0/8 set-head/fetch remote/HEAD updatesBence Ferdinandy, Oct 21, 2024
  2. 1/8 t/t5505-remote: set default branch to mainBence Ferdinandy, Oct 21, 2024
  3. 2/8 refs: atomically record overwritten ref in update_symrefBence Ferdinandy, Oct 21, 2024
  4. 3/8 remote set-head: refactor for readabilityBence Ferdinandy, Oct 21, 2024
  5. 4/8 remote set-head: better output for --autoBence Ferdinandy, Oct 21, 2024
  6. 5/8 refs: add TRANSACTION_CREATE_EXISTS errorBence Ferdinandy, Oct 21, 2024
  7. 6/8 refs: add create_only option to refs_update_symref_extendedBence Ferdinandy, Oct 21, 2024
  8. 8/8 fetch set_head: handle mirrored bare repositoriesBence Ferdinandy, Oct 21, 2024
  9. 7/8 fetch: set remote/HEAD if it does not existBence Ferdinandy, Oct 21, 2024
  10. Taylor BlauOct 21, 2024
  11. Bence FerdinandyOct 21, 2024
  12. Taylor BlauOct 22, 2024
  13. Bence FerdinandyOct 22, 2024
  14. Taylor BlauOct 22, 2024
  15. Bence FerdinandyOct 22, 2024

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.