]> git.ipfire.org Git - thirdparty/git.git/blobdiff - pack-revindex.c
setup: adopt shared init-db & clone code
[thirdparty/git.git] / pack-revindex.c
index 29f5358b2564cbcd8dda4f47ac2a99c38f26b23d..1f51b712e879e401e9b308d993a2b810460f01e3 100644 (file)
@@ -1,10 +1,13 @@
-#include "cache.h"
+#include "git-compat-util.h"
 #include "gettext.h"
 #include "pack-revindex.h"
+#include "object-file.h"
 #include "object-store.h"
 #include "packfile.h"
+#include "trace2.h"
 #include "config.h"
 #include "midx.h"
+#include "csum-file.h"
 
 struct revindex_entry {
        off_t offset;
@@ -211,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)) {
@@ -263,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;
@@ -301,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;