aboutsummaryrefslogtreecommitdiffstats
path: root/refs/packed-backend.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2025-11-03 07:27:58 -0800
committerJunio C Hamano <gitster@pobox.com>2025-11-03 07:27:58 -0800
commit8ac48a10de61267858d66383c34833e55a5e9d02 (patch)
treec944ea41f08960307abbd4c2c4e558e898e20c4c /refs/packed-backend.c
parentMerge branch 'tc/last-modified-active-paths-optimization' into next (diff)
parentref-filter: parse objects on demand (diff)
downloadgit-8ac48a10de61267858d66383c34833e55a5e9d02.tar.gz
git-8ac48a10de61267858d66383c34833e55a5e9d02.zip
Merge branch 'ps/ref-peeled-tags' into next
Some ref backend storage can hold not just the object name of an annotated tag, but the object name of the object the tag points at. The code to handle this information has been streamlined. * ps/ref-peeled-tags: ref-filter: parse objects on demand ref-filter: detect broken tags when dereferencing them refs: don't store peeled object IDs for invalid tags object: add flag to `peel_object()` to verify object type refs: drop infrastructure to peel via iterators refs: drop `current_ref_iter` hack builtin/show-ref: convert to use `reference_get_peeled_oid()` ref-filter: propagate peeled object ID upload-pack: convert to use `reference_get_peeled_oid()` refs: expose peeled object ID via the iterator refs: refactor reference status flags refs: fully reset `struct ref_iterator::ref` on iteration refs: introduce `.ref` field for the base iterator refs: introduce wrapper struct for `each_ref_fn`
Diffstat (limited to 'refs/packed-backend.c')
-rw-r--r--refs/packed-backend.c71
1 files changed, 25 insertions, 46 deletions
diff --git a/refs/packed-backend.c b/refs/packed-backend.c
index a8c22a0a7f..1ab0c50393 100644
--- a/refs/packed-backend.c
+++ b/refs/packed-backend.c
@@ -882,6 +882,7 @@ static int next_record(struct packed_ref_iterator *iter)
{
const char *p, *eol;
+ memset(&iter->base.ref, 0, sizeof(iter->base.ref));
strbuf_reset(&iter->refname_buf);
/*
@@ -908,7 +909,7 @@ static int next_record(struct packed_ref_iterator *iter)
if (iter->pos == iter->eof)
return ITER_DONE;
- iter->base.flags = REF_ISPACKED;
+ iter->base.ref.flags = REF_ISPACKED;
p = iter->pos;
if (iter->eof - p < snapshot_hexsz(iter->snapshot) + 2 ||
@@ -916,6 +917,7 @@ static int next_record(struct packed_ref_iterator *iter)
!isspace(*p++))
die_invalid_line(iter->snapshot->refs->path,
iter->pos, iter->eof - iter->pos);
+ iter->base.ref.oid = &iter->oid;
eol = memchr(p, '\n', iter->eof - p);
if (!eol)
@@ -923,22 +925,22 @@ static int next_record(struct packed_ref_iterator *iter)
iter->pos, iter->eof - iter->pos);
strbuf_add(&iter->refname_buf, p, eol - p);
- iter->base.refname = iter->refname_buf.buf;
+ iter->base.ref.name = iter->refname_buf.buf;
if (refname_contains_nul(&iter->refname_buf))
- die("packed refname contains embedded NULL: %s", iter->base.refname);
+ die("packed refname contains embedded NULL: %s", iter->base.ref.name);
- if (check_refname_format(iter->base.refname, REFNAME_ALLOW_ONELEVEL)) {
- if (!refname_is_safe(iter->base.refname))
+ if (check_refname_format(iter->base.ref.name, REFNAME_ALLOW_ONELEVEL)) {
+ if (!refname_is_safe(iter->base.ref.name))
die("packed refname is dangerous: %s",
- iter->base.refname);
+ iter->base.ref.name);
oidclr(&iter->oid, iter->repo->hash_algo);
- iter->base.flags |= REF_BAD_NAME | REF_ISBROKEN;
+ iter->base.ref.flags |= REF_BAD_NAME | REF_ISBROKEN;
}
if (iter->snapshot->peeled == PEELED_FULLY ||
(iter->snapshot->peeled == PEELED_TAGS &&
- starts_with(iter->base.refname, "refs/tags/")))
- iter->base.flags |= REF_KNOWS_PEELED;
+ starts_with(iter->base.ref.name, "refs/tags/")))
+ iter->base.ref.flags |= REF_KNOWS_PEELED;
iter->pos = eol + 1;
@@ -956,11 +958,12 @@ static int next_record(struct packed_ref_iterator *iter)
* definitely know the value of *this* reference. But
* we suppress it if the reference is broken:
*/
- if ((iter->base.flags & REF_ISBROKEN)) {
+ if ((iter->base.ref.flags & REF_ISBROKEN)) {
oidclr(&iter->peeled, iter->repo->hash_algo);
- iter->base.flags &= ~REF_KNOWS_PEELED;
+ iter->base.ref.flags &= ~REF_KNOWS_PEELED;
} else {
- iter->base.flags |= REF_KNOWS_PEELED;
+ iter->base.ref.flags |= REF_KNOWS_PEELED;
+ iter->base.ref.peeled_oid = &iter->peeled;
}
} else {
oidclr(&iter->peeled, iter->repo->hash_algo);
@@ -976,15 +979,15 @@ static int packed_ref_iterator_advance(struct ref_iterator *ref_iterator)
int ok;
while ((ok = next_record(iter)) == ITER_OK) {
- const char *refname = iter->base.refname;
+ const char *refname = iter->base.ref.name;
const char *prefix = iter->prefix;
if (iter->flags & DO_FOR_EACH_PER_WORKTREE_ONLY &&
- !is_per_worktree_ref(iter->base.refname))
+ !is_per_worktree_ref(iter->base.ref.name))
continue;
if (!(iter->flags & DO_FOR_EACH_INCLUDE_BROKEN) &&
- !ref_resolves_to_object(iter->base.refname, iter->repo,
+ !ref_resolves_to_object(iter->base.ref.name, iter->repo,
&iter->oid, iter->flags))
continue;
@@ -1027,22 +1030,6 @@ static int packed_ref_iterator_seek(struct ref_iterator *ref_iterator,
return 0;
}
-static int packed_ref_iterator_peel(struct ref_iterator *ref_iterator,
- struct object_id *peeled)
-{
- struct packed_ref_iterator *iter =
- (struct packed_ref_iterator *)ref_iterator;
-
- if ((iter->base.flags & REF_KNOWS_PEELED)) {
- oidcpy(peeled, &iter->peeled);
- return is_null_oid(&iter->peeled) ? -1 : 0;
- } else if ((iter->base.flags & (REF_ISBROKEN | REF_ISSYMREF))) {
- return -1;
- } else {
- return peel_object(iter->repo, &iter->oid, peeled) ? -1 : 0;
- }
-}
-
static void packed_ref_iterator_release(struct ref_iterator *ref_iterator)
{
struct packed_ref_iterator *iter =
@@ -1056,7 +1043,6 @@ static void packed_ref_iterator_release(struct ref_iterator *ref_iterator)
static struct ref_iterator_vtable packed_ref_iterator_vtable = {
.advance = packed_ref_iterator_advance,
.seek = packed_ref_iterator_seek,
- .peel = packed_ref_iterator_peel,
.release = packed_ref_iterator_release,
};
@@ -1194,7 +1180,6 @@ static struct ref_iterator *packed_ref_iterator_begin(
iter->snapshot = snapshot;
acquire_snapshot(snapshot);
strbuf_init(&iter->refname_buf, 0);
- iter->base.oid = &iter->oid;
iter->repo = ref_store->repo;
iter->flags = flags;
@@ -1436,7 +1421,7 @@ static enum ref_transaction_error write_with_updates(struct packed_ref_store *re
if (!iter)
cmp = +1;
else
- cmp = strcmp(iter->refname, update->refname);
+ cmp = strcmp(iter->ref.name, update->refname);
}
if (!cmp) {
@@ -1459,11 +1444,11 @@ static enum ref_transaction_error write_with_updates(struct packed_ref_store *re
}
goto error;
- } else if (!oideq(&update->old_oid, iter->oid)) {
+ } else if (!oideq(&update->old_oid, iter->ref.oid)) {
strbuf_addf(err, "cannot update ref '%s': "
"is at %s but expected %s",
update->refname,
- oid_to_hex(iter->oid),
+ oid_to_hex(iter->ref.oid),
oid_to_hex(&update->old_oid));
ret = REF_TRANSACTION_ERROR_INCORRECT_OLD_VALUE;
@@ -1523,13 +1508,8 @@ static enum ref_transaction_error write_with_updates(struct packed_ref_store *re
if (cmp < 0) {
/* Pass the old reference through. */
-
- struct object_id peeled;
- int peel_error = ref_iterator_peel(iter, &peeled);
-
- if (write_packed_entry(out, iter->refname,
- iter->oid,
- peel_error ? NULL : &peeled))
+ if (write_packed_entry(out, iter->ref.name,
+ iter->ref.oid, iter->ref.peeled_oid))
goto write_error;
if ((ok = ref_iterator_advance(iter)) != ITER_OK) {
@@ -1547,9 +1527,8 @@ static enum ref_transaction_error write_with_updates(struct packed_ref_store *re
i++;
} else {
struct object_id peeled;
- int peel_error = peel_object(refs->base.repo,
- &update->new_oid,
- &peeled);
+ int peel_error = peel_object(refs->base.repo, &update->new_oid,
+ &peeled, PEEL_OBJECT_VERIFY_OBJECT_TYPE);
if (write_packed_entry(out, update->refname,
&update->new_oid,