]> git.ipfire.org Git - thirdparty/git.git/commitdiff
packfile: introduce function to read object info from a store
authorPatrick Steinhardt <ps@pks.im>
Sun, 23 Nov 2025 18:59:36 +0000 (19:59 +0100)
committerJunio C Hamano <gitster@pobox.com>
Sun, 23 Nov 2025 20:56:45 +0000 (12:56 -0800)
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>
odb.c
packfile.c
packfile.h

diff --git a/odb.c b/odb.c
index 3ec21ef24e16bb6da22b58abfa50553318f98761..f4cbee4b042d83e4442ba3e264b3752e68148bee 100644 (file)
--- 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,
index 40f733dd234900662dc23d5c48906690b0046d88..b4bc40d895c8da1d573e145457924f3d2ca7f35b 100644 (file)
@@ -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)
 {
index 58fcc88e20224b18319168d4d6efdb6e2d6a3dff..0a98bddd8119210b06ac3a2726f330f4bb903c77 100644 (file)
@@ -144,6 +144,17 @@ void packfile_store_add_pack(struct packfile_store *store,
 #define repo_for_each_pack(repo, p) \
        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);