builtin/cat-file: filter objects via object database

When batching all objects, git-cat-file(1) reaches into the internals of the object database and manually manages bitmaps to apply object filters. This creates coupling between the command and the internals of the respective backend. Refactor git-cat-file(1) to use the new object filter option when batching all objects. This significantly simplifies the logic and ensures that we don't have to reach into internals of the "files" source anymore. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jul 15, 2026 at 08:22 UTC bfa86e6a3a80b910f0875350d747f7a831694b18
1 file changed +7 -69
builtin/cat-file.c
+7 -69
@@ -20,7 +20,6 @@
20 #include "userdiff.h"
21 #include "oid-array.h"
22 #include "packfile.h"
23 -#include "pack-bitmap.h"
23 #include "object-file.h"
24 #include "object-name.h"
25 #include "odb.h"
@@ -844,28 +843,6 @@ static int batch_one_object_oi(const struct object_id *oid,
843 return payload->callback(oid, NULL, 0, payload->payload);
844 }
845
847 -static int batch_one_object_packed(const struct object_id *oid,
848 - struct packed_git *pack,
849 - uint32_t pos,
850 - void *_payload)
851 -{
852 - struct for_each_object_payload *payload = _payload;
853 - return payload->callback(oid, pack, nth_packed_object_offset(pack, pos),
854 - payload->payload);
855 -}
856 -
857 -static int batch_one_object_bitmapped(const struct object_id *oid,
858 - enum object_type type UNUSED,
859 - int flags UNUSED,
860 - uint32_t hash UNUSED,
861 - struct packed_git *pack,
862 - off_t offset,
863 - void *_payload)
864 -{
865 - struct for_each_object_payload *payload = _payload;
866 - return payload->callback(oid, pack, offset, payload->payload);
867 -}
868 -
846 static void batch_each_object(struct batch_options *opt,
847 for_each_object_fn callback,
848 unsigned flags,
@@ -875,56 +852,17 @@ static void batch_each_object(struct batch_options *opt,
852 .callback = callback,
853 .payload = _payload,
854 };
855 + struct odb_source_info source_info;
856 + struct object_info oi = {
857 + .source_infop = &source_info,
858 + };
859 struct odb_for_each_object_options opts = {
860 .flags = flags,
861 + .filter = &opt->objects_filter,
862 };
881 - struct bitmap_index *bitmap = NULL;
882 - struct odb_source *source;
883 -
884 - /*
885 - * TODO: we still need to tap into implementation details of the object
886 - * database sources. Ideally, we should extend `odb_for_each_object()`
887 - * to handle object filters itself so that we can move the filtering
888 - * logic into the individual sources.
889 - */
890 - odb_prepare_alternates(the_repository->objects);
891 - for (source = the_repository->objects->sources; source; source = source->next) {
892 - struct odb_source_files *files = odb_source_files_downcast(source);
893 - int ret = odb_source_for_each_object(&files->loose->base, NULL, batch_one_object_oi,
894 - &payload, &opts);
895 - if (ret)
896 - break;
897 - }
898 -
899 - if (opt->objects_filter.choice != LOFC_DISABLED &&
900 - (bitmap = prepare_bitmap_git(the_repository)) &&
901 - !for_each_bitmapped_object(bitmap, &opt->objects_filter,
902 - batch_one_object_bitmapped, &payload)) {
903 - struct packed_git *pack;
904 -
905 - repo_for_each_pack(the_repository, pack) {
906 - if (bitmap_index_contains_pack(bitmap, pack) ||
907 - open_pack_index(pack))
908 - continue;
909 - for_each_object_in_pack(pack, batch_one_object_packed,
910 - &payload, flags);
911 - }
912 - } else {
913 - struct odb_source_info source_info;
914 - struct object_info oi = {
915 - .source_infop = &source_info,
916 - };
917 -
918 - for (source = the_repository->objects->sources; source; source = source->next) {
919 - struct odb_source_files *files = odb_source_files_downcast(source);
920 - int ret = odb_source_for_each_object(&files->packed->base, &oi,
921 - batch_one_object_oi, &payload, &opts);
922 - if (ret)
923 - break;
924 - }
925 - }
863
927 - free_bitmap_index(bitmap);
864 + odb_for_each_object_ext(the_repository->objects, &oi,
865 + batch_one_object_oi, &payload, &opts);
866 }
867
868 static int batch_objects(struct batch_options *opt)