upload-pack: convert to use `reference_get_peeled_oid()`

The `write_v0_ref()` callback is invoked from two callsites: - Once via `send_ref()` which is a callback passed to `for_each_namespaced_ref_1()` and `refs_head_ref_namespaced()`. - Once manually to announce capabilities. When sending references to the client we also send the peeled value of tags. As we don't have a `struct reference` available in the second case, we cannot easily peel by calling `reference_get_peeled_oid()`, but we instead have to depend on on global state via `peel_iterated_oid()`. We do have a reference available though in the first case, it's only the second case that keeps us from using `reference_get_peeled_oid()`. But that second case only announces capabilities anyway, so we're not really handling a reference at all here. Adapt that case to construct a reference manually and pass that to `write_v0_ref()`. Start to use `reference_get_peeled_oid()` now that we always have a `struct reference` available. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Oct 23, 2025 at 09:16 UTC adecd5f0b6fdd40219d5503fdaf46aa8d36a4ff7
1 file changed +13 -9
upload-pack.c
+13 -9
@@ -1249,15 +1249,15 @@ static void format_session_id(struct strbuf *buf, struct upload_pack_data *d) {
1249 }
1250
1251 static void write_v0_ref(struct upload_pack_data *data,
1252 - const char *refname, const char *refname_nons,
1253 - const struct object_id *oid)
1252 + const struct reference *ref,
1253 + const char *refname_nons)
1254 {
1255 static const char *capabilities = "multi_ack thin-pack side-band"
1256 " side-band-64k ofs-delta shallow deepen-since deepen-not"
1257 " deepen-relative no-progress include-tag multi_ack_detailed";
1258 struct object_id peeled;
1259
1260 - if (mark_our_ref(refname_nons, refname, oid, &data->hidden_refs))
1260 + if (mark_our_ref(refname_nons, ref->name, ref->oid, &data->hidden_refs))
1261 return;
1262
1263 if (capabilities) {
@@ -1267,7 +1267,7 @@ static void write_v0_ref(struct upload_pack_data *data,
1267 format_symref_info(&symref_info, &data->symref);
1268 format_session_id(&session_id, data);
1269 packet_fwrite_fmt(stdout, "%s %s%c%s%s%s%s%s%s%s object-format=%s agent=%s\n",
1270 - oid_to_hex(oid), refname_nons,
1270 + oid_to_hex(ref->oid), refname_nons,
1271 0, capabilities,
1272 (data->allow_uor & ALLOW_TIP_SHA1) ?
1273 " allow-tip-sha1-in-want" : "",
@@ -1283,17 +1283,17 @@ static void write_v0_ref(struct upload_pack_data *data,
1283 strbuf_release(&session_id);
1284 data->sent_capabilities = 1;
1285 } else {
1286 - packet_fwrite_fmt(stdout, "%s %s\n", oid_to_hex(oid), refname_nons);
1286 + packet_fwrite_fmt(stdout, "%s %s\n", oid_to_hex(ref->oid), refname_nons);
1287 }
1288 capabilities = NULL;
1289 - if (!peel_iterated_oid(the_repository, oid, &peeled))
1289 + if (!reference_get_peeled_oid(the_repository, ref, &peeled))
1290 packet_fwrite_fmt(stdout, "%s %s^{}\n", oid_to_hex(&peeled), refname_nons);
1291 return;
1292 }
1293
1294 static int send_ref(const struct reference *ref, void *cb_data)
1295 {
1296 - write_v0_ref(cb_data, ref->name, strip_namespace(ref->name), ref->oid);
1296 + write_v0_ref(cb_data, ref, strip_namespace(ref->name));
1297 return 0;
1298 }
1299
@@ -1442,8 +1442,12 @@ void upload_pack(const int advertise_refs, const int stateless_rpc,
1442 send_ref, &data);
1443 for_each_namespaced_ref_1(send_ref, &data);
1444 if (!data.sent_capabilities) {
1445 - const char *refname = "capabilities^{}";
1446 - write_v0_ref(&data, refname, refname, null_oid(the_hash_algo));
1445 + struct reference ref = {
1446 + .name = "capabilities^{}",
1447 + .oid = null_oid(the_hash_algo),
1448 + };
1449 +
1450 + write_v0_ref(&data, &ref, ref.name);
1451 }
1452 /*
1453 * fflush stdout before calling advertise_shallow_grafts because send_ref