Skip to content

Commit 0dd7657

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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d1bef4a commit 0dd7657

File tree

12 files changed

+48
-10
lines changed

12 files changed

+48
-10
lines changed

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
@@ -1107,7 +1107,7 @@ static int dfs_on_ref(const struct reference *ref, void *cb_data)
11071107
struct commit_list *stack = NULL;
11081108
struct commit *commit;
11091109

1110-
if (!peel_iterated_oid(the_repository, ref->oid, &peeled))
1110+
if (!reference_get_peeled_oid(the_repository, ref, &peeled))
11111111
maybe_peeled = &peeled;
11121112
if (odb_read_object_info(the_repository->objects, maybe_peeled, NULL) != OBJ_COMMIT)
11131113
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
}
@@ -4532,7 +4533,7 @@ static int mark_bitmap_preferred_tip(const struct reference *ref, void *data UNU
45324533
struct object_id peeled;
45334534
struct object *object;
45344535

4535-
if (!peel_iterated_oid(the_repository, ref->oid, &peeled))
4536+
if (!reference_get_peeled_oid(the_repository, ref, &peeled))
45364537
maybe_peeled = &peeled;
45374538

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

builtin/repack.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,7 @@ static int midx_snapshot_ref_one(const struct reference *ref, void *_data)
779779
const struct object_id *maybe_peeled = ref->oid;
780780
struct object_id peeled;
781781

782-
if (!peel_iterated_oid(the_repository, ref->oid, &peeled))
782+
if (!reference_get_peeled_oid(the_repository, ref, &peeled))
783783
maybe_peeled = &peeled;
784784

785785
if (oidset_insert(&data->seen, maybe_peeled))

commit-graph.c

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

1855-
if (!peel_iterated_oid(data->repo, ref->oid, &peeled))
1855+
if (!reference_get_peeled_oid(data->repo, ref, &peeled))
18561856
maybe_peeled = &peeled;
18571857
if (odb_read_object_info(data->repo->objects, maybe_peeled, NULL) == OBJ_COMMIT)
18581858
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
@@ -2333,6 +2333,18 @@ int peel_iterated_oid(struct repository *r, const struct object_id *base, struct
23332333
return peel_object(r, base, peeled) ? -1 : 0;
23342334
}
23352335

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

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`

0 commit comments

Comments
 (0)