pack-revindex: open index if necessary

We can't create a pack revindex if we haven't actually looked at the index. Normally we would never get as far as creating a revindex without having already been looking in the pack, so this code never bothered to double-check that pack->index_data had been loaded. But with the new multi-pack-index feature, many code paths might not load the individual pack .idx at all (they'd find objects via the midx and then open the .pack, but not its index). This can't yet be triggered in practice, because a bug in the midx code means we accidentally open up the individual .idx files anyway. But in preparation for fixing that, let's have the revindex code check that everything it needs has been loaded. In most cases this will just be a quick noop. But note that this does introduce a possibility of error (if we have to open the index and it's corrupt), so load_pack_revindex() now returns a result code, and callers need to handle the error. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Apr 5, 2019 at 14:04 UTC 4828ce9871fee0ea0309220c461fdedf255df931
4 files changed +17 -7
pack-bitmap.c
+2 -1
@@ -308,7 +308,8 @@ static int load_pack_bitmap(struct bitmap_index *bitmap_git)
308
309 bitmap_git->bitmaps = kh_init_sha1();
310 bitmap_git->ext_index.positions = kh_init_sha1_pos();
311 - load_pack_revindex(bitmap_git->pack);
311 + if (load_pack_revindex(bitmap_git->pack))
312 + goto failed;
313
314 if (!(bitmap_git->commits = read_bitmap_1(bitmap_git)) ||
315 !(bitmap_git->trees = read_bitmap_1(bitmap_git)) ||
pack-revindex.c
+10 -3
@@ -1,6 +1,7 @@
1 #include "cache.h"
2 #include "pack-revindex.h"
3 #include "object-store.h"
4 +#include "packfile.h"
5
6 /*
7 * Pack index for existing packs give us easy access to the offsets into
@@ -158,10 +159,14 @@ static void create_pack_revindex(struct packed_git *p)
159 sort_revindex(p->revindex, num_ent, p->pack_size);
160 }
161
161 -void load_pack_revindex(struct packed_git *p)
162 +int load_pack_revindex(struct packed_git *p)
163 {
163 - if (!p->revindex)
164 + if (!p->revindex) {
165 + if (open_pack_index(p))
166 + return -1;
167 create_pack_revindex(p);
168 + }
169 + return 0;
170 }
171
172 int find_revindex_position(struct packed_git *p, off_t ofs)
@@ -188,7 +193,9 @@ struct revindex_entry *find_pack_revindex(struct packed_git *p, off_t ofs)
193 {
194 int pos;
195
191 - load_pack_revindex(p);
196 + if (load_pack_revindex(p))
197 + return NULL;
198 +
199 pos = find_revindex_position(p, ofs);
200
201 if (pos < 0)
pack-revindex.h
+1 -1
@@ -8,7 +8,7 @@ struct revindex_entry {
8 unsigned int nr;
9 };
10
11 -void load_pack_revindex(struct packed_git *p);
11 +int load_pack_revindex(struct packed_git *p);
12 int find_revindex_position(struct packed_git *p, off_t ofs);
13
14 struct revindex_entry *find_pack_revindex(struct packed_git *p, off_t ofs);
packfile.c
+4 -2
@@ -2023,8 +2023,10 @@ int for_each_object_in_pack(struct packed_git *p,
2023 uint32_t i;
2024 int r = 0;
2025
2026 - if (flags & FOR_EACH_OBJECT_PACK_ORDER)
2027 - load_pack_revindex(p);
2026 + if (flags & FOR_EACH_OBJECT_PACK_ORDER) {
2027 + if (load_pack_revindex(p))
2028 + return -1;
2029 + }
2030
2031 for (i = 0; i < p->num_objects; i++) {
2032 uint32_t pos;