diff options
author | Junio C Hamano <gitster@pobox.com> | 2023-04-28 01:00:59 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2023-04-28 01:00:59 +0200 |
commit | a02675ad907a31205b2de86a945eec327de38132 (patch) | |
tree | 0a85f04bc45f5023568853269ac53591b5a4c9f5 /pack-revindex.c | |
parent | Merge branch 'tb/pack-revindex-on-disk' (diff) | |
parent | fsck: validate .rev file header (diff) | |
download | git-a02675ad907a31205b2de86a945eec327de38132.tar.xz git-a02675ad907a31205b2de86a945eec327de38132.zip |
Merge branch 'ds/fsck-pack-revindex'
"git fsck" learned to validate the on-disk pack reverse index files.
* ds/fsck-pack-revindex:
fsck: validate .rev file header
fsck: check rev-index position values
fsck: check rev-index checksums
fsck: create scaffolding for rev-index checks
Diffstat (limited to 'pack-revindex.c')
-rw-r--r-- | pack-revindex.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/pack-revindex.c b/pack-revindex.c index db282dac8d..1f51b712e8 100644 --- a/pack-revindex.c +++ b/pack-revindex.c @@ -7,6 +7,7 @@ #include "trace2.h" #include "config.h" #include "midx.h" +#include "csum-file.h" struct revindex_entry { off_t offset; @@ -213,7 +214,8 @@ static int load_revindex_from_disk(char *revindex_name, fd = git_open(revindex_name); if (fd < 0) { - ret = -1; + /* "No file" means return 1. */ + ret = 1; goto cleanup; } if (fstat(fd, &st)) { @@ -265,7 +267,7 @@ cleanup: return ret; } -static int load_pack_revindex_from_disk(struct packed_git *p) +int load_pack_revindex_from_disk(struct packed_git *p) { char *revindex_name; int ret; @@ -303,6 +305,43 @@ int load_pack_revindex(struct repository *r, struct packed_git *p) return -1; } +/* + * verify_pack_revindex verifies that the on-disk rev-index for the given + * pack-file is the same that would be created if written from scratch. + * + * A negative number is returned on error. + */ +int verify_pack_revindex(struct packed_git *p) +{ + int res = 0; + + /* Do not bother checking if not initialized. */ + if (!p->revindex_map || !p->revindex_data) + return res; + + if (!hashfile_checksum_valid((const unsigned char *)p->revindex_map, p->revindex_size)) { + error(_("invalid checksum")); + res = -1; + } + + /* This may fail due to a broken .idx. */ + if (create_pack_revindex_in_memory(p)) + return res; + + for (size_t i = 0; i < p->num_objects; i++) { + uint32_t nr = p->revindex[i].nr; + uint32_t rev_val = get_be32(p->revindex_data + i); + + if (nr != rev_val) { + error(_("invalid rev-index position at %"PRIu64": %"PRIu32" != %"PRIu32""), + (uint64_t)i, nr, rev_val); + res = -1; + } + } + + return res; +} + int load_midx_revindex(struct multi_pack_index *m) { struct strbuf revindex_name = STRBUF_INIT; |