packfile: refactor `find_pack_entry()` to work on the packfile store

The function `find_pack_entry()` doesn't work on a specific packfile store, but instead works on the whole repository. This causes a bit of a conceptual mismatch in its callers: - `packfile_store_freshen_object()` supposedly acts on a store, and its callers know to iterate through all sources already. - `packfile_store_read_object_info()` behaves likewise. The only exception that doesn't know to handle iteration through sources is `has_object_pack()`, but that function is trivial to adapt. Refactor the code so that `find_pack_entry()` works on the packfile store level instead. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jan 9, 2026 at 09:33 UTC a593373b097322adc74aa5f9614c7650f87ebed9
1 file changed +23 -20
packfile.c
+23 -20
@@ -2087,29 +2087,23 @@ static int fill_pack_entry(const struct object_id *oid,
2087 return 1;
2088 }
2089
2090 -static int find_pack_entry(struct repository *r,
2090 +static int find_pack_entry(struct packfile_store *store,
2091 const struct object_id *oid,
2092 struct pack_entry *e)
2093 {
2094 - struct odb_source *source;
2095 -
2096 - for (source = r->objects->sources; source; source = source->next) {
2097 - packfile_store_prepare(r->objects->sources->packfiles);
2098 - if (source->midx && fill_midx_entry(source->midx, oid, e))
2099 - return 1;
2100 - }
2094 + struct packfile_list_entry *l;
2095
2102 - for (source = r->objects->sources; source; source = source->next) {
2103 - struct packfile_list_entry *l;
2096 + packfile_store_prepare(store);
2097 + if (store->source->midx && fill_midx_entry(store->source->midx, oid, e))
2098 + return 1;
2099
2105 - for (l = source->packfiles->packs.head; l; l = l->next) {
2106 - struct packed_git *p = l->pack;
2100 + for (l = store->packs.head; l; l = l->next) {
2101 + struct packed_git *p = l->pack;
2102
2108 - if (!p->multi_pack_index && fill_pack_entry(oid, e, p)) {
2109 - if (!source->packfiles->skip_mru_updates)
2110 - packfile_list_prepend(&source->packfiles->packs, p);
2111 - return 1;
2112 - }
2103 + if (!p->multi_pack_index && fill_pack_entry(oid, e, p)) {
2104 + if (!store->skip_mru_updates)
2105 + packfile_list_prepend(&store->packs, p);
2106 + return 1;
2107 }
2108 }
2109
@@ -2120,7 +2114,7 @@ int packfile_store_freshen_object(struct packfile_store *store,
2114 const struct object_id *oid)
2115 {
2116 struct pack_entry e;
2123 - if (!find_pack_entry(store->source->odb->repo, oid, &e))
2117 + if (!find_pack_entry(store, oid, &e))
2118 return 0;
2119 if (e.p->is_cruft)
2120 return 0;
@@ -2141,7 +2135,7 @@ int packfile_store_read_object_info(struct packfile_store *store,
2135 struct pack_entry e;
2136 int rtype;
2137
2144 - if (!find_pack_entry(store->source->odb->repo, oid, &e))
2138 + if (!find_pack_entry(store, oid, &e))
2139 return 1;
2140
2141 /*
@@ -2217,8 +2211,17 @@ struct packed_git **packfile_store_get_kept_pack_cache(struct packfile_store *st
2211
2212 int has_object_pack(struct repository *r, const struct object_id *oid)
2213 {
2214 + struct odb_source *source;
2215 struct pack_entry e;
2221 - return find_pack_entry(r, oid, &e);
2216 +
2217 + odb_prepare_alternates(r->objects);
2218 + for (source = r->objects->sources; source; source = source->next) {
2219 + int ret = find_pack_entry(source->packfiles, oid, &e);
2220 + if (ret)
2221 + return ret;
2222 + }
2223 +
2224 + return 0;
2225 }
2226
2227 int has_object_kept_pack(struct repository *r, const struct object_id *oid,