pack-bitmap.c: harden 'test_bitmap_walk()' to check type bitmaps
The special `--test-bitmap` mode of `git rev-list` is used to compare the result of an object traversal with a bitmap to check its integrity. This mode does not, however, assert that the types of reachable objects are stored correctly. Harden this mode by teaching it to also check that each time an object's bit is marked, the corresponding bit should be set in exactly one of the type bitmaps (whose type matches the object's true type). Co-authored-by: Jeff King <peff@peff.net> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Taylor Blau committed
Aug 24, 2021 at 12:15 UTC
fa95666a403e5dda4c2c14ac168b5c3389126e6c
1 file changed
+48
pack-bitmap.c
+48
@@ -1325,10 +1325,52 @@ void count_bitmap_commit_list(struct bitmap_index *bitmap_git,
1325
struct bitmap_test_data {
1326
struct bitmap_index *bitmap_git;
1327
struct bitmap *base;
1328
+ struct bitmap *commits;
1329
+ struct bitmap *trees;
1330
+ struct bitmap *blobs;
1331
+ struct bitmap *tags;
1332
struct progress *prg;
1333
size_t seen;
1334
};
1335
1336
+static void test_bitmap_type(struct bitmap_test_data *tdata,
1337
+ struct object *obj, int pos)
1338
+{
1339
+ enum object_type bitmap_type = OBJ_NONE;
1340
+ int bitmaps_nr = 0;
1341
+
1342
+ if (bitmap_get(tdata->commits, pos)) {
1343
+ bitmap_type = OBJ_COMMIT;
1344
+ bitmaps_nr++;
1345
+ }
1346
+ if (bitmap_get(tdata->trees, pos)) {
1347
+ bitmap_type = OBJ_TREE;
1348
+ bitmaps_nr++;
1349
+ }
1350
+ if (bitmap_get(tdata->blobs, pos)) {
1351
+ bitmap_type = OBJ_BLOB;
1352
+ bitmaps_nr++;
1353
+ }
1354
+ if (bitmap_get(tdata->tags, pos)) {
1355
+ bitmap_type = OBJ_TAG;
1356
+ bitmaps_nr++;
1357
+ }
1358
+
1359
+ if (bitmap_type == OBJ_NONE)
1360
+ die("object %s not found in type bitmaps",
1361
+ oid_to_hex(&obj->oid));
1362
+
1363
+ if (bitmaps_nr > 1)
1364
+ die("object %s does not have a unique type",
1365
+ oid_to_hex(&obj->oid));
1366
+
1367
+ if (bitmap_type != obj->type)
1368
+ die("object %s: real type %s, expected: %s",
1369
+ oid_to_hex(&obj->oid),
1370
+ type_name(obj->type),
1371
+ type_name(bitmap_type));
1372
+}
1373
+
1374
static void test_show_object(struct object *object, const char *name,
1375
void *data)
1376
{
@@ -1338,6 +1380,7 @@ static void test_show_object(struct object *object, const char *name,
1380
bitmap_pos = bitmap_position(tdata->bitmap_git, &object->oid);
1381
if (bitmap_pos < 0)
1382
die("Object not in bitmap: %s\n", oid_to_hex(&object->oid));
1383
+ test_bitmap_type(tdata, object, bitmap_pos);
1384
1385
bitmap_set(tdata->base, bitmap_pos);
1386
display_progress(tdata->prg, ++tdata->seen);
@@ -1352,6 +1395,7 @@ static void test_show_commit(struct commit *commit, void *data)
1395
&commit->object.oid);
1396
if (bitmap_pos < 0)
1397
die("Object not in bitmap: %s\n", oid_to_hex(&commit->object.oid));
1398
+ test_bitmap_type(tdata, &commit->object, bitmap_pos);
1399
1400
bitmap_set(tdata->base, bitmap_pos);
1401
display_progress(tdata->prg, ++tdata->seen);
@@ -1399,6 +1443,10 @@ void test_bitmap_walk(struct rev_info *revs)
1443
1444
tdata.bitmap_git = bitmap_git;
1445
tdata.base = bitmap_new();
1446
+ tdata.commits = ewah_to_bitmap(bitmap_git->commits);
1447
+ tdata.trees = ewah_to_bitmap(bitmap_git->trees);
1448
+ tdata.blobs = ewah_to_bitmap(bitmap_git->blobs);
1449
+ tdata.tags = ewah_to_bitmap(bitmap_git->tags);
1450
tdata.prg = start_progress("Verifying bitmap entries", result_popcnt);
1451
tdata.seen = 0;
1452