summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/describe.c2
-rw-r--r--builtin/gc.c2
-rw-r--r--builtin/pack-objects.c7
-rw-r--r--commit-graph.c2
-rw-r--r--ls-refs.c2
-rw-r--r--midx-write.c2
-rw-r--r--pseudo-merge.c2
-rw-r--r--refs.c12
-rw-r--r--refs.h19
-rw-r--r--refs/packed-backend.c1
-rw-r--r--refs/reftable-backend.c5
-rw-r--r--repack-midx.c2
12 files changed, 48 insertions, 10 deletions
diff --git a/builtin/describe.c b/builtin/describe.c
index 7954535044..443546aaac 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -208,7 +208,7 @@ static int get_name(const struct reference *ref, void *cb_data UNUSED)
}
/* Is it annotated? */
- if (!peel_iterated_oid(the_repository, ref->oid, &peeled)) {
+ if (!reference_get_peeled_oid(the_repository, ref, &peeled)) {
is_annotated = !oideq(ref->oid, &peeled);
} else {
oidcpy(&peeled, ref->oid);
diff --git a/builtin/gc.c b/builtin/gc.c
index 9de5de175f..f0cf20d423 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -1109,7 +1109,7 @@ static int dfs_on_ref(const struct reference *ref, void *cb_data)
struct commit_list *stack = NULL;
struct commit *commit;
- if (!peel_iterated_oid(the_repository, ref->oid, &peeled))
+ if (!reference_get_peeled_oid(the_repository, ref, &peeled))
maybe_peeled = &peeled;
if (odb_read_object_info(the_repository->objects, maybe_peeled, NULL) != OBJ_COMMIT)
return 0;
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 39633a0158..1613fecb66 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -838,7 +838,7 @@ static int mark_tagged(const struct reference *ref, void *cb_data UNUSED)
if (entry)
entry->tagged = 1;
- if (!peel_iterated_oid(the_repository, ref->oid, &peeled)) {
+ if (!reference_get_peeled_oid(the_repository, ref, &peeled)) {
entry = packlist_find(&to_pack, &peeled);
if (entry)
entry->tagged = 1;
@@ -3309,7 +3309,8 @@ static int add_ref_tag(const struct reference *ref, void *cb_data UNUSED)
{
struct object_id peeled;
- if (!peel_iterated_oid(the_repository, ref->oid, &peeled) && obj_is_packed(&peeled))
+ if (!reference_get_peeled_oid(the_repository, ref, &peeled) &&
+ obj_is_packed(&peeled))
add_tag_chain(ref->oid);
return 0;
}
@@ -4537,7 +4538,7 @@ static int mark_bitmap_preferred_tip(const struct reference *ref, void *data UNU
struct object_id peeled;
struct object *object;
- if (!peel_iterated_oid(the_repository, ref->oid, &peeled))
+ if (!reference_get_peeled_oid(the_repository, ref, &peeled))
maybe_peeled = &peeled;
object = parse_object_or_die(the_repository, maybe_peeled, ref->name);
diff --git a/commit-graph.c b/commit-graph.c
index f91af41625..80be2ff2c3 100644
--- a/commit-graph.c
+++ b/commit-graph.c
@@ -1857,7 +1857,7 @@ static int add_ref_to_set(const struct reference *ref, void *cb_data)
struct object_id peeled;
struct refs_cb_data *data = (struct refs_cb_data *)cb_data;
- if (!peel_iterated_oid(data->repo, ref->oid, &peeled))
+ if (!reference_get_peeled_oid(data->repo, ref, &peeled))
maybe_peeled = &peeled;
if (odb_read_object_info(data->repo->objects, maybe_peeled, NULL) == OBJ_COMMIT)
oidset_insert(data->commits, maybe_peeled);
diff --git a/ls-refs.c b/ls-refs.c
index 64d0272369..8641281b86 100644
--- a/ls-refs.c
+++ b/ls-refs.c
@@ -110,7 +110,7 @@ static int send_ref(const struct reference *ref, void *cb_data)
if (data->peel && ref->oid) {
struct object_id peeled;
- if (!peel_iterated_oid(the_repository, ref->oid, &peeled))
+ if (!reference_get_peeled_oid(the_repository, ref, &peeled))
strbuf_addf(&data->buf, " peeled:%s", oid_to_hex(&peeled));
}
diff --git a/midx-write.c b/midx-write.c
index f4dd875747..23e61cb000 100644
--- a/midx-write.c
+++ b/midx-write.c
@@ -709,7 +709,7 @@ static int add_ref_to_pending(const struct reference *ref, void *cb_data)
return 0;
}
- if (!peel_iterated_oid(revs->repo, ref->oid, &peeled))
+ if (!reference_get_peeled_oid(revs->repo, ref, &peeled))
maybe_peeled = &peeled;
object = parse_object_or_die(revs->repo, maybe_peeled, ref->name);
diff --git a/pseudo-merge.c b/pseudo-merge.c
index 0abd51b42c..a2d5bd85f9 100644
--- a/pseudo-merge.c
+++ b/pseudo-merge.c
@@ -230,7 +230,7 @@ static int find_pseudo_merge_group_for_ref(const struct reference *ref, void *_d
uint32_t i;
int has_bitmap;
- if (!peel_iterated_oid(the_repository, ref->oid, &peeled))
+ if (!reference_get_peeled_oid(the_repository, ref, &peeled))
maybe_peeled = &peeled;
c = lookup_commit(the_repository, maybe_peeled);
diff --git a/refs.c b/refs.c
index f96cf43b12..1b1551f981 100644
--- a/refs.c
+++ b/refs.c
@@ -2334,6 +2334,18 @@ int peel_iterated_oid(struct repository *r, const struct object_id *base, struct
return peel_object(r, base, peeled) ? -1 : 0;
}
+int reference_get_peeled_oid(struct repository *repo,
+ const struct reference *ref,
+ struct object_id *peeled_oid)
+{
+ if (ref->peeled_oid) {
+ oidcpy(peeled_oid, ref->peeled_oid);
+ return 0;
+ }
+
+ return peel_object(repo, ref->oid, peeled_oid) ? -1 : 0;
+}
+
int refs_update_symref(struct ref_store *refs, const char *ref,
const char *target, const char *logmsg)
{
diff --git a/refs.h b/refs.h
index 4f0a685714..886ed2c0f4 100644
--- a/refs.h
+++ b/refs.h
@@ -371,11 +371,30 @@ struct reference {
*/
const struct object_id *oid;
+ /*
+ * An optional peeled object ID. This field _may_ be set for tags in
+ * case the peeled value is present in the backend. Please refer to
+ * `reference_get_peeled_oid()`.
+ */
+ const struct object_id *peeled_oid;
+
/* A bitfield of `enum reference_status` flags. */
unsigned flags;
};
/*
+ * Peel the tag to a non-tag commit. If present, this uses the peeled object ID
+ * exposed by the reference backend. Otherwise, the object is peeled via the
+ * object database, which is less efficient.
+ *
+ * Return `0` if the reference could be peeled, a negative error code
+ * otherwise.
+ */
+int reference_get_peeled_oid(struct repository *repo,
+ const struct reference *ref,
+ struct object_id *peeled_oid);
+
+/*
* The signature for the callback function for the for_each_*()
* functions below. The memory pointed to by the `struct reference`
* argument is only guaranteed to be valid for the duration of a
diff --git a/refs/packed-backend.c b/refs/packed-backend.c
index 711e07f832..1fefefd54e 100644
--- a/refs/packed-backend.c
+++ b/refs/packed-backend.c
@@ -963,6 +963,7 @@ static int next_record(struct packed_ref_iterator *iter)
iter->base.ref.flags &= ~REF_KNOWS_PEELED;
} else {
iter->base.ref.flags |= REF_KNOWS_PEELED;
+ iter->base.ref.peeled_oid = &iter->peeled;
}
} else {
oidclr(&iter->peeled, iter->repo->hash_algo);
diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c
index 728886eafd..e214e120d7 100644
--- a/refs/reftable-backend.c
+++ b/refs/reftable-backend.c
@@ -547,6 +547,7 @@ struct reftable_ref_iterator {
struct reftable_iterator iter;
struct reftable_ref_record ref;
struct object_id oid;
+ struct object_id peeled_oid;
char *prefix;
size_t prefix_len;
@@ -671,6 +672,8 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)
case REFTABLE_REF_VAL2:
oidread(&iter->oid, iter->ref.value.val2.value,
refs->base.repo->hash_algo);
+ oidread(&iter->peeled_oid, iter->ref.value.val2.target_value,
+ refs->base.repo->hash_algo);
break;
case REFTABLE_REF_SYMREF:
referent = refs_resolve_ref_unsafe(&iter->refs->base,
@@ -708,6 +711,8 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)
iter->base.ref.name = iter->ref.refname;
iter->base.ref.target = referent;
iter->base.ref.oid = &iter->oid;
+ if (iter->ref.value_type == REFTABLE_REF_VAL2)
+ iter->base.ref.peeled_oid = &iter->peeled_oid;
iter->base.ref.flags = flags;
break;
diff --git a/repack-midx.c b/repack-midx.c
index 349f7e20b5..74bdfa3a6e 100644
--- a/repack-midx.c
+++ b/repack-midx.c
@@ -22,7 +22,7 @@ static int midx_snapshot_ref_one(const struct reference *ref, void *_data)
const struct object_id *maybe_peeled = ref->oid;
struct object_id peeled;
- if (!peel_iterated_oid(data->repo, ref->oid, &peeled))
+ if (!reference_get_peeled_oid(data->repo, ref, &peeled))
maybe_peeled = &peeled;
if (oidset_insert(&data->seen, maybe_peeled))