From 552de3d95ad000140bebb0507a65f16f731c06e6 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 31 Aug 2026 08:46:21 +0200 Subject: [PATCH] builtin/fsck: move reverse index verification into the packed source The checks for reverse indexes live in `check_pack_rev_indexes()`, which is hosted in "builtin/fsck.c". These checks are obviously specific to the "packed" backend. Move the logic into `odb_source_packed_fsck()`. As in the preceding commit, drop the dedicated `ERROR_PACK_REV_INDEX` bit and instead use the generic `ERROR_OBJECT` bit. Note that this changes behaviour in two ways: - The checks are now skipped when "--connectivity-only" was passed. This is because we don't even run `odb_fsck()` at all when that flag has been passed by the user, and not verifying data structures of the object database matches the documented intent of that flag, which is to only check the connectivity of reachable objects. - The checks are now skipped for non-local sources when "--no-full" was passed. This is, again, in line with the documented intent of that flag. Add a test to cast these semantics into stone. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/fsck.c | 37 ------------------------------------- odb/source-packed.c | 39 +++++++++++++++++++++++++++++++++++++++ t/t5325-reverse-index.sh | 8 ++++++++ 3 files changed, 47 insertions(+), 37 deletions(-) diff --git a/builtin/fsck.c b/builtin/fsck.c index e504dae904..06e72877f3 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -23,7 +23,6 @@ #include "run-command.h" #include "sparse-index.h" #include "worktree.h" -#include "pack-revindex.h" #include "pack-bitmap.h" #define REACHABLE 0x0001 @@ -51,7 +50,6 @@ static timestamp_t now; #define ERROR_REFS 010 #define ERROR_COMMIT_GRAPH 020 #define ERROR_MULTI_PACK_INDEX 040 -#define ERROR_PACK_REV_INDEX 0100 #define ERROR_BITMAP 0200 static const char *describe_object(const struct object_id *oid) @@ -890,40 +888,6 @@ static int mark_object_for_connectivity(const struct object_id *oid, return 0; } -static int check_pack_rev_indexes(struct repository *r, int show_progress) -{ - struct progress *progress = NULL; - struct packed_git *p; - uint32_t pack_count = 0; - int res = 0; - - if (show_progress) { - repo_for_each_pack(r, p) - pack_count++; - progress = start_delayed_progress(r, - "Verifying reverse pack-indexes", pack_count); - pack_count = 0; - } - - repo_for_each_pack(r, p) { - int load_error = load_pack_revindex_from_disk(p); - - if (load_error < 0) { - error(_("unable to load rev-index for pack '%s'"), p->pack_name); - res = ERROR_PACK_REV_INDEX; - } else if (!load_error && - !load_pack_revindex(r, p) && - verify_pack_revindex(p)) { - error(_("invalid rev-index for pack '%s'"), p->pack_name); - res = ERROR_PACK_REV_INDEX; - } - display_progress(progress, ++pack_count); - } - stop_progress(&progress); - - return res; -} - static void fsck_refs(struct repository *r) { struct child_process refs_verify = CHILD_PROCESS_INIT; @@ -1104,7 +1068,6 @@ int cmd_fsck(int argc, free_worktrees(worktrees); } - errors_found |= check_pack_rev_indexes(repo, show_progress); if (verify_bitmap_files(repo)) errors_found |= ERROR_BITMAP; diff --git a/odb/source-packed.c b/odb/source-packed.c index 0d3599f8fe..e5e69636dd 100644 --- a/odb/source-packed.c +++ b/odb/source-packed.c @@ -10,6 +10,7 @@ #include "odb/source-packed.h" #include "odb/streaming.h" #include "pack.h" +#include "pack-revindex.h" #include "packfile.h" #include "pack-bitmap.h" #include "progress.h" @@ -861,6 +862,41 @@ static int verify_packs(struct odb_source_packed *source, return ret; } +static int verify_reverse_indices(struct odb_source_packed *source, + struct odb_fsck_options *opts) +{ + struct progress *progress = NULL; + struct packfile_list_entry *e; + uint32_t pack_count = 0; + int res = 0; + + if (opts->flags & ODB_FSCK_PROGRESS) { + for (e = packfile_store_get_packs(source); e; e = e->next) + pack_count++; + progress = start_delayed_progress(source->base.odb->repo, + "Verifying reverse pack-indexes", pack_count); + pack_count = 0; + } + + for (e = packfile_store_get_packs(source); e; e = e->next) { + int load_error = load_pack_revindex_from_disk(e->pack); + + if (load_error < 0) { + error(_("unable to load rev-index for pack '%s'"), e->pack->pack_name); + res = -1; + } else if (!load_error && + !load_pack_revindex(source->base.odb->repo, e->pack) && + verify_pack_revindex(e->pack)) { + error(_("invalid rev-index for pack '%s'"), e->pack->pack_name); + res = -1; + } + display_progress(progress, ++pack_count); + } + stop_progress(&progress); + + return res; +} + static int odb_source_packed_fsck(struct odb_source *source, struct odb_fsck_options *opts) { @@ -870,6 +906,9 @@ static int odb_source_packed_fsck(struct odb_source *source, if ((opts->flags & ODB_FSCK_FULL) && verify_packs(packed, opts) < 0) ret = -1; + if (verify_reverse_indices(packed, opts) < 0) + ret = -1; + return ret; } diff --git a/t/t5325-reverse-index.sh b/t/t5325-reverse-index.sh index 5493791938..6b81abf663 100755 --- a/t/t5325-reverse-index.sh +++ b/t/t5325-reverse-index.sh @@ -204,4 +204,12 @@ test_expect_success 'fsck catches invalid header: hash function' ' "reverse-index file .* has unsupported hash id" ' +test_expect_success 'fsck --no-full checks rev-index, --connectivity-only does not' ' + test_must_fail git -C corrupt fsck --no-full 2>err && + test_grep "has unsupported hash id" err && + + git -C corrupt fsck --connectivity-only 2>err && + test_grep ! "has unsupported hash id" err +' + test_done