odb/source-packed: wire up `read_object_info()` callback

Move the logic to read object info from a "packed" source into
"odb/source-packed.c" and wire it up as the `read_object_info()`
callback.

Note that we also move around the supporting `find_pack_entry()`, but we
still have to expose it to other callers that exist in "packfile.c".
This will be fixed in subsequent commits though, where all callers in
"packfile.c" will have been moved into "odb/source-packed.c", and at
that point we'll be able to make `find_pack_entry()` file-local again.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
next
Patrick Steinhardt 2026-06-17 08:39:52 +02:00 committed by Junio C Hamano
parent 77e175c6d0
commit 64136a8207
5 changed files with 79 additions and 78 deletions

View File

@ -55,7 +55,7 @@ static int odb_source_files_read_object_info(struct odb_source *source,
{
struct odb_source_files *files = odb_source_files_downcast(source);

if (!packfile_store_read_object_info(files->packed, oid, oi, flags) ||
if (!odb_source_read_object_info(&files->packed->base, oid, oi, flags) ||
!odb_source_read_object_info(&files->loose->base, oid, oi, flags))
return 0;


View File

@ -7,6 +7,65 @@
#include "odb/source-packed.h"
#include "packfile.h"

int find_pack_entry(struct odb_source_packed *store,
const struct object_id *oid,
struct pack_entry *e)
{
struct packfile_list_entry *l;

odb_source_packed_prepare(store);
if (store->midx && fill_midx_entry(store->midx, oid, e))
return 1;

for (l = store->packs.head; l; l = l->next) {
struct packed_git *p = l->pack;

if (!p->multi_pack_index && packfile_fill_entry(p, oid, e)) {
if (!store->skip_mru_updates)
packfile_list_prepend(&store->packs, p);
return 1;
}
}

return 0;
}

static int odb_source_packed_read_object_info(struct odb_source *source,
const struct object_id *oid,
struct object_info *oi,
enum object_info_flags flags)
{
struct odb_source_packed *packed = odb_source_packed_downcast(source);
struct pack_entry e;
int ret;

/*
* In case the first read didn't surface the object, we have to reload
* packfiles. This may cause us to discover new packfiles that have
* been added since the last time we have prepared the packfile store.
*/
if (flags & OBJECT_INFO_SECOND_READ)
odb_source_reprepare(source);

if (!find_pack_entry(packed, oid, &e))
return 1;

/*
* We know that the caller doesn't actually need the
* information below, so return early.
*/
if (!oi)
return 0;

ret = packed_object_info(e.p, e.offset, oi);
if (ret < 0) {
mark_bad_packed_object(e.p, oid);
return -1;
}

return 0;
}

void (*report_garbage)(unsigned seen_bits, const char *path);

static void report_helper(const struct string_list *list,
@ -215,6 +274,7 @@ struct odb_source_packed *odb_source_packed_new(struct odb_source_files *parent)
packed->base.free = odb_source_packed_free;
packed->base.close = odb_source_packed_close;
packed->base.reprepare = odb_source_packed_reprepare;
packed->base.read_object_info = odb_source_packed_read_object_info;

if (!is_absolute_path(parent->base.path))
chdir_notify_register(NULL, odb_source_packed_reparent, packed);

View File

@ -90,4 +90,10 @@ static inline struct odb_source_packed *odb_source_packed_downcast(struct odb_so
*/
void odb_source_packed_prepare(struct odb_source_packed *source);

struct pack_entry;

int find_pack_entry(struct odb_source_packed *store,
const struct object_id *oid,
struct pack_entry *e);

#endif

View File

@ -1895,9 +1895,9 @@ int is_pack_valid(struct packed_git *p)
return !open_packed_git(p);
}

static int fill_pack_entry(const struct object_id *oid,
struct pack_entry *e,
struct packed_git *p)
int packfile_fill_entry(struct packed_git *p,
const struct object_id *oid,
struct pack_entry *e)
{
off_t offset;

@ -1923,29 +1923,6 @@ static int fill_pack_entry(const struct object_id *oid,
return 1;
}

static int find_pack_entry(struct odb_source_packed *store,
const struct object_id *oid,
struct pack_entry *e)
{
struct packfile_list_entry *l;

odb_source_packed_prepare(store);
if (store->midx && fill_midx_entry(store->midx, oid, e))
return 1;

for (l = store->packs.head; l; l = l->next) {
struct packed_git *p = l->pack;

if (!p->multi_pack_index && fill_pack_entry(oid, e, p)) {
if (!store->skip_mru_updates)
packfile_list_prepend(&store->packs, p);
return 1;
}
}

return 0;
}

int packfile_store_freshen_object(struct odb_source_packed *store,
const struct object_id *oid)
{
@ -1962,41 +1939,6 @@ int packfile_store_freshen_object(struct odb_source_packed *store,
return 1;
}

int packfile_store_read_object_info(struct odb_source_packed *store,
const struct object_id *oid,
struct object_info *oi,
enum object_info_flags flags)
{
struct pack_entry e;
int ret;

/*
* In case the first read didn't surface the object, we have to reload
* packfiles. This may cause us to discover new packfiles that have
* been added since the last time we have prepared the packfile store.
*/
if (flags & OBJECT_INFO_SECOND_READ)
odb_source_reprepare(&store->base);

if (!find_pack_entry(store, oid, &e))
return 1;

/*
* We know that the caller doesn't actually need the
* information below, so return early.
*/
if (!oi)
return 0;

ret = packed_object_info(e.p, e.offset, oi);
if (ret < 0) {
mark_bad_packed_object(e.p, oid);
return -1;
}

return 0;
}

static void maybe_invalidate_kept_pack_cache(struct odb_source_packed *store,
unsigned flags)
{
@ -2053,7 +1995,7 @@ int has_object_pack(struct repository *r, const struct object_id *oid)
odb_prepare_alternates(r->objects);
for (source = r->objects->sources; source; source = source->next) {
struct odb_source_files *files = odb_source_files_downcast(source);
if (!packfile_store_read_object_info(files->packed, oid, NULL, 0))
if (!odb_source_read_object_info(&files->packed->base, oid, NULL, 0))
return 1;
}

@ -2074,7 +2016,7 @@ int has_object_kept_pack(struct repository *r, const struct object_id *oid,

for (; *cache; cache++) {
struct packed_git *p = *cache;
if (fill_pack_entry(oid, &e, p))
if (packfile_fill_entry(p, oid, &e))
return 1;
}
}
@ -2208,8 +2150,8 @@ static int for_each_prefixed_object_in_midx(
if (data->request) {
struct object_info oi = *data->request;

ret = packfile_store_read_object_info(store, current,
&oi, 0);
ret = odb_source_read_object_info(&store->base, current,
&oi, 0);
if (ret)
goto out;

@ -2259,7 +2201,7 @@ static int for_each_prefixed_object_in_pack(
if (data->request) {
struct object_info oi = *data->request;

ret = packfile_store_read_object_info(store, &oid, &oi, 0);
ret = odb_source_read_object_info(&store->base, &oid, &oi, 0);
if (ret)
goto out;


View File

@ -128,17 +128,6 @@ int packfile_store_read_object_stream(struct odb_read_stream **out,
struct odb_source_packed *store,
const struct object_id *oid);

/*
* Try to read the object identified by its ID from the object store and
* populate the object info with its data. Returns 1 in case the object was
* not found, 0 if it was and read successfully, and a negative error code in
* case the object was corrupted.
*/
int packfile_store_read_object_info(struct odb_source_packed *store,
const struct object_id *oid,
struct object_info *oi,
enum object_info_flags flags);

/*
* Open the packfile and add it to the store if it isn't yet known. Returns
* either the newly opened packfile or the preexisting packfile. Returns a
@ -340,6 +329,10 @@ off_t nth_packed_object_offset(const struct packed_git *, uint32_t n);
*/
off_t find_pack_entry_one(const struct object_id *oid, struct packed_git *);

int packfile_fill_entry(struct packed_git *p,
const struct object_id *oid,
struct pack_entry *e);

int is_pack_valid(struct packed_git *);
void *unpack_entry(struct repository *r, struct packed_git *, off_t, enum object_type *, unsigned long *);
unsigned long unpack_object_header_buffer(const unsigned char *buf, unsigned long len, enum object_type *type, size_t *sizep);