Skip to content

Commit f898661

Browse files
pks-tgitster
authored andcommitted
refs: expose peeled object ID via the iterator
Both the "files" and "reftable" backend are able to store peeled values for tags in the respective formats. This allows for a more efficient lookup of the target object of such a tag without having to manually peel via the object database. The infrastructure to access these peeled object IDs is somewhat funky though. When iterating through objects, we store a pointer reference to the current iterator in a global variable. The callbacks invoked by that iterator are then expected to call `peel_iterated_oid()`, which checks whether the globally-stored iterator's current reference refers to the one handed into that function. If so, we ask the iterator to peel the object, otherwise we manually peel the object via the object database. Depending on global state like this is somewhat weird and also quite fragile. Introduce a new `struct reference::peeled_oid` field that can be populated by the reference backends. This field can be accessed via a new function `reference_get_peeled_oid()` that either uses that value, if set, or alternatively peels via the ODB. With this change we don't have to rely on global state anymore, but make the peeled object ID available to the callback functions directly. Adjust trivial callers that already have a `struct reference` available. Remaining callers will be adjusted in subsequent commits. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent eb2934d commit f898661

12 files changed

Lines changed: 48 additions & 10 deletions

File tree

builtin/describe.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ static int get_name(const struct reference *ref, void *cb_data UNUSED)
208208
}
209209

