aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2025-11-23 19:59:36 +0100
committerJunio C Hamano <gitster@pobox.com>2025-11-23 12:56:45 -0800
commit385e18810f10ec0ce0a266d25da4e1878c8ce15a (patch)
tree6d817f18b5c22197e883df29998ded0f8cfe3db9
parenteb5abbb4e6a8c06f5c6275bbb541bf7d736171c5 (diff)
downloadgit-385e18810f10ec0ce0a266d25da4e1878c8ce15a.tar.gz
packfile: introduce function to read object info from a store
Extract the logic to read object info for a packed object from `do_oid_object_into_extended()` into a standalone function that operates on the packfile store. This function will be used in a subsequent commit. Note that this change allows us to make `find_pack_entry()` an internal implementation detail. As a consequence though we have to move around `packfile_store_freshen_object()` so that it is defined after that function. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--odb.c29
-rw-r--r--packfile.c71
-rw-r--r--packfile.h12
3 files changed, 69 insertions, 43 deletions
diff --git a/odb.c b/odb.c
index 3ec21ef24e..f4cbee4b04 100644
--- a/odb.c
+++ b/odb.c
@@ -666,8 +666,6 @@ static int do_oid_object_info_extended(struct object_database *odb,
{
static struct object_info blank_oi = OBJECT_INFO_INIT;
const struct cached_object *co;
- struct pack_entry e;
- int rtype;
const struct object_id *real = oid;
int already_retried = 0;
@@ -702,8 +700,8 @@ static int do_oid_object_info_extended(struct object_database *odb,
while (1) {
struct odb_source *source;
- if (find_pack_entry(odb->repo, real, &e))
- break;
+ if (!packfile_store_read_object_info(odb->packfiles, real, oi, flags))
+ return 0;
/* Most likely it's a loose object. */
for (source = odb->sources; source; source = source->next)
@@ -713,8 +711,8 @@ static int do_oid_object_info_extended(struct object_database *odb,
/* Not a loose object; someone else may have just packed it. */
if (!(flags & OBJECT_INFO_QUICK)) {
odb_reprepare(odb->repo->objects);
- if (find_pack_entry(odb->repo, real, &e))
- break;
+ if (!packfile_store_read_object_info(odb->packfiles, real, oi, flags))
+ return 0;
}
/*
@@ -747,25 +745,6 @@ static int do_oid_object_info_extended(struct object_database *odb,
}
return -1;
}
-
- if (oi == &blank_oi)
- /*
- * We know that the caller doesn't actually need the
- * information below, so return early.
- */
- return 0;
- rtype = packed_object_info(odb->repo, e.p, e.offset, oi);
- if (rtype < 0) {
- mark_bad_packed_object(e.p, real);
- return do_oid_object_info_extended(odb, real, oi, 0);
- } else if (oi->whence == OI_PACKED) {
- oi->u.packed.offset = e.offset;
- oi->u.packed.pack = e.p;
- oi->u.packed.is_delta = (rtype == OBJ_REF_DELTA ||
- rtype == OBJ_OFS_DELTA);
- }
-
- return 0;
}
static int oid_object_info_convert(struct repository *r,
diff --git a/packfile.c b/packfile.c
index 40f733dd23..b4bc40d895 100644
--- a/packfile.c
+++ b/packfile.c
@@ -819,22 +819,6 @@ struct packed_git *packfile_store_load_pack(struct packfile_store *store,
return p;
}
-int packfile_store_freshen_object(struct packfile_store *store,
- const struct object_id *oid)
-{
- struct pack_entry e;
- if (!find_pack_entry(store->odb->repo, oid, &e))
- return 0;
- if (e.p->is_cruft)
- return 0;
- if (e.p->freshened)
- return 1;
- if (utime(e.p->pack_name, NULL))
- return 0;
- e.p->freshened = 1;
- return 1;
-}
-
void (*report_garbage)(unsigned seen_bits, const char *path);
static void report_helper(const struct string_list *list,
@@ -2064,7 +2048,9 @@ static int fill_pack_entry(const struct object_id *oid,
return 1;
}
-int find_pack_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e)
+static int find_pack_entry(struct repository *r,
+ const struct object_id *oid,
+ struct pack_entry *e)
{
struct list_head *pos;
@@ -2087,6 +2073,57 @@ int find_pack_entry(struct repository *r, const struct object_id *oid, struct pa
return 0;
}
+int packfile_store_freshen_object(struct packfile_store *store,
+ const struct object_id *oid)
+{
+ struct pack_entry e;
+ if (!find_pack_entry(store->odb->repo, oid, &e))
+ return 0;
+ if (e.p->is_cruft)
+ return 0;
+ if (e.p->freshened)
+ return 1;
+ if (utime(e.p->pack_name, NULL))
+ return 0;
+ e.p->freshened = 1;
+ return 1;
+}
+
+int packfile_store_read_object_info(struct packfile_store *store,
+ const struct object_id *oid,
+ struct object_info *oi,
+ unsigned flags UNUSED)
+{
+ static struct object_info blank_oi = OBJECT_INFO_INIT;
+ struct pack_entry e;
+ int rtype;
+
+ if (!find_pack_entry(store->odb->repo, oid, &e))
+ return 1;
+
+ /*
+ * We know that the caller doesn't actually need the
+ * information below, so return early.
+ */
+ if (oi == &blank_oi)
+ return 0;
+
+ rtype = packed_object_info(store->odb->repo, e.p, e.offset, oi);
+ if (rtype < 0) {
+ mark_bad_packed_object(e.p, oid);
+ return -1;
+ }
+
+ if (oi->whence == OI_PACKED) {
+ oi->u.packed.offset = e.offset;
+ oi->u.packed.pack = e.p;
+ oi->u.packed.is_delta = (rtype == OBJ_REF_DELTA ||
+ rtype == OBJ_OFS_DELTA);
+ }
+
+ return 0;
+}
+
static void maybe_invalidate_kept_pack_cache(struct repository *r,
unsigned flags)
{
diff --git a/packfile.h b/packfile.h
index 58fcc88e20..0a98bddd81 100644
--- a/packfile.h
+++ b/packfile.h
@@ -145,6 +145,17 @@ void packfile_store_add_pack(struct packfile_store *store,
for (p = packfile_store_get_packs(repo->objects->packfiles); p; p = p->next)
/*
+ * 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 packfile_store *store,
+ const struct object_id *oid,
+ struct object_info *oi,
+ unsigned flags);
+
+/*
* Get all packs managed by the given store, including packfiles that are
* referenced by multi-pack indices.
*/
@@ -357,7 +368,6 @@ const struct packed_git *has_packed_and_bad(struct repository *, const struct ob
* Iff a pack file in the given repository contains the object named by sha1,
* return true and store its location to e.
*/
-int find_pack_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e);
int find_kept_pack_entry(struct repository *r, const struct object_id *oid, unsigned flags, struct pack_entry *e);
int has_object_pack(struct repository *r, const struct object_id *oid);