pack-bitmap: implement object type filter

The preceding commit has added a new object filter for git-rev-list(1) which allows to filter objects by type. Implement the equivalent filter for packfile bitmaps so that we can answer these queries fast. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Apr 19, 2021 at 13:46 UTC 7ab6aafa582b9c537885d4a6ef2c837323c5014d
2 files changed +50 -4
pack-bitmap.c
+26 -3
@@ -779,9 +779,6 @@ static void filter_bitmap_exclude_type(struct bitmap_index *bitmap_git,
779 eword_t mask;
780 uint32_t i;
781
782 - if (type != OBJ_BLOB && type != OBJ_TREE)
783 - BUG("filter_bitmap_exclude_type: unsupported type '%d'", type);
784 -
782 /*
783 * The non-bitmap version of this filter never removes
784 * objects which the other side specifically asked for,
@@ -911,6 +908,24 @@ static void filter_bitmap_tree_depth(struct bitmap_index *bitmap_git,
908 OBJ_BLOB);
909 }
910
911 +static void filter_bitmap_object_type(struct bitmap_index *bitmap_git,
912 + struct object_list *tip_objects,
913 + struct bitmap *to_filter,
914 + enum object_type object_type)
915 +{
916 + if (object_type < OBJ_COMMIT || object_type > OBJ_TAG)
917 + BUG("filter_bitmap_object_type given invalid object");
918 +
919 + if (object_type != OBJ_TAG)
920 + filter_bitmap_exclude_type(bitmap_git, tip_objects, to_filter, OBJ_TAG);
921 + if (object_type != OBJ_COMMIT)
922 + filter_bitmap_exclude_type(bitmap_git, tip_objects, to_filter, OBJ_COMMIT);
923 + if (object_type != OBJ_TREE)
924 + filter_bitmap_exclude_type(bitmap_git, tip_objects, to_filter, OBJ_TREE);
925 + if (object_type != OBJ_BLOB)
926 + filter_bitmap_exclude_type(bitmap_git, tip_objects, to_filter, OBJ_BLOB);
927 +}
928 +
929 static int filter_bitmap(struct bitmap_index *bitmap_git,
930 struct object_list *tip_objects,
931 struct bitmap *to_filter,
@@ -943,6 +958,14 @@ static int filter_bitmap(struct bitmap_index *bitmap_git,
958 return 0;
959 }
960
961 + if (filter->choice == LOFC_OBJECT_TYPE) {
962 + if (bitmap_git)
963 + filter_bitmap_object_type(bitmap_git, tip_objects,
964 + to_filter,
965 + filter->object_type);
966 + return 0;
967 + }
968 +
969 /* filter choice not handled */
970 return -1;
971 }
t/t6113-rev-list-bitmap-filters.sh
+24 -1
@@ -10,7 +10,8 @@ test_expect_success 'set up bitmapped repo' '
10 test_commit much-larger-blob-one &&
11 git repack -adb &&
12 test_commit two &&
13 - test_commit much-larger-blob-two
13 + test_commit much-larger-blob-two &&
14 + git tag tag
15 '
16
17 test_expect_success 'filters fallback to non-bitmap traversal' '
@@ -75,4 +76,26 @@ test_expect_success 'tree:1 filter' '
76 test_cmp expect actual
77 '
78
79 +test_expect_success 'object:type filter' '
80 + git rev-list --objects --filter=object:type=tag tag >expect &&
81 + git rev-list --use-bitmap-index \
82 + --objects --filter=object:type=tag tag >actual &&
83 + test_cmp expect actual &&
84 +
85 + git rev-list --objects --filter=object:type=commit tag >expect &&
86 + git rev-list --use-bitmap-index \
87 + --objects --filter=object:type=commit tag >actual &&
88 + test_bitmap_traversal expect actual &&
89 +
90 + git rev-list --objects --filter=object:type=tree tag >expect &&
91 + git rev-list --use-bitmap-index \
92 + --objects --filter=object:type=tree tag >actual &&
93 + test_bitmap_traversal expect actual &&
94 +
95 + git rev-list --objects --filter=object:type=blob tag >expect &&
96 + git rev-list --use-bitmap-index \
97 + --objects --filter=object:type=blob tag >actual &&
98 + test_bitmap_traversal expect actual
99 +'
100 +
101 test_done