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>
Patrick Steinhardt committed
Nov 23, 2025 at 19:59 UTC
385e18810f10ec0ce0a266d25da4e1878c8ce15a
3 files changed
+69
-43
odb.c
+4
-25
@@ -666,8 +666,6 @@ static int do_oid_object_info_extended(struct object_database *odb,
666
{
667
static struct object_info blank_oi = OBJECT_INFO_INIT;
668
const struct cached_object *co;
669
- struct pack_entry e;
670
- int rtype;
669
const struct object_id *real = oid;
670
int already_retried = 0;
671
@@ -702,8 +700,8 @@ static int do_oid_object_info_extended(struct object_database *odb,
700
while (1) {
701
struct odb_source *source;
702
705
- if (find_pack_entry(odb->repo, real, &e))
706
- break;
703
+ if (!packfile_store_read_object_info(odb->packfiles, real, oi, flags))
704
+ return 0;
705
706
/* Most likely it's a loose object. */
707
for (source = odb->sources; source; source = source->next)
@@ -713,8 +711,8 @@ static int do_oid_object_info_extended(struct object_database *odb,
711
/* Not a loose object; someone else may have just packed it. */
712
if (!(flags & OBJECT_INFO_QUICK)) {
713
odb_reprepare(odb->repo->objects);
716
- if (find_pack_entry(odb->repo, real, &e))
717
- break;
714
+ if (!packfile_store_read_object_info(odb->packfiles, real, oi, flags))
715
+ return 0;
716
}
717
718
/*
@@ -747,25 +745,6 @@ static int do_oid_object_info_extended(struct object_database *odb,
745
}
746
return -1;
747
}
750
-
751
- if (oi == &blank_oi)
752
- /*
753
- * We know that the caller doesn't actually need the
754
- * information below, so return early.
755
- */
756
- return 0;
757
- rtype = packed_object_info(odb->repo, e.p, e.offset, oi);
758
- if (rtype < 0) {
759
- mark_bad_packed_object(e.p, real);
760
- return do_oid_object_info_extended(odb, real, oi, 0);
761
- } else if (oi->whence == OI_PACKED) {
762
- oi->u.packed.offset = e.offset;
763
- oi->u.packed.pack = e.p;
764
- oi->u.packed.is_delta = (rtype == OBJ_REF_DELTA ||
765
- rtype == OBJ_OFS_DELTA);
766
- }
767
-
768
- return 0;
748
}
749
750
static int oid_object_info_convert(struct repository *r,
packfile.c
+54
-17
@@ -819,22 +819,6 @@ struct packed_git *packfile_store_load_pack(struct packfile_store *store,
819
return p;
820
}
821
822
-int packfile_store_freshen_object(struct packfile_store *store,
823
- const struct object_id *oid)
824
-{
825
- struct pack_entry e;
826
- if (!find_pack_entry(store->odb->repo, oid, &e))
827
- return 0;
828
- if (e.p->is_cruft)
829
- return 0;
830
- if (e.p->freshened)
831
- return 1;
832
- if (utime(e.p->pack_name, NULL))
833
- return 0;
834
- e.p->freshened = 1;
835
- return 1;
836
-}
837
-
822
void (*report_garbage)(unsigned seen_bits, const char *path);
823
824
static void report_helper(const struct string_list *list,
@@ -2064,7 +2048,9 @@ static int fill_pack_entry(const struct object_id *oid,
2048
return 1;
2049
}
2050
2067
-int find_pack_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e)
2051
+static int find_pack_entry(struct repository *r,
2052
+ const struct object_id *oid,
2053
+ struct pack_entry *e)
2054
{
2055
struct list_head *pos;
2056
@@ -2087,6 +2073,57 @@ int find_pack_entry(struct repository *r, const struct object_id *oid, struct pa
2073
return 0;
2074
}
2075
2076
+int packfile_store_freshen_object(struct packfile_store *store,
2077
+ const struct object_id *oid)
2078
+{
2079
+ struct pack_entry e;
2080
+ if (!find_pack_entry(store->odb->repo, oid, &e))
2081
+ return 0;
2082
+ if (e.p->is_cruft)
2083
+ return 0;
2084
+ if (e.p->freshened)
2085
+ return 1;
2086
+ if (utime(e.p->pack_name, NULL))
2087
+ return 0;
2088
+ e.p->freshened = 1;
2089
+ return 1;
2090
+}
2091
+
2092
+int packfile_store_read_object_info(struct packfile_store *store,
2093
+ const struct object_id *oid,
2094
+ struct object_info *oi,
2095
+ unsigned flags UNUSED)
2096
+{
2097
+ static struct object_info blank_oi = OBJECT_INFO_INIT;
2098
+ struct pack_entry e;
2099
+ int rtype;
2100
+
2101
+ if (!find_pack_entry(store->odb->repo, oid, &e))
2102
+ return 1;
2103
+
2104
+ /*
2105
+ * We know that the caller doesn't actually need the
2106
+ * information below, so return early.
2107
+ */
2108
+ if (oi == &blank_oi)
2109
+ return 0;
2110
+
2111
+ rtype = packed_object_info(store->odb->repo, e.p, e.offset, oi);
2112
+ if (rtype < 0) {
2113
+ mark_bad_packed_object(e.p, oid);
2114
+ return -1;
2115
+ }
2116
+
2117
+ if (oi->whence == OI_PACKED) {
2118
+ oi->u.packed.offset = e.offset;
2119
+ oi->u.packed.pack = e.p;
2120
+ oi->u.packed.is_delta = (rtype == OBJ_REF_DELTA ||
2121
+ rtype == OBJ_OFS_DELTA);
2122
+ }
2123
+
2124
+ return 0;
2125
+}
2126
+
2127
static void maybe_invalidate_kept_pack_cache(struct repository *r,
2128
unsigned flags)
2129
{
packfile.h
+11
-1
@@ -144,6 +144,17 @@ void packfile_store_add_pack(struct packfile_store *store,
144
#define repo_for_each_pack(repo, p) \
145
for (p = packfile_store_get_packs(repo->objects->packfiles); p; p = p->next)
146
147
+/*
148
+ * Try to read the object identified by its ID from the object store and
149
+ * populate the object info with its data. Returns 1 in case the object was
150
+ * not found, 0 if it was and read successfully, and a negative error code in
151
+ * case the object was corrupted.
152
+ */
153
+int packfile_store_read_object_info(struct packfile_store *store,
154
+ const struct object_id *oid,
155
+ struct object_info *oi,
156
+ unsigned flags);
157
+
158
/*
159
* Get all packs managed by the given store, including packfiles that are
160
* referenced by multi-pack indices.
@@ -357,7 +368,6 @@ const struct packed_git *has_packed_and_bad(struct repository *, const struct ob
368
* Iff a pack file in the given repository contains the object named by sha1,
369
* return true and store its location to e.
370
*/
360
-int find_pack_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e);
371
int find_kept_pack_entry(struct repository *r, const struct object_id *oid, unsigned flags, struct pack_entry *e);
372
373
int has_object_pack(struct repository *r, const struct object_id *oid);