From 30aaff437fddd889ba429b50b96ea4c151c502c5 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 17 May 2024 10:19:04 +0200 Subject: [PATCH] refs: pass repo when peeling objects Both `peel_object()` and `peel_iterated_oid()` implicitly rely on `the_repository` to look up objects. Despite the fact that we want to get rid of `the_repository`, it also leads to some restrictions in our ref iterators when trying to retrieve the peeled value for a repository other than `the_repository`. Refactor these functions such that both take a repository as argument and remove the now-unnecessary restrictions. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/describe.c | 2 +- builtin/gc.c | 2 +- builtin/pack-objects.c | 6 +++--- builtin/repack.c | 2 +- builtin/show-ref.c | 2 +- commit-graph.c | 2 +- ls-refs.c | 2 +- midx-write.c | 2 +- object.c | 10 ++++++---- object.h | 3 ++- ref-filter.c | 2 +- refs.c | 4 ++-- refs.h | 5 +++-- refs/packed-backend.c | 8 +++----- refs/ref-cache.c | 5 +---- refs/reftable-backend.c | 6 ++++-- t/helper/test-reach.c | 2 +- tag.c | 4 ++-- tag.h | 2 +- upload-pack.c | 2 +- 20 files changed, 37 insertions(+), 36 deletions(-) diff --git a/builtin/describe.c b/builtin/describe.c index 82aca00c80..e5287eddf2 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -200,7 +200,7 @@ static int get_name(const char *path, const struct object_id *oid, } /* Is it annotated? */ - if (!peel_iterated_oid(oid, &peeled)) { + if (!peel_iterated_oid(the_repository, oid, &peeled)) { is_annotated = !oideq(oid, &peeled); } else { oidcpy(&peeled, oid); diff --git a/builtin/gc.c b/builtin/gc.c index 054fca7835..72bac2554f 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -846,7 +846,7 @@ static int dfs_on_ref(const char *refname UNUSED, struct commit_list *stack = NULL; struct commit *commit; - if (!peel_iterated_oid(oid, &peeled)) + if (!peel_iterated_oid(the_repository, oid, &peeled)) oid = &peeled; if (oid_object_info(the_repository, oid, NULL) != OBJ_COMMIT) return 0; diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index cd2396896d..62ddf41f84 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -779,7 +779,7 @@ static int mark_tagged(const char *path UNUSED, const struct object_id *oid, if (entry) entry->tagged = 1; - if (!peel_iterated_oid(oid, &peeled)) { + if (!peel_iterated_oid(the_repository, oid, &peeled)) { entry = packlist_find(&to_pack, &peeled); if (entry) entry->tagged = 1; @@ -3125,7 +3125,7 @@ static int add_ref_tag(const char *tag UNUSED, const struct object_id *oid, { struct object_id peeled; - if (!peel_iterated_oid(oid, &peeled) && obj_is_packed(&peeled)) + if (!peel_iterated_oid(the_repository, oid, &peeled) && obj_is_packed(&peeled)) add_tag_chain(oid); return 0; } @@ -4074,7 +4074,7 @@ static int mark_bitmap_preferred_tip(const char *refname, struct object_id peeled; struct object *object; - if (!peel_iterated_oid(oid, &peeled)) + if (!peel_iterated_oid(the_repository, oid, &peeled)) oid = &peeled; object = parse_object_or_die(oid, refname); diff --git a/builtin/repack.c b/builtin/repack.c index 43491a4cbf..58ad82dd97 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -673,7 +673,7 @@ static int midx_snapshot_ref_one(const char *refname UNUSED, struct midx_snapshot_ref_data *data = _data; struct object_id peeled; - if (!peel_iterated_oid(oid, &peeled)) + if (!peel_iterated_oid(the_repository, oid, &peeled)) oid = &peeled; if (oidset_insert(&data->seen, oid)) diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 151ef35134..3114bdc391 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -50,7 +50,7 @@ static void show_one(const struct show_one_options *opts, if (!opts->deref_tags) return; - if (!peel_iterated_oid(oid, &peeled)) { + if (!peel_iterated_oid(the_repository, oid, &peeled)) { hex = repo_find_unique_abbrev(the_repository, &peeled, opts->abbrev); printf("%s %s^{}\n", hex, refname); } diff --git a/commit-graph.c b/commit-graph.c index c4c156ff52..e5dd3553df 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -1821,7 +1821,7 @@ static int add_ref_to_set(const char *refname UNUSED, struct object_id peeled; struct refs_cb_data *data = (struct refs_cb_data *)cb_data; - if (!peel_iterated_oid(oid, &peeled)) + if (!peel_iterated_oid(the_repository, oid, &peeled)) oid = &peeled; if (oid_object_info(the_repository, oid, NULL) == OBJ_COMMIT) oidset_insert(data->commits, oid); diff --git a/ls-refs.c b/ls-refs.c index 8e3ffff811..398afe4ce3 100644 --- a/ls-refs.c +++ b/ls-refs.c @@ -110,7 +110,7 @@ static int send_ref(const char *refname, const struct object_id *oid, if (data->peel && oid) { struct object_id peeled; - if (!peel_iterated_oid(oid, &peeled)) + if (!peel_iterated_oid(the_repository, oid, &peeled)) strbuf_addf(&data->buf, " peeled:%s", oid_to_hex(&peeled)); } diff --git a/midx-write.c b/midx-write.c index 9d096d5a28..86173abdb9 100644 --- a/midx-write.c +++ b/midx-write.c @@ -664,7 +664,7 @@ static int add_ref_to_pending(const char *refname, return 0; } - if (!peel_iterated_oid(oid, &peeled)) + if (!peel_iterated_oid(the_repository, oid, &peeled)) oid = &peeled; object = parse_object_or_die(oid, refname); diff --git a/object.c b/object.c index 995041926a..93b5d97fdb 100644 --- a/object.c +++ b/object.c @@ -207,12 +207,14 @@ struct object *lookup_object_by_type(struct repository *r, } } -enum peel_status peel_object(const struct object_id *name, struct object_id *oid) +enum peel_status peel_object(struct repository *r, + const struct object_id *name, + struct object_id *oid) { - struct object *o = lookup_unknown_object(the_repository, name); + struct object *o = lookup_unknown_object(r, name); if (o->type == OBJ_NONE) { - int type = oid_object_info(the_repository, name, NULL); + int type = oid_object_info(r, name, NULL); if (type < 0 || !object_as_type(o, type, 0)) return PEEL_INVALID; } @@ -220,7 +222,7 @@ enum peel_status peel_object(const struct object_id *name, struct object_id *oid if (o->type != OBJ_TAG) return PEEL_NON_TAG; - o = deref_tag_noverify(o); + o = deref_tag_noverify(r, o); if (!o) return PEEL_INVALID; diff --git a/object.h b/object.h index 31ccd1bb10..83fcc035e9 100644 --- a/object.h +++ b/object.h @@ -288,7 +288,8 @@ enum peel_status { * or is not valid, return PEEL_NON_TAG or PEEL_INVALID, respectively, * and leave oid unchanged. */ -enum peel_status peel_object(const struct object_id *name, struct object_id *oid); +enum peel_status peel_object(struct repository *r, + const struct object_id *name, struct object_id *oid); struct object_list *object_list_insert(struct object *item, struct object_list **list_p); diff --git a/ref-filter.c b/ref-filter.c index 31cc096644..79e7d3910d 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -2520,7 +2520,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err) * If it is a tag object, see if we use the peeled value. If we do, * grab the peeled OID. */ - if (need_tagged && peel_iterated_oid(&obj->oid, &oi_deref.oid)) + if (need_tagged && peel_iterated_oid(the_repository, &obj->oid, &oi_deref.oid)) die("bad tag"); return get_object(ref, 1, &obj, &oi_deref, err); diff --git a/refs.c b/refs.c index d1b530679f..5f1819b33e 100644 --- a/refs.c +++ b/refs.c @@ -2064,14 +2064,14 @@ int refs_pack_refs(struct ref_store *refs, struct pack_refs_opts *opts) return refs->be->pack_refs(refs, opts); } -int peel_iterated_oid(const struct object_id *base, struct object_id *peeled) +int peel_iterated_oid(struct repository *r, const struct object_id *base, struct object_id *peeled) { if (current_ref_iter && (current_ref_iter->oid == base || oideq(current_ref_iter->oid, base))) return ref_iterator_peel(current_ref_iter, peeled); - return peel_object(base, peeled) ? -1 : 0; + return peel_object(r, base, peeled) ? -1 : 0; } int refs_create_symref(struct ref_store *refs, diff --git a/refs.h b/refs.h index 56d9714293..e043b6cfa3 100644 --- a/refs.h +++ b/refs.h @@ -127,13 +127,14 @@ void ref_store_release(struct ref_store *ref_store); * Return the peeled value of the oid currently being iterated via * for_each_ref(), etc. This is equivalent to calling: * - * peel_object(oid, &peeled); + * peel_object(r, oid, &peeled); * * with the "oid" value given to the each_ref_fn callback, except * that some ref storage may be able to answer the query without * actually loading the object in memory. */ -int peel_iterated_oid(const struct object_id *base, struct object_id *peeled); +int peel_iterated_oid(struct repository *r, + const struct object_id *base, struct object_id *peeled); /** * Resolve refname in the nested "gitlink" repository in the specified diff --git a/refs/packed-backend.c b/refs/packed-backend.c index 9c98e6295f..dfdd718eb9 100644 --- a/refs/packed-backend.c +++ b/refs/packed-backend.c @@ -953,16 +953,13 @@ static int packed_ref_iterator_peel(struct ref_iterator *ref_iterator, struct packed_ref_iterator *iter = (struct packed_ref_iterator *)ref_iterator; - if (iter->repo != the_repository) - BUG("peeling for non-the_repository is not supported"); - 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->oid, peeled) ? -1 : 0; + return peel_object(iter->repo, &iter->oid, peeled) ? -1 : 0; } } @@ -1421,7 +1418,8 @@ static int write_with_updates(struct packed_ref_store *refs, i++; } else { struct object_id peeled; - int peel_error = peel_object(&update->new_oid, + int peel_error = peel_object(refs->base.repo, + &update->new_oid, &peeled); if (write_packed_entry(out, update->refname, diff --git a/refs/ref-cache.c b/refs/ref-cache.c index 9f9797209a..b6c53fc8ed 100644 --- a/refs/ref-cache.c +++ b/refs/ref-cache.c @@ -441,10 +441,7 @@ static int cache_ref_iterator_peel(struct ref_iterator *ref_iterator, { struct cache_ref_iterator *iter = (struct cache_ref_iterator *)ref_iterator; - - if (iter->repo != the_repository) - BUG("peeling for non-the_repository is not supported"); - return peel_object(ref_iterator->oid, peeled) ? -1 : 0; + return peel_object(iter->repo, ref_iterator->oid, peeled) ? -1 : 0; } static int cache_ref_iterator_abort(struct ref_iterator *ref_iterator) diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index 7b73f73f59..850466da4b 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -1144,7 +1144,7 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data ref.refname = (char *)u->refname; ref.update_index = ts; - peel_error = peel_object(&u->new_oid, &peeled); + peel_error = peel_object(arg->refs->base.repo, &u->new_oid, &peeled); if (!peel_error) { ref.value_type = REFTABLE_REF_VAL2; memcpy(ref.value.val2.target_value, peeled.hash, GIT_MAX_RAWSZ); @@ -2045,6 +2045,7 @@ static int reftable_be_delete_reflog(struct ref_store *ref_store, } struct reflog_expiry_arg { + struct reftable_ref_store *refs; struct reftable_stack *stack; struct reftable_log_record *records; struct object_id update_oid; @@ -2073,7 +2074,7 @@ static int write_reflog_expiry_table(struct reftable_writer *writer, void *cb_da ref.refname = (char *)arg->refname; ref.update_index = ts; - if (!peel_object(&arg->update_oid, &peeled)) { + if (!peel_object(arg->refs->base.repo, &arg->update_oid, &peeled)) { ref.value_type = REFTABLE_REF_VAL2; memcpy(ref.value.val2.target_value, peeled.hash, GIT_MAX_RAWSZ); memcpy(ref.value.val2.value, arg->update_oid.hash, GIT_MAX_RAWSZ); @@ -2235,6 +2236,7 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, reftable_ref_record_val1(&ref_record)) oidread(&arg.update_oid, last_hash); + arg.refs = refs; arg.records = rewritten; arg.len = logs_nr; arg.stack = stack, diff --git a/t/helper/test-reach.c b/t/helper/test-reach.c index 1e3b431e3e..1ba226f1f9 100644 --- a/t/helper/test-reach.c +++ b/t/helper/test-reach.c @@ -62,7 +62,7 @@ int cmd__reach(int ac, const char **av) die("failed to resolve %s", buf.buf + 2); orig = parse_object(r, &oid); - peeled = deref_tag_noverify(orig); + peeled = deref_tag_noverify(the_repository, orig); if (!peeled) die("failed to load commit for input %s resulting in oid %s\n", diff --git a/tag.c b/tag.c index fc3834db46..52bbe50819 100644 --- a/tag.c +++ b/tag.c @@ -91,10 +91,10 @@ struct object *deref_tag(struct repository *r, struct object *o, const char *war return o; } -struct object *deref_tag_noverify(struct object *o) +struct object *deref_tag_noverify(struct repository *r, struct object *o) { while (o && o->type == OBJ_TAG) { - o = parse_object(the_repository, &o->oid); + o = parse_object(r, &o->oid); if (o && o->type == OBJ_TAG && ((struct tag *)o)->tagged) o = ((struct tag *)o)->tagged; else diff --git a/tag.h b/tag.h index 3ce8e72192..c49d7c19ad 100644 --- a/tag.h +++ b/tag.h @@ -16,7 +16,7 @@ int parse_tag_buffer(struct repository *r, struct tag *item, const void *data, u int parse_tag(struct tag *item); void release_tag_memory(struct tag *t); struct object *deref_tag(struct repository *r, struct object *, const char *, int); -struct object *deref_tag_noverify(struct object *); +struct object *deref_tag_noverify(struct repository *r, struct object *); int gpg_verify_tag(const struct object_id *oid, const char *name_to_report, unsigned flags); struct object_id *get_tagged_oid(struct tag *tag); diff --git a/upload-pack.c b/upload-pack.c index 8fbd138515..bbfb04c8bd 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -1269,7 +1269,7 @@ static void write_v0_ref(struct upload_pack_data *data, packet_fwrite_fmt(stdout, "%s %s\n", oid_to_hex(oid), refname_nons); } capabilities = NULL; - if (!peel_iterated_oid(oid, &peeled)) + if (!peel_iterated_oid(the_repository, oid, &peeled)) packet_fwrite_fmt(stdout, "%s %s^{}\n", oid_to_hex(&peeled), refname_nons); return; }