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>
maint
Patrick Steinhardt 2026-03-23 16:03:01 +01:00 committed by Junio C Hamano
parent 2b2287c479
commit 1c5f77b610
3 changed files with 17 additions and 10 deletions

View File

@ -447,15 +447,16 @@ out:
} }


static int fsck_obj_buffer(const struct object_id *oid, enum object_type type, static int fsck_obj_buffer(const struct object_id *oid, enum object_type type,
unsigned long size, void *buffer, int *eaten) unsigned long size, void *buffer, int *eaten, void *cb_data)
{ {
struct repository *repo = cb_data;
struct object *obj;

/* /*
* Note, buffer may be NULL if type is OBJ_BLOB. See * Note, buffer may be NULL if type is OBJ_BLOB. See
* verify_packfile(), data_valid variable for details. * verify_packfile(), data_valid variable for details.
*/ */
struct object *obj; obj = parse_object_buffer(repo, oid, type, size, buffer, eaten);
obj = parse_object_buffer(the_repository, oid, type, size, buffer,
eaten);
if (!obj) { if (!obj) {
errors_found |= ERROR_OBJECT; errors_found |= ERROR_OBJECT;
return error(_("%s: object corrupt or missing"), return error(_("%s: object corrupt or missing"),
@ -1089,7 +1090,7 @@ int cmd_fsck(int argc,
repo_for_each_pack(repo, p) { repo_for_each_pack(repo, p) {
/* verify gives error messages itself */ /* verify gives error messages itself */
if (verify_pack(repo, if (verify_pack(repo,
p, fsck_obj_buffer, p, fsck_obj_buffer, repo,
progress, count)) progress, count))
errors_found |= ERROR_PACK; errors_found |= ERROR_PACK;
count += p->num_objects; count += p->num_objects;

View File

@ -53,6 +53,7 @@ static int verify_packfile(struct repository *r,
struct packed_git *p, struct packed_git *p,
struct pack_window **w_curs, struct pack_window **w_curs,
verify_fn fn, verify_fn fn,
void *fn_data,
struct progress *progress, uint32_t base_count) struct progress *progress, uint32_t base_count)


{ {
@ -161,7 +162,7 @@ static int verify_packfile(struct repository *r,
oid_to_hex(&oid), p->pack_name); oid_to_hex(&oid), p->pack_name);
else if (fn) { else if (fn) {
int eaten = 0; int eaten = 0;
err |= fn(&oid, type, size, data, &eaten); err |= fn(&oid, type, size, data, &eaten, fn_data);
if (eaten) if (eaten)
data = NULL; data = NULL;
} }
@ -192,7 +193,7 @@ int verify_pack_index(struct packed_git *p)
return err; return err;
} }


int verify_pack(struct repository *r, struct packed_git *p, verify_fn fn, int verify_pack(struct repository *r, struct packed_git *p, verify_fn fn, void *fn_data,
struct progress *progress, uint32_t base_count) struct progress *progress, uint32_t base_count)
{ {
int err = 0; int err = 0;
@ -202,7 +203,7 @@ int verify_pack(struct repository *r, struct packed_git *p, verify_fn fn,
if (!p->index_data) if (!p->index_data)
return -1; return -1;


err |= verify_packfile(r, p, &w_curs, fn, progress, base_count); err |= verify_packfile(r, p, &w_curs, fn, fn_data, progress, base_count);
unuse_pack(&w_curs); unuse_pack(&w_curs);


return err; return err;

9
pack.h
View File

@ -85,7 +85,11 @@ struct pack_idx_entry {


struct progress; struct progress;
/* Note, the data argument could be NULL if object type is blob */ /* Note, the data argument could be NULL if object type is blob */
typedef int (*verify_fn)(const struct object_id *, enum object_type, unsigned long, void*, int*); typedef int (*verify_fn)(const struct object_id *oid,
enum object_type type,
unsigned long size,
void *buffer, int *eaten,
void *fn_data);


const char *write_idx_file(struct repository *repo, const char *write_idx_file(struct repository *repo,
const char *index_name, const char *index_name,
@ -95,7 +99,8 @@ const char *write_idx_file(struct repository *repo,
const unsigned char *sha1); const unsigned char *sha1);
int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, off_t offset, off_t len, unsigned int nr); int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, off_t offset, off_t len, unsigned int nr);
int verify_pack_index(struct packed_git *); int verify_pack_index(struct packed_git *);
int verify_pack(struct repository *, struct packed_git *, verify_fn fn, struct progress *, uint32_t); int verify_pack(struct repository *, struct packed_git *, verify_fn fn, void *fn_data,
struct progress *, uint32_t);
off_t write_pack_header(struct hashfile *f, uint32_t); off_t write_pack_header(struct hashfile *f, uint32_t);
void fixup_pack_header_footer(const struct git_hash_algo *, int, void fixup_pack_header_footer(const struct git_hash_algo *, int,
unsigned char *, const char *, uint32_t, unsigned char *, const char *, uint32_t,