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>
This commit is contained in:
Taylor Blau 2021-08-24 12:15:51 -04:00 коммит произвёл Junio C Hamano
Родитель 225bc32a98
Коммит fa95666a40
1 изменённых файлов: 48 добавлений и 0 удалений

Просмотреть файл

@ -1325,10 +1325,52 @@ void count_bitmap_commit_list(struct bitmap_index *bitmap_git,
struct bitmap_test_data {
struct bitmap_index *bitmap_git;
struct bitmap *base;
struct bitmap *commits;
struct bitmap *trees;
struct bitmap *blobs;
struct bitmap *tags;
struct progress *prg;
size_t seen;
};
static void test_bitmap_type(struct bitmap_test_data *tdata,
struct object *obj, int pos)
{
enum object_type bitmap_type = OBJ_NONE;
int bitmaps_nr = 0;
if (bitmap_get(tdata->commits, pos)) {
bitmap_type = OBJ_COMMIT;
bitmaps_nr++;
}
if (bitmap_get(tdata->trees, pos)) {
bitmap_type = OBJ_TREE;
bitmaps_nr++;
}
if (bitmap_get(tdata->blobs, pos)) {
bitmap_type = OBJ_BLOB;
bitmaps_nr++;
}
if (bitmap_get(tdata->tags, pos)) {
bitmap_type = OBJ_TAG;
bitmaps_nr++;
}
if (bitmap_type == OBJ_NONE)
die("object %s not found in type bitmaps",
oid_to_hex(&obj->oid));
if (bitmaps_nr > 1)
die("object %s does not have a unique type",
oid_to_hex(&obj->oid));
if (bitmap_type != obj->type)
die("object %s: real type %s, expected: %s",
oid_to_hex(&obj->oid),
type_name(obj->type),
type_name(bitmap_type));
}
static void test_show_object(struct object *object, const char *name,
void *data)
{
@ -1338,6 +1380,7 @@ static void test_show_object(struct object *object, const char *name,
bitmap_pos = bitmap_position(tdata->bitmap_git, &object->oid);
if (bitmap_pos < 0)
die("Object not in bitmap: %s\n", oid_to_hex(&object->oid));
test_bitmap_type(tdata, object, bitmap_pos);
bitmap_set(tdata->base, bitmap_pos);
display_progress(tdata->prg, ++tdata->seen);
@ -1352,6 +1395,7 @@ static void test_show_commit(struct commit *commit, void *data)
&commit->object.oid);
if (bitmap_pos < 0)
die("Object not in bitmap: %s\n", oid_to_hex(&commit->object.oid));
test_bitmap_type(tdata, &commit->object, bitmap_pos);
bitmap_set(tdata->base, bitmap_pos);
display_progress(tdata->prg, ++tdata->seen);
@ -1399,6 +1443,10 @@ void test_bitmap_walk(struct rev_info *revs)
tdata.bitmap_git = bitmap_git;
tdata.base = bitmap_new();
tdata.commits = ewah_to_bitmap(bitmap_git->commits);
tdata.trees = ewah_to_bitmap(bitmap_git->trees);
tdata.blobs = ewah_to_bitmap(bitmap_git->blobs);
tdata.tags = ewah_to_bitmap(bitmap_git->tags);
tdata.prg = start_progress("Verifying bitmap entries", result_popcnt);
tdata.seen = 0;