210210
/* Is it annotated? */
211-
if (!peel_iterated_oid(the_repository, ref->oid, &peeled)) {
211+
if (!reference_get_peeled_oid(the_repository, ref, &peeled)) {
212212
is_annotated = !oideq(ref->oid, &peeled);
213213
} else {
214214
oidcpy(&peeled, ref->oid);

builtin/gc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1109,7 +1109,7 @@ static int dfs_on_ref(const struct reference *ref, void *cb_data)
11091109
struct commit_list *stack = NULL;
11101110
struct commit *commit;
11111111

1112-
if (!peel_iterated_oid(the_repository, ref->oid, &peeled))
1112+
if (!reference_get_peeled_oid(the_repository, ref, &peeled))
11131113
maybe_peeled = &peeled;
11141114
if (odb_read_object_info(the_repository->objects, maybe_peeled, NULL) != OBJ_COMMIT)
11151115
return 0;

builtin/pack-objects.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ static int mark_tagged(const struct reference *ref, void *cb_data UNUSED)
838838

839839
if (entry)
840840
entry->tagged = 1;
841-
if (!peel_iterated_oid(the_repository, ref->oid, &peeled)) {
841+
if (!reference_get_peeled_oid(the_repository, ref, &peeled)) {
842842
entry = packlist_find(&to_pack, &peeled);
843843
if (entry)
844844
entry->tagged = 1;
@@ -3309,7 +3309,8 @@ static int add_ref_tag(const struct reference *ref, void *cb_data UNUSED)
33093309
{
33103310
struct object_id peeled;
33113311

3312-
if (!peel_iterated_oid(the_repository, ref->oid, &peeled) && obj_is_packed(&peeled))
3312+
if (!reference_get_peeled_oid(the_repository, ref, &peeled) &&
3313+
obj_is_packed(&peeled))
33133314
add_tag_chain(ref->oid);
33143315
return 0;
33153316
}
@@ -4537,7 +4538,7 @@ static int mark_bitmap_preferred_tip(const struct reference *ref, void *data UNU
45374538
struct object_id peeled;
45384539
struct object *object;
45394540

4540-
if (!peel_iterated_oid(the_repository, ref->oid, &peeled))
4541+
if (!reference_get_peeled_oid(the_repository, ref, &peeled))
45414542
maybe_peeled = &peeled;
45424543

45434544
object = parse_object_or_die(the_repository, maybe_peeled, ref->name);

commit-graph.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1857,7 +1857,7 @@ static int add_ref_to_set(const struct reference *ref, void *cb_data)
18571857
struct object_id peeled;
18581858
struct refs_cb_data *data = (struct refs_cb_data *)cb_data;
18591859

1860-
if (!peel_iterated_oid(data->repo, ref->oid, &peeled))
1860+
if (!reference_get_peeled_oid(data->repo, ref, &peeled))
18611861
maybe_peeled = &peeled;
18621862
if (odb_read_object_info(data->repo->objects, maybe_peeled, NULL) == OBJ_COMMIT)
18631863
oidset_insert(data->commits, maybe_peeled);

ls-refs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ static int send_ref(const struct reference *ref, void *cb_data)
110110

111111
if (data->peel && ref->oid) {
112112
struct object_id peeled;
113-
if (!peel_iterated_oid(the_repository, ref->oid, &peeled))
113+
if (!reference_get_peeled_oid(the_repository, ref, &peeled))
114114
strbuf_addf(&data->buf, " peeled:%s", oid_to_hex(&peeled));
115115
}
116116

midx-write.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ static int add_ref_to_pending(const struct reference *ref, void *cb_data)
709709
return 0;
710710
}
711711

712-
if (!peel_iterated_oid(revs->repo, ref->oid, &peeled))
712+
if (!reference_get_peeled_oid(revs->repo, ref, &peeled))
713713
maybe_peeled = &peeled;
714714

715715
object = parse_object_or_die(revs->repo, maybe_peeled, ref->name);

pseudo-merge.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ static int find_pseudo_merge_group_for_ref(const struct reference *ref, void *_d
230230
uint32_t i;
231231
int has_bitmap;
232232

233-
if (!peel_iterated_oid(the_repository, ref->oid, &peeled))
233+
if (!reference_get_peeled_oid(the_repository, ref, &peeled))
234234
maybe_peeled = &peeled;
235235

236236
c = lookup_commit(the_repository, maybe_peeled);

refs.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2334,6 +2334,18 @@ int peel_iterated_oid(struct repository *r, const struct object_id *base, struct
23342334
return peel_object(r, base, peeled) ? -1 : 0;
23352335
}
23362336

2337+
int reference_get_peeled_oid(struct repository *repo,
2338+
const struct reference *ref,
2339+
struct object_id *peeled_oid)
2340+
{
2341+
if (ref->peeled_oid) {
2342+
oidcpy(peeled_oid, ref->peeled_oid);
2343+
return 0;
2344+
}
2345+
2346+
return peel_object(repo, ref->oid, peeled_oid) ? -1 : 0;
2347+
}
2348+
23372349
int refs_update_symref(struct ref_store *refs, const char *ref,
23382350
const char *target, const char *logmsg)
23392351
{

refs.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,10 +371,29 @@ struct reference {
371371
*/
372372
const struct object_id *oid;
373373

374+
/*
375+
* An optional peeled object ID. This field _may_ be set for tags in
376+
* case the peeled value is present in the backend. Please refer to
377+
* `reference_get_peeled_oid()`.
378+
*/
379+
const struct object_id *peeled_oid;
380+
374381
/* A bitfield of `enum reference_status` flags. */
375382
unsigned flags;
376383
};
377384

385+
/*
386+
* Peel the tag to a non-tag commit. If present, this uses the peeled object ID
387+
* exposed by the reference backend. Otherwise, the object is peeled via the
388+
* object database, which is less efficient.
389+
*
390+
* Return `0` if the reference could be peeled, a negative error code
391+
* otherwise.
392+
*/
393+
int reference_get_peeled_oid(struct repository *repo,
394+
const struct reference *ref,
395+
struct object_id *peeled_oid);
396+
378397
/*
379398
* The signature for the callback function for the for_each_*()
380399
* functions below. The memory pointed to by the `struct reference`

refs/packed-backend.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,7 @@ static int next_record(struct packed_ref_iterator *iter)
963963
iter->base.ref.flags &= ~REF_KNOWS_PEELED;
964964
} else {
965965
iter->base.ref.flags |= REF_KNOWS_PEELED;
966+
iter->base.ref.peeled_oid = &iter->peeled;
966967
}
967968
} else {
968969
oidclr(&iter->peeled, iter->repo->hash_algo);

0 commit comments

Comments
 (0)