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 <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed May 17, 2024 at 10:19 UTC 30aaff437fddd889ba429b50b96ea4c151c502c5
20 files changed +37 -36
builtin/describe.c
+1 -1
@@ -200,7 +200,7 @@ static int get_name(const char *path, const struct object_id *oid,
200 }
201
202 /* Is it annotated? */
203 - if (!peel_iterated_oid(oid, &peeled)) {
203 + if (!peel_iterated_oid(the_repository, oid, &peeled)) {
204 is_annotated = !oideq(oid, &peeled);
205 } else {
206 oidcpy(&peeled, oid);
builtin/gc.c
+1 -1
@@ -846,7 +846,7 @@ static int dfs_on_ref(const char *refname UNUSED,
846 struct commit_list *stack = NULL;
847 struct commit *commit;
848
849 - if (!peel_iterated_oid(oid, &peeled))
849 + if (!peel_iterated_oid(the_repository, oid, &peeled))
850 oid = &peeled;
851 if (oid_object_info(the_repository, oid, NULL) != OBJ_COMMIT)
852 return 0;
builtin/pack-objects.c
+3 -3
@@ -779,7 +779,7 @@ static int mark_tagged(const char *path UNUSED, const struct object_id *oid,
779
780 if (entry)
781 entry->tagged = 1;
782 - if (!peel_iterated_oid(oid, &peeled)) {
782 + if (!peel_iterated_oid(the_repository, oid, &peeled)) {
783 entry = packlist_find(&to_pack, &peeled);
784 if (entry)
785 entry->tagged = 1;
@@ -3125,7 +3125,7 @@ static int add_ref_tag(const char *tag UNUSED, const struct object_id *oid,
3125 {
3126 struct object_id peeled;
3127
3128 - if (!peel_iterated_oid(oid, &peeled) && obj_is_packed(&peeled))
3128 + if (!peel_iterated_oid(the_repository, oid, &peeled) && obj_is_packed(&peeled))
3129 add_tag_chain(oid);
3130 return 0;
3131 }
@@ -4074,7 +4074,7 @@ static int mark_bitmap_preferred_tip(const char *refname,
4074 struct object_id peeled;
4075 struct object *object;
4076
4077 - if (!peel_iterated_oid(oid, &peeled))
4077 + if (!peel_iterated_oid(the_repository, oid, &peeled))
4078 oid = &peeled;
4079
4080 object = parse_object_or_die(oid, refname);
builtin/repack.c
+1 -1
@@ -673,7 +673,7 @@ static int midx_snapshot_ref_one(const char *refname UNUSED,
673 struct midx_snapshot_ref_data *data = _data;
674 struct object_id peeled;
675
676 - if (!peel_iterated_oid(oid, &peeled))
676 + if (!peel_iterated_oid(the_repository, oid, &peeled))
677 oid = &peeled;
678
679 if (oidset_insert(&data->seen, oid))
builtin/show-ref.c
+1 -1
@@ -50,7 +50,7 @@ static void show_one(const struct show_one_options *opts,
50 if (!opts->deref_tags)
51 return;
52
53 - if (!peel_iterated_oid(oid, &peeled)) {
53 + if (!peel_iterated_oid(the_repository, oid, &peeled)) {
54 hex = repo_find_unique_abbrev(the_repository, &peeled, opts->abbrev);
55 printf("%s %s^{}\n", hex, refname);
56 }
commit-graph.c
+1 -1
@@ -1821,7 +1821,7 @@ static int add_ref_to_set(const char *refname UNUSED,
1821 struct object_id peeled;
1822 struct refs_cb_data *data = (struct refs_cb_data *)cb_data;
1823
1824 - if (!peel_iterated_oid(oid, &peeled))
1824 + if (!peel_iterated_oid(the_repository, oid, &peeled))
1825 oid = &peeled;
1826 if (oid_object_info(the_repository, oid, NULL) == OBJ_COMMIT)
1827 oidset_insert(data->commits, oid);
ls-refs.c
+1 -1
@@ -110,7 +110,7 @@ static int send_ref(const char *refname, const struct object_id *oid,
110
111 if (data->peel && oid) {
112 struct object_id peeled;
113 - if (!peel_iterated_oid(oid, &peeled))
113 + if (!peel_iterated_oid(the_repository, oid, &peeled))
114 strbuf_addf(&data->buf, " peeled:%s", oid_to_hex(&peeled));
115 }
116
midx-write.c
+1 -1
@@ -664,7 +664,7 @@ static int add_ref_to_pending(const char *refname,
664 return 0;
665 }
666
667 - if (!peel_iterated_oid(oid, &peeled))
667 + if (!peel_iterated_oid(the_repository, oid, &peeled))
668 oid = &peeled;
669
670 object = parse_object_or_die(oid, refname);
object.c
+6 -4
@@ -207,12 +207,14 @@ struct object *lookup_object_by_type(struct repository *r,
207 }
208 }
209
210 -enum peel_status peel_object(const struct object_id *name, struct object_id *oid)
210 +enum peel_status peel_object(struct repository *r,
211 + const struct object_id *name,
212 + struct object_id *oid)
213 {
212 - struct object *o = lookup_unknown_object(the_repository, name);
214 + struct object *o = lookup_unknown_object(r, name);
215
216 if (o->type == OBJ_NONE) {
215 - int type = oid_object_info(the_repository, name, NULL);
217 + int type = oid_object_info(r, name, NULL);
218 if (type < 0 || !object_as_type(o, type, 0))
219 return PEEL_INVALID;
220 }
@@ -220,7 +222,7 @@ enum peel_status peel_object(const struct object_id *name, struct object_id *oid
222 if (o->type != OBJ_TAG)
223 return PEEL_NON_TAG;
224
223 - o = deref_tag_noverify(o);
225 + o = deref_tag_noverify(r, o);
226 if (!o)
227 return PEEL_INVALID;
228
object.h
+2 -1
@@ -288,7 +288,8 @@ enum peel_status {
288 * or is not valid, return PEEL_NON_TAG or PEEL_INVALID, respectively,
289 * and leave oid unchanged.
290 */
291 -enum peel_status peel_object(const struct object_id *name, struct object_id *oid);
291 +enum peel_status peel_object(struct repository *r,
292 + const struct object_id *name, struct object_id *oid);
293
294 struct object_list *object_list_insert(struct object *item,
295 struct object_list **list_p);
ref-filter.c
+1 -1
@@ -2520,7 +2520,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
2520 * If it is a tag object, see if we use the peeled value. If we do,
2521 * grab the peeled OID.
2522 */
2523 - if (need_tagged && peel_iterated_oid(&obj->oid, &oi_deref.oid))
2523 + if (need_tagged && peel_iterated_oid(the_repository, &obj->oid, &oi_deref.oid))
2524 die("bad tag");
2525
2526 return get_object(ref, 1, &obj, &oi_deref, err);
refs.c
+2 -2
@@ -2064,14 +2064,14 @@ int refs_pack_refs(struct ref_store *refs, struct pack_refs_opts *opts)
2064 return refs->be->pack_refs(refs, opts);
2065 }
2066
2067 -int peel_iterated_oid(const struct object_id *base, struct object_id *peeled)
2067 +int peel_iterated_oid(struct repository *r, const struct object_id *base, struct object_id *peeled)
2068 {
2069 if (current_ref_iter &&
2070 (current_ref_iter->oid == base ||
2071 oideq(current_ref_iter->oid, base)))
2072 return ref_iterator_peel(current_ref_iter, peeled);
2073
2074 - return peel_object(base, peeled) ? -1 : 0;
2074 + return peel_object(r, base, peeled) ? -1 : 0;
2075 }
2076
2077 int refs_create_symref(struct ref_store *refs,
refs.h
+3 -2
@@ -127,13 +127,14 @@ void ref_store_release(struct ref_store *ref_store);
127 * Return the peeled value of the oid currently being iterated via
128 * for_each_ref(), etc. This is equivalent to calling:
129 *
130 - * peel_object(oid, &peeled);
130 + * peel_object(r, oid, &peeled);
131 *
132 * with the "oid" value given to the each_ref_fn callback, except
133 * that some ref storage may be able to answer the query without
134 * actually loading the object in memory.
135 */
136 -int peel_iterated_oid(const struct object_id *base, struct object_id *peeled);
136 +int peel_iterated_oid(struct repository *r,
137 + const struct object_id *base, struct object_id *peeled);
138
139 /**
140 * Resolve refname in the nested "gitlink" repository in the specified
refs/packed-backend.c
+3 -5
@@ -953,16 +953,13 @@ static int packed_ref_iterator_peel(struct ref_iterator *ref_iterator,
953 struct packed_ref_iterator *iter =
954 (struct packed_ref_iterator *)ref_iterator;
955
956 - if (iter->repo != the_repository)
957 - BUG("peeling for non-the_repository is not supported");
958 -
956 if ((iter->base.flags & REF_KNOWS_PEELED)) {
957 oidcpy(peeled, &iter->peeled);
958 return is_null_oid(&iter->peeled) ? -1 : 0;
959 } else if ((iter->base.flags & (REF_ISBROKEN | REF_ISSYMREF))) {
960 return -1;
961 } else {
965 - return peel_object(&iter->oid, peeled) ? -1 : 0;
962 + return peel_object(iter->repo, &iter->oid, peeled) ? -1 : 0;
963 }
964 }
965
@@ -1421,7 +1418,8 @@ static int write_with_updates(struct packed_ref_store *refs,
1418 i++;
1419 } else {
1420 struct object_id peeled;
1424 - int peel_error = peel_object(&update->new_oid,
1421 + int peel_error = peel_object(refs->base.repo,
1422 + &update->new_oid,
1423 &peeled);
1424
1425 if (write_packed_entry(out, update->refname,
refs/ref-cache.c
+1 -4
@@ -441,10 +441,7 @@ static int cache_ref_iterator_peel(struct ref_iterator *ref_iterator,
441 {
442 struct cache_ref_iterator *iter =
443 (struct cache_ref_iterator *)ref_iterator;
444 -
445 - if (iter->repo != the_repository)
446 - BUG("peeling for non-the_repository is not supported");
447 - return peel_object(ref_iterator->oid, peeled) ? -1 : 0;
444 + return peel_object(iter->repo, ref_iterator->oid, peeled) ? -1 : 0;
445 }
446
447 static int cache_ref_iterator_abort(struct ref_iterator *ref_iterator)
refs/reftable-backend.c
+4 -2
@@ -1144,7 +1144,7 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data
1144 ref.refname = (char *)u->refname;
1145 ref.update_index = ts;
1146
1147 - peel_error = peel_object(&u->new_oid, &peeled);
1147 + peel_error = peel_object(arg->refs->base.repo, &u->new_oid, &peeled);
1148 if (!peel_error) {
1149 ref.value_type = REFTABLE_REF_VAL2;
1150 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,
2045 }
2046
2047 struct reflog_expiry_arg {
2048 + struct reftable_ref_store *refs;
2049 struct reftable_stack *stack;
2050 struct reftable_log_record *records;
2051 struct object_id update_oid;
@@ -2073,7 +2074,7 @@ static int write_reflog_expiry_table(struct reftable_writer *writer, void *cb_da
2074 ref.refname = (char *)arg->refname;
2075 ref.update_index = ts;
2076
2076 - if (!peel_object(&arg->update_oid, &peeled)) {
2077 + if (!peel_object(arg->refs->base.repo, &arg->update_oid, &peeled)) {
2078 ref.value_type = REFTABLE_REF_VAL2;
2079 memcpy(ref.value.val2.target_value, peeled.hash, GIT_MAX_RAWSZ);
2080 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,
2236 reftable_ref_record_val1(&ref_record))
2237 oidread(&arg.update_oid, last_hash);
2238
2239 + arg.refs = refs;
2240 arg.records = rewritten;
2241 arg.len = logs_nr;
2242 arg.stack = stack,
t/helper/test-reach.c
+1 -1
@@ -62,7 +62,7 @@ int cmd__reach(int ac, const char **av)
62 die("failed to resolve %s", buf.buf + 2);
63
64 orig = parse_object(r, &oid);
65 - peeled = deref_tag_noverify(orig);
65 + peeled = deref_tag_noverify(the_repository, orig);
66
67 if (!peeled)
68 die("failed to load commit for input %s resulting in oid %s\n",
tag.c
+2 -2
@@ -91,10 +91,10 @@ struct object *deref_tag(struct repository *r, struct object *o, const char *war
91 return o;
92 }
93
94 -struct object *deref_tag_noverify(struct object *o)
94 +struct object *deref_tag_noverify(struct repository *r, struct object *o)
95 {
96 while (o && o->type == OBJ_TAG) {
97 - o = parse_object(the_repository, &o->oid);
97 + o = parse_object(r, &o->oid);
98 if (o && o->type == OBJ_TAG && ((struct tag *)o)->tagged)
99 o = ((struct tag *)o)->tagged;
100 else
tag.h
+1 -1
@@ -16,7 +16,7 @@ int parse_tag_buffer(struct repository *r, struct tag *item, const void *data, u
16 int parse_tag(struct tag *item);
17 void release_tag_memory(struct tag *t);
18 struct object *deref_tag(struct repository *r, struct object *, const char *, int);
19 -struct object *deref_tag_noverify(struct object *);
19 +struct object *deref_tag_noverify(struct repository *r, struct object *);
20 int gpg_verify_tag(const struct object_id *oid,
21 const char *name_to_report, unsigned flags);
22 struct object_id *get_tagged_oid(struct tag *tag);
upload-pack.c
+1 -1
@@ -1269,7 +1269,7 @@ static void write_v0_ref(struct upload_pack_data *data,
1269 packet_fwrite_fmt(stdout, "%s %s\n", oid_to_hex(oid), refname_nons);
1270 }
1271 capabilities = NULL;
1272 - if (!peel_iterated_oid(oid, &peeled))
1272 + if (!peel_iterated_oid(the_repository, oid, &peeled))
1273 packet_fwrite_fmt(stdout, "%s %s^{}\n", oid_to_hex(&peeled), refname_nons);
1274 return;
1275 }