pack-bitmap: deduplicate logic to iterate over preferred bitmap tips

We have two locations that iterate over the preferred bitmap tips as configured by the user via "pack.preferBitmapTips". Both of these callsites are subtly wrong: when the preferred bitmap tips contain an exact refname match, then we will hit a `BUG()`. Prepare for the fix by unifying the two callsites into a new `for_each_preferred_bitmap_tip()` function. This removes the last callsite of `bitmap_preferred_tips()` outside of "pack-bitmap.c". As such, convert the function to be local to that file only. Note that the function is still used by a second caller, so we cannot just inline it. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Feb 19, 2026 at 08:57 UTC ed693078e988adf66c969feb6de9f83c7abe7d24
4 files changed +30 -30
builtin/pack-objects.c
+2 -17
@@ -4554,22 +4554,6 @@ static int mark_bitmap_preferred_tip(const struct reference *ref, void *data UNU
4554 return 0;
4555 }
4556
4557 -static void mark_bitmap_preferred_tips(void)
4558 -{
4559 - struct string_list_item *item;
4560 - const struct string_list *preferred_tips;
4561 -
4562 - preferred_tips = bitmap_preferred_tips(the_repository);
4563 - if (!preferred_tips)
4564 - return;
4565 -
4566 - for_each_string_list_item(item, preferred_tips) {
4567 - refs_for_each_ref_in(get_main_ref_store(the_repository),
4568 - item->string, mark_bitmap_preferred_tip,
4569 - NULL);
4570 - }
4571 -}
4572 -
4557 static inline int is_oid_uninteresting(struct repository *repo,
4558 struct object_id *oid)
4559 {
@@ -4710,7 +4694,8 @@ static void get_object_list(struct rev_info *revs, struct strvec *argv)
4694 load_delta_islands(the_repository, progress);
4695
4696 if (write_bitmap_index)
4713 - mark_bitmap_preferred_tips();
4697 + for_each_preferred_bitmap_tip(the_repository, mark_bitmap_preferred_tip,
4698 + NULL);
4699
4700 if (!fn_show_object)
4701 fn_show_object = show_object;
pack-bitmap.c
+17 -1
@@ -3314,7 +3314,7 @@ int bitmap_is_midx(struct bitmap_index *bitmap_git)
3314 return !!bitmap_git->midx;
3315 }
3316
3317 -const struct string_list *bitmap_preferred_tips(struct repository *r)
3317 +static const struct string_list *bitmap_preferred_tips(struct repository *r)
3318 {
3319 const struct string_list *dest;
3320
@@ -3323,6 +3323,22 @@ const struct string_list *bitmap_preferred_tips(struct repository *r)
3323 return NULL;
3324 }
3325
3326 +void for_each_preferred_bitmap_tip(struct repository *repo,
3327 + each_ref_fn cb, void *cb_data)
3328 +{
3329 + struct string_list_item *item;
3330 + const struct string_list *preferred_tips;
3331 +
3332 + preferred_tips = bitmap_preferred_tips(repo);
3333 + if (!preferred_tips)
3334 + return;
3335 +
3336 + for_each_string_list_item(item, preferred_tips) {
3337 + refs_for_each_ref_in(get_main_ref_store(repo),
3338 + item->string, cb, cb_data);
3339 + }
3340 +}
3341 +
3342 int bitmap_is_preferred_refname(struct repository *r, const char *refname)
3343 {
3344 const struct string_list *preferred_tips = bitmap_preferred_tips(r);
pack-bitmap.h
+8 -1
@@ -5,6 +5,7 @@
5 #include "khash.h"
6 #include "pack.h"
7 #include "pack-objects.h"
8 +#include "refs.h"
9 #include "string-list.h"
10
11 struct commit;
@@ -99,6 +100,13 @@ int for_each_bitmapped_object(struct bitmap_index *bitmap_git,
100 show_reachable_fn show_reach,
101 void *payload);
102
103 +/*
104 + * Iterate over all references that are configured as preferred bitmap tips via
105 + * "pack.preferBitmapTips" and invoke the callback on each function.
106 + */
107 +void for_each_preferred_bitmap_tip(struct repository *repo,
108 + each_ref_fn cb, void *cb_data);
109 +
110 #define GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL \
111 "GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL"
112
@@ -182,7 +190,6 @@ char *pack_bitmap_filename(struct packed_git *p);
190
191 int bitmap_is_midx(struct bitmap_index *bitmap_git);
192
185 -const struct string_list *bitmap_preferred_tips(struct repository *r);
193 int bitmap_is_preferred_refname(struct repository *r, const char *refname);
194
195 int verify_bitmap_files(struct repository *r);
repack-midx.c
+3 -11
@@ -40,7 +40,6 @@ static int midx_snapshot_ref_one(const struct reference *ref, void *_data)
40 void midx_snapshot_refs(struct repository *repo, struct tempfile *f)
41 {
42 struct midx_snapshot_ref_data data;
43 - const struct string_list *preferred = bitmap_preferred_tips(repo);
43
44 data.repo = repo;
45 data.f = f;
@@ -51,16 +50,9 @@ void midx_snapshot_refs(struct repository *repo, struct tempfile *f)
50 die(_("could not open tempfile %s for writing"),
51 get_tempfile_path(f));
52
54 - if (preferred) {
55 - struct string_list_item *item;
56 -
57 - data.preferred = 1;
58 - for_each_string_list_item(item, preferred)
59 - refs_for_each_ref_in(get_main_ref_store(repo),
60 - item->string,
61 - midx_snapshot_ref_one, &data);
62 - data.preferred = 0;
63 - }
53 + data.preferred = 1;
54 + for_each_preferred_bitmap_tip(repo, midx_snapshot_ref_one, &data);
55 + data.preferred = 0;
56
57 refs_for_each_ref(get_main_ref_store(repo),
58 midx_snapshot_ref_one, &data);