Skip to content

Commit fa95666

Browse files
ttaylorrpeff
authored andcommitted
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 <[email protected]> Signed-off-by: Jeff King <[email protected]> Signed-off-by: Taylor Blau <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 225bc32 commit fa95666

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

pack-bitmap.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,10 +1325,52 @@ void count_bitmap_commit_list(struct bitmap_index *bitmap_git,
13251325
struct bitmap_test_data {
13261326
struct bitmap_index *bitmap_git;
13271327
struct bitmap *base;
1328+
struct bitmap *commits;
1329+
struct bitmap *trees;
1330+
struct bitmap *blobs;
1331+
struct bitmap *tags;
13281332
struct progress *prg;
13291333
size_t seen;
13301334
};
13311335

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+
13321374
static void test_show_object(struct object *object, const char *name,
13331375
void *data)
13341376
{
@@ -1338,6 +1380,7 @@ static void test_show_object(struct object *object, const char *name,
13381380
bitmap_pos = bitmap_position(tdata->bitmap_git, &object->oid);
13391381
if (bitmap_pos < 0)
13401382
die("Object not in bitmap: %s\n", oid_to_hex(&object->oid));
1383+
test_bitmap_type(tdata, object, bitmap_pos);
13411384

13421385
bitmap_set(tdata->base, bitmap_pos);
13431386
display_progress(tdata->prg, ++tdata->seen);
@@ -1352,6 +1395,7 @@ static void test_show_commit(struct commit *commit, void *data)
13521395
&commit->object.oid);
13531396
if (bitmap_pos < 0)
13541397
die("Object not in bitmap: %s\n", oid_to_hex(&commit->object.oid));
1398+
test_bitmap_type(tdata, &commit->object, bitmap_pos);
13551399

13561400
bitmap_set(tdata->base, bitmap_pos);
13571401
display_progress(tdata->prg, ++tdata->seen);
@@ -1399,6 +1443,10 @@ void test_bitmap_walk(struct rev_info *revs)
13991443

14001444
tdata.bitmap_git = bitmap_git;
14011445
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);
14021450
tdata.prg = start_progress("Verifying bitmap entries", result_popcnt);
14031451
tdata.seen = 0;
14041452

0 commit comments

Comments
 (0)