pack-objects: simplify --filter handling

pack-objects uses OPT_PARSE_LIST_OBJECTS_FILTER_INIT() to initialize the a rev_info struct lazily before populating its filter member using the --filter option values. It tracks whether the initialization is needed using the .have_revs member of the callback data. There is a better way: Use a stand-alone list_objects_filter_options struct and build a rev_info struct with its .filter member after option parsing. This allows using the simpler OPT_PARSE_LIST_OBJECTS_FILTER() and getting rid of the extra callback mechanism. Even simpler would be using a struct rev_info as before 5cb28270a1 (pack-objects: lazily set up "struct rev_info", don't leak, 2022-03-28), but that would expose a memory leak caused by repo_init_revisions() followed by release_revisions() without a setup_revisions() call in between. Using list_objects_filter_options also allows pushing the rev_info struct into get_object_list(), where it arguably belongs. Either way, this is all left for later. Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Nov 29, 2022 at 13:25 UTC 0d5448a554723acfb0d8bbb131e0583504dc7230
1 file changed +6 -22
builtin/pack-objects.c
+6 -22
@@ -4149,22 +4149,6 @@ static int option_parse_cruft_expiration(const struct option *opt,
4149 return 0;
4150 }
4151
4152 -struct po_filter_data {
4153 - unsigned have_revs:1;
4154 - struct rev_info revs;
4155 -};
4156 -
4157 -static struct list_objects_filter_options *po_filter_revs_init(void *value)
4158 -{
4159 - struct po_filter_data *data = value;
4160 -
4161 - if (!data->have_revs)
4162 - repo_init_revisions(the_repository, &data->revs, NULL);
4163 - data->have_revs = 1;
4164 -
4165 - return &data->revs.filter;
4166 -}
4167 -
4152 int cmd_pack_objects(int argc, const char **argv, const char *prefix)
4153 {
4154 int use_internal_rev_list = 0;
@@ -4175,7 +4159,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
4159 int rev_list_index = 0;
4160 int stdin_packs = 0;
4161 struct string_list keep_pack_list = STRING_LIST_INIT_NODUP;
4178 - struct po_filter_data pfd = { .have_revs = 0 };
4162 + struct list_objects_filter_options filter_options =
4163 + LIST_OBJECTS_FILTER_INIT;
4164
4165 struct option pack_objects_options[] = {
4166 OPT_SET_INT('q', "quiet", &progress,
@@ -4266,7 +4251,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
4251 &write_bitmap_index,
4252 N_("write a bitmap index if possible"),
4253 WRITE_BITMAP_QUIET, PARSE_OPT_HIDDEN),
4269 - OPT_PARSE_LIST_OBJECTS_FILTER_INIT(&pfd, po_filter_revs_init),
4254 + OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
4255 OPT_CALLBACK_F(0, "missing", NULL, N_("action"),
4256 N_("handling for missing objects"), PARSE_OPT_NONEG,
4257 option_parse_missing_action),
@@ -4386,7 +4371,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
4371 if (!rev_list_all || !rev_list_reflog || !rev_list_index)
4372 unpack_unreachable_expiration = 0;
4373
4389 - if (pfd.have_revs && pfd.revs.filter.choice) {
4374 + if (filter_options.choice) {
4375 if (!pack_to_stdout)
4376 die(_("cannot use --filter without --stdout"));
4377 if (stdin_packs)
@@ -4473,13 +4458,11 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
4458 read_cruft_objects();
4459 } else if (!use_internal_rev_list) {
4460 read_object_list_from_stdin();
4476 - } else if (pfd.have_revs) {
4477 - get_object_list(&pfd.revs, rp.nr, rp.v);
4478 - release_revisions(&pfd.revs);
4461 } else {
4462 struct rev_info revs;
4463
4464 repo_init_revisions(the_repository, &revs, NULL);
4465 + list_objects_filter_copy(&revs.filter, &filter_options);
4466 get_object_list(&revs, rp.nr, rp.v);
4467 release_revisions(&revs);
4468 }
@@ -4514,6 +4497,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
4497 reuse_packfile_objects);
4498
4499 cleanup:
4500 + list_objects_filter_release(&filter_options);
4501 strvec_clear(&rp);
4502
4503 return 0;