builtin/fsck: stop using `the_repository` when checking packed objects

We implicitly rely on `the_repository` when checking objects part of a packfile. These objects are iterated over via `verify_pack()`, which is provided by the packfile subsystem, and a callback function is then invoked for each of the objects in that specific pack. Unfortunately, it is not possible to provide a payload to the callback function. Refactor `verify_pack()` to accept a payload that is passed through to the callback so that we can inject the repository and get rid of the use of `the_repository`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Mar 23, 2026 at 16:03 UTC 1c5f77b6103adae5d45ae9ff24e9945b8f8b76c8
3 files changed +17 -10
builtin/fsck.c
+6 -5
@@ -447,15 +447,16 @@ out:
447 }
448
449 static int fsck_obj_buffer(const struct object_id *oid, enum object_type type,
450 - unsigned long size, void *buffer, int *eaten)
450 + unsigned long size, void *buffer, int *eaten, void *cb_data)
451 {
452 + struct repository *repo = cb_data;
453 + struct object *obj;
454 +
455 /*
456 * Note, buffer may be NULL if type is OBJ_BLOB. See
457 * verify_packfile(), data_valid variable for details.
458 */
456 - struct object *obj;
457 - obj = parse_object_buffer(the_repository, oid, type, size, buffer,
458 - eaten);
459 + obj = parse_object_buffer(repo, oid, type, size, buffer, eaten);
460 if (!obj) {
461 errors_found |= ERROR_OBJECT;
462 return error(_("%s: object corrupt or missing"),
@@ -1089,7 +1090,7 @@ int cmd_fsck(int argc,
1090 repo_for_each_pack(repo, p) {
1091 /* verify gives error messages itself */
1092 if (verify_pack(repo,
1092 - p, fsck_obj_buffer,
1093 + p, fsck_obj_buffer, repo,
1094 progress, count))
1095 errors_found |= ERROR_PACK;
1096 count += p->num_objects;
pack-check.c
+4 -3
@@ -53,6 +53,7 @@ static int verify_packfile(struct repository *r,
53 struct packed_git *p,
54 struct pack_window **w_curs,
55 verify_fn fn,
56 + void *fn_data,
57 struct progress *progress, uint32_t base_count)
58
59 {
@@ -161,7 +162,7 @@ static int verify_packfile(struct repository *r,
162 oid_to_hex(&oid), p->pack_name);
163 else if (fn) {
164 int eaten = 0;
164 - err |= fn(&oid, type, size, data, &eaten);
165 + err |= fn(&oid, type, size, data, &eaten, fn_data);
166 if (eaten)
167 data = NULL;
168 }
@@ -192,7 +193,7 @@ int verify_pack_index(struct packed_git *p)
193 return err;
194 }
195
195 -int verify_pack(struct repository *r, struct packed_git *p, verify_fn fn,
196 +int verify_pack(struct repository *r, struct packed_git *p, verify_fn fn, void *fn_data,
197 struct progress *progress, uint32_t base_count)
198 {
199 int err = 0;
@@ -202,7 +203,7 @@ int verify_pack(struct repository *r, struct packed_git *p, verify_fn fn,
203 if (!p->index_data)
204 return -1;
205
205 - err |= verify_packfile(r, p, &w_curs, fn, progress, base_count);
206 + err |= verify_packfile(r, p, &w_curs, fn, fn_data, progress, base_count);
207 unuse_pack(&w_curs);
208
209 return err;
pack.h
+7 -2
@@ -85,7 +85,11 @@ struct pack_idx_entry {
85
86 struct progress;
87 /* Note, the data argument could be NULL if object type is blob */
88 -typedef int (*verify_fn)(const struct object_id *, enum object_type, unsigned long, void*, int*);
88 +typedef int (*verify_fn)(const struct object_id *oid,
89 + enum object_type type,
90 + unsigned long size,
91 + void *buffer, int *eaten,
92 + void *fn_data);
93
94 const char *write_idx_file(struct repository *repo,
95 const char *index_name,
@@ -95,7 +99,8 @@ const char *write_idx_file(struct repository *repo,
99 const unsigned char *sha1);
100 int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, off_t offset, off_t len, unsigned int nr);
101 int verify_pack_index(struct packed_git *);
98 -int verify_pack(struct repository *, struct packed_git *, verify_fn fn, struct progress *, uint32_t);
102 +int verify_pack(struct repository *, struct packed_git *, verify_fn fn, void *fn_data,
103 + struct progress *, uint32_t);
104 off_t write_pack_header(struct hashfile *f, uint32_t);
105 void fixup_pack_header_footer(const struct git_hash_algo *, int,
106 unsigned char *, const char *, uint32_t,