Git development
 help / color / mirror / Atom feed
From: Karthik Nayak <karthik.188@gmail.com>
To: git@vger.kernel.org
Cc: ps@pks.im, toon@iotcl.com, Karthik Nayak <karthik.188@gmail.com>
Subject: [PATCH v4 8/9] refs: add peeled object ID to the `ref_update` struct
Date: Mon, 04 May 2026 19:44:12 +0200	[thread overview]
Message-ID: <20260504-refs-move-to-generic-layer-v4-8-936ac2f0b1a3@gmail.com> (raw)
In-Reply-To: <20260504-refs-move-to-generic-layer-v4-0-936ac2f0b1a3@gmail.com>

Certain reference backends {packed, reftable}, have the ability to also
store the peeled object ID for a reference pointing to a tag object.
This has the added benefit that during retrieval of such references, we
also obtain the peeled object ID without having to use the ODB.

To provide this functionality, each backend independently calls the ODB
to obtain the peeled OID. To move this functionality to the generic
layer, there must be support infrastructure to pass in a peeled OID for
reference updates.

Add a `peeled` field to the `ref_update` structure and modify
`ref_transaction_add_update()` to receive and copy this object ID to the
`ref_update` structure. Finally, modify `ref_transaction_update()` to
peel tag objects and pass the peeled OID to
`ref_transaction_add_update()`.

Update all callers of these functions with the new function parameters.
Callers which only add reflog updates, need to only pass in NULL, since
for reflogs, we don't store peeled OIDs. Reference deletions also only
need to pass in NULL. For others, pass along the peeled OID if
available.

In a following commit, we'll modify the backends to use this peeled OID
instead of parsing it themselves.

Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
---
 refs.c                  | 15 +++++++++++++--
 refs/files-backend.c    | 20 ++++++++++++--------
 refs/refs-internal.h    | 14 ++++++++++++++
 refs/reftable-backend.c |  6 +++---
 4 files changed, 42 insertions(+), 13 deletions(-)

diff --git a/refs.c b/refs.c
index 662a9e6f9e..0648df2b6c 100644
--- a/refs.c
+++ b/refs.c
@@ -1307,6 +1307,7 @@ struct ref_update *ref_transaction_add_update(
 		const char *refname, unsigned int flags,
 		const struct object_id *new_oid,
 		const struct object_id *old_oid,
+		const struct object_id *peeled,
 		const char *new_target, const char *old_target,
 		const char *committer_info,
 		const char *msg)
@@ -1339,6 +1340,8 @@ struct ref_update *ref_transaction_add_update(
 		update->committer_info = xstrdup_or_null(committer_info);
 		update->msg = normalize_reflog_message(msg);
 	}
+	if (flags & REF_HAVE_PEELED)
+		oidcpy(&update->peeled, peeled);
 
 	/*
 	 * This list is generally used by the backends to avoid duplicates.
@@ -1392,6 +1395,8 @@ enum ref_transaction_error ref_transaction_update(struct ref_transaction *transa
 						  unsigned int flags, const char *msg,
 						  struct strbuf *err)
 {
+	struct object_id peeled;
+
 	assert(err);
 
 	if ((flags & REF_FORCE_CREATE_REFLOG) &&
@@ -1432,10 +1437,16 @@ enum ref_transaction_error ref_transaction_update(struct ref_transaction *transa
 				    oid_to_hex(new_oid), refname);
 			return REF_TRANSACTION_ERROR_INVALID_NEW_VALUE;
 		}
+
+		if (o->type == OBJ_TAG) {
+			if (!peel_object(transaction->ref_store->repo, new_oid, &peeled,
+					 PEEL_OBJECT_VERIFY_TAGGED_OBJECT_TYPE))
+				flags |= REF_HAVE_PEELED;
+		}
 	}
 
 	ref_transaction_add_update(transaction, refname, flags,
-				   new_oid, old_oid, new_target,
+				   new_oid, old_oid, &peeled, new_target,
 				   old_target, NULL, msg);
 
 	return 0;
@@ -1462,7 +1473,7 @@ int ref_transaction_update_reflog(struct ref_transaction *transaction,
 		return -1;
 
 	update = ref_transaction_add_update(transaction, refname, flags,
-					    new_oid, old_oid, NULL, NULL,
+					    new_oid, old_oid, NULL, NULL, NULL,
 					    committer_info, msg);
 	update->index = index;
 
diff --git a/refs/files-backend.c b/refs/files-backend.c
index f20f580fbc..d0896d0e37 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -1325,7 +1325,8 @@ static void prune_ref(struct files_ref_store *refs, struct ref_to_prune *r)
 	ref_transaction_add_update(
 			transaction, r->name,
 			REF_NO_DEREF | REF_HAVE_NEW | REF_HAVE_OLD | REF_IS_PRUNING,
-			null_oid(the_hash_algo), &r->oid, NULL, NULL, NULL, NULL);
+			null_oid(the_hash_algo), &r->oid, NULL, NULL, NULL,
+			NULL, NULL);
 	if (ref_transaction_commit(transaction, &err))
 		goto cleanup;
 
@@ -2468,7 +2469,7 @@ static enum ref_transaction_error split_head_update(struct ref_update *update,
 	new_update = ref_transaction_add_update(
 			transaction, "HEAD",
 			update->flags | REF_LOG_ONLY | REF_NO_DEREF | REF_LOG_VIA_SPLIT,
-			&update->new_oid, &update->old_oid,
+			&update->new_oid, &update->old_oid, &update->peeled,
 			NULL, NULL, update->committer_info, update->msg);
 	new_update->parent_update = update;
 
@@ -2530,8 +2531,8 @@ static enum ref_transaction_error split_symref_update(struct ref_update *update,
 			transaction, referent, new_flags,
 			update->new_target ? NULL : &update->new_oid,
 			update->old_target ? NULL : &update->old_oid,
-			update->new_target, update->old_target, NULL,
-			update->msg);
+			&update->peeled, update->new_target, update->old_target,
+			NULL, update->msg);
 
 	new_update->parent_update = update;
 
@@ -2994,7 +2995,7 @@ static int files_transaction_prepare(struct ref_store *ref_store,
 			ref_transaction_add_update(
 					packed_transaction, update->refname,
 					REF_HAVE_NEW | REF_NO_DEREF,
-					&update->new_oid, NULL,
+					&update->new_oid, NULL, NULL,
 					NULL, NULL, NULL, NULL);
 		}
 	}
@@ -3200,19 +3201,22 @@ static int files_transaction_finish_initial(struct files_ref_store *refs,
 			if (update->flags & REF_LOG_ONLY)
 				ref_transaction_add_update(loose_transaction, update->refname,
 							   update->flags, &update->new_oid,
-							   &update->old_oid, NULL, NULL,
+							   &update->old_oid, &update->peeled,
+							   NULL, NULL,
 							   update->committer_info, update->msg);
 			else
 				ref_transaction_add_update(loose_transaction, update->refname,
 							   update->flags & ~REF_HAVE_OLD,
 							   update->new_target ? NULL : &update->new_oid, NULL,
-							   update->new_target, NULL, update->committer_info,
+							   &update->peeled, update->new_target,
+							   NULL, update->committer_info,
 							   NULL);
 		} else {
 			ref_transaction_add_update(packed_transaction, update->refname,
 						   update->flags & ~REF_HAVE_OLD,
 						   &update->new_oid, &update->old_oid,
-						   NULL, NULL, update->committer_info, NULL);
+						   &update->peeled, NULL, NULL,
+						   update->committer_info, NULL);
 		}
 	}
 
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index d103387ebf..307dcb277b 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -39,6 +39,13 @@ struct ref_transaction;
  */
 #define REF_LOG_ONLY (1 << 7)
 
+/*
+ * The reference contains a peeled object ID. This is used when the
+ * new_oid is pointing to a tag object and the reference backend
+ * wants to also store the peeled value for optimized retrieval.
+ */
+#define REF_HAVE_PEELED (1 << 15)
+
 /*
  * Return the length of time to retry acquiring a loose reference lock
  * before giving up, in milliseconds:
@@ -92,6 +99,12 @@ struct ref_update {
 	 */
 	struct object_id old_oid;
 
+	/*
+	 * If the new_oid points to a tag object, set this to the peeled
+	 * object ID for optimized retrieval without needed to hit the odb.
+	 */
+	struct object_id peeled;
+
 	/*
 	 * If set, point the reference to this value. This can also be
 	 * used to convert regular references to become symbolic refs.
@@ -169,6 +182,7 @@ struct ref_update *ref_transaction_add_update(
 		const char *refname, unsigned int flags,
 		const struct object_id *new_oid,
 		const struct object_id *old_oid,
+		const struct object_id *peeled,
 		const char *new_target, const char *old_target,
 		const char *committer_info,
 		const char *msg);
diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c
index 444b0c24e5..b0c010387d 100644
--- a/refs/reftable-backend.c
+++ b/refs/reftable-backend.c
@@ -1107,8 +1107,8 @@ static enum ref_transaction_error prepare_single_update(struct reftable_ref_stor
 		ref_transaction_add_update(
 			transaction, "HEAD",
 			u->flags | REF_LOG_ONLY | REF_NO_DEREF,
-			&u->new_oid, &u->old_oid, NULL, NULL, NULL,
-			u->msg);
+			&u->new_oid, &u->old_oid, &u->peeled, NULL, NULL,
+			NULL, u->msg);
 	}
 
 	ret = reftable_backend_read_ref(be, rewritten_ref,
@@ -1194,7 +1194,7 @@ static enum ref_transaction_error prepare_single_update(struct reftable_ref_stor
 				transaction, referent->buf, new_flags,
 				u->new_target ? NULL : &u->new_oid,
 				u->old_target ? NULL : &u->old_oid,
-				u->new_target, u->old_target,
+				&u->peeled, u->new_target, u->old_target,
 				u->committer_info, u->msg);
 
 			new_update->parent_update = u;

-- 
2.53.GIT


  parent reply	other threads:[~2026-05-04 17:44 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-20 10:11 [PATCH 0/8] refs: move some of the generic logic out of the backends Karthik Nayak
2026-04-20 10:11 ` [PATCH 1/8] refs: remove unused typedef 'ref_transaction_commit_fn' Karthik Nayak
2026-04-22 11:15   ` Patrick Steinhardt
2026-04-22 12:20     ` Karthik Nayak
2026-04-20 10:12 ` [PATCH 2/8] refs: extract out reflog config to generic layer Karthik Nayak
2026-04-22 11:15   ` Patrick Steinhardt
2026-04-22 13:13     ` Karthik Nayak
2026-04-20 10:12 ` [PATCH 3/8] refs: return `ref_transaction_error` from `ref_transaction_update()` Karthik Nayak
2026-04-22 11:15   ` Patrick Steinhardt
2026-04-22 13:14     ` Karthik Nayak
2026-04-20 10:12 ` [PATCH 4/8] update-ref: move `print_rejected_refs()` up Karthik Nayak
2026-04-22 11:15   ` Patrick Steinhardt
2026-04-22 13:16     ` Karthik Nayak
2026-04-20 10:12 ` [PATCH 5/8] update-ref: handle rejections while adding updates Karthik Nayak
2026-04-22 11:15   ` Patrick Steinhardt
2026-04-22 14:13     ` Karthik Nayak
2026-04-20 10:12 ` [PATCH 6/8] refs: move object parsing to the generic layer Karthik Nayak
2026-04-22 11:15   ` Patrick Steinhardt
2026-04-22 15:03     ` Karthik Nayak
2026-04-20 10:12 ` [PATCH 7/8] refs: add peeled object ID to the `ref_update` struct Karthik Nayak
2026-04-20 10:12 ` [PATCH 8/8] refs: use peeled tag values in reference backends Karthik Nayak
2026-04-23  8:40 ` [PATCH v2 0/9] refs: move some of the generic logic out of the backends Karthik Nayak
2026-04-23  8:40   ` [PATCH v2 1/9] refs: remove unused typedef 'ref_transaction_commit_fn' Karthik Nayak
2026-04-23  8:40   ` [PATCH v2 2/9] refs: introduce `ref_store_init_options` Karthik Nayak
2026-04-23  8:52     ` Patrick Steinhardt
2026-04-24  9:34       ` Karthik Nayak
2026-04-23  8:40   ` [PATCH v2 3/9] refs: extract out reflog config to generic layer Karthik Nayak
2026-04-23  8:52     ` Patrick Steinhardt
2026-04-23  8:40   ` [PATCH v2 4/9] refs: return `ref_transaction_error` from `ref_transaction_update()` Karthik Nayak
2026-04-24 11:01     ` Toon Claes
2026-04-23  8:40   ` [PATCH v2 5/9] update-ref: move `print_rejected_refs()` up Karthik Nayak
2026-04-23  8:40   ` [PATCH v2 6/9] update-ref: handle rejections while adding updates Karthik Nayak
2026-04-23  8:52     ` Patrick Steinhardt
2026-04-24  9:35       ` Karthik Nayak
2026-04-24 11:22     ` Toon Claes
2026-04-27  8:47       ` Karthik Nayak
2026-04-23  8:40   ` [PATCH v2 7/9] refs: move object parsing to the generic layer Karthik Nayak
2026-04-24 12:06     ` Toon Claes
2026-04-27  9:32       ` Karthik Nayak
2026-04-23  8:40   ` [PATCH v2 8/9] refs: add peeled object ID to the `ref_update` struct Karthik Nayak
2026-04-24 16:44     ` Toon Claes
2026-04-27  9:33       ` Karthik Nayak
2026-04-23  8:40   ` [PATCH v2 9/9] refs: use peeled tag values in reference backends Karthik Nayak
2026-04-27 10:42 ` [PATCH v3 0/9] refs: move some of the generic logic out of the backends Karthik Nayak
2026-04-27 10:42   ` [PATCH v3 1/9] refs: remove unused typedef 'ref_transaction_commit_fn' Karthik Nayak
2026-04-27 10:42   ` [PATCH v3 2/9] refs: introduce `ref_store_init_options` Karthik Nayak
2026-04-27 10:42   ` [PATCH v3 3/9] refs: extract out reflog config to generic layer Karthik Nayak
2026-04-27 10:42   ` [PATCH v3 4/9] refs: return `ref_transaction_error` from `ref_transaction_update()` Karthik Nayak
2026-04-27 10:42   ` [PATCH v3 5/9] update-ref: move `print_rejected_refs()` up Karthik Nayak
2026-04-27 10:42   ` [PATCH v3 6/9] update-ref: handle rejections while adding updates Karthik Nayak
2026-04-29 12:24     ` Toon Claes
2026-04-30  9:52       ` Karthik Nayak
2026-04-27 10:42   ` [PATCH v3 7/9] refs: move object parsing to the generic layer Karthik Nayak
2026-04-27 10:42   ` [PATCH v3 8/9] refs: add peeled object ID to the `ref_update` struct Karthik Nayak
2026-04-27 10:42   ` [PATCH v3 9/9] refs: use peeled tag values in reference backends Karthik Nayak
2026-05-04 17:44 ` [PATCH v4 0/9] refs: move some of the generic logic out of the backends Karthik Nayak
2026-05-04 17:44   ` [PATCH v4 1/9] refs: remove unused typedef 'ref_transaction_commit_fn' Karthik Nayak
2026-05-04 17:44   ` [PATCH v4 2/9] refs: introduce `ref_store_init_options` Karthik Nayak
2026-05-04 17:44   ` [PATCH v4 3/9] refs: extract out reflog config to generic layer Karthik Nayak
2026-05-04 17:44   ` [PATCH v4 4/9] refs: return `ref_transaction_error` from `ref_transaction_update()` Karthik Nayak
2026-05-04 17:44   ` [PATCH v4 5/9] update-ref: move `print_rejected_refs()` up Karthik Nayak
2026-05-04 17:44   ` [PATCH v4 6/9] update-ref: handle rejections while adding updates Karthik Nayak
2026-05-05  5:52     ` Patrick Steinhardt
2026-05-05  8:23       ` Karthik Nayak
2026-05-06 19:44         ` Toon Claes
2026-05-04 17:44   ` [PATCH v4 7/9] refs: move object parsing to the generic layer Karthik Nayak
2026-05-04 17:44   ` Karthik Nayak [this message]
2026-05-04 17:44   ` [PATCH v4 9/9] refs: use peeled tag values in reference backends Karthik Nayak

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=20260504-refs-move-to-generic-layer-v4-8-936ac2f0b1a3@gmail.com \
    --to=karthik.188@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=ps@pks.im \
    --cc=toon@iotcl.com \
    /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