packfile: refactor `get_multi_pack_index()` to work on sources
The function `get_multi_pack_index()` loads multi-pack indices via `prepare_packed_git()` and then returns the linked list of multi-pack indices that is stored in `struct object_database`. That list is in the process of being removed though in favor of storing the MIDX as part of the object database source it belongs to. Refactor `get_multi_pack_index()` so that it returns the multi-pack index for a single object source. Callers are now expected to call this function for each source they are interested in. This requires them to iterate through alternates, so we have to prepare alternate object sources before doing so. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Jul 15, 2025 at 13:29 UTC
736bb725ebcd37d567455db2ac50524dea11223c
7 files changed
+57
-62
builtin/pack-objects.c
+7
-3
@@ -1706,8 +1706,8 @@ static int want_object_in_pack_mtime(const struct object_id *oid,
1706
uint32_t found_mtime)
1707
{
1708
int want;
1709
+ struct odb_source *source;
1710
struct list_head *pos;
1710
- struct multi_pack_index *m;
1711
1712
if (!exclude && local && has_loose_object_nonlocal(oid))
1713
return 0;
@@ -1727,9 +1727,13 @@ static int want_object_in_pack_mtime(const struct object_id *oid,
1727
*found_offset = 0;
1728
}
1729
1730
- for (m = get_multi_pack_index(the_repository); m; m = m->next) {
1730
+ odb_prepare_alternates(the_repository->objects);
1731
+
1732
+ for (source = the_repository->objects->sources; source; source = source->next) {
1733
+ struct multi_pack_index *m = get_multi_pack_index(source);
1734
struct pack_entry e;
1732
- if (fill_midx_entry(the_repository, oid, &e, m)) {
1735
+
1736
+ if (m && fill_midx_entry(the_repository, oid, &e, m)) {
1737
want = want_object_in_pack_one(e.p, oid, exclude, found_pack, found_offset, found_mtime);
1738
if (want != -1)
1739
return want;
builtin/repack.c
+5
-5
@@ -223,9 +223,9 @@ static void mark_packs_for_deletion(struct existing_packs *existing,
223
static void remove_redundant_pack(const char *dir_name, const char *base_name)
224
{
225
struct strbuf buf = STRBUF_INIT;
226
- struct multi_pack_index *m = get_local_multi_pack_index(the_repository);
226
+ struct multi_pack_index *m = get_multi_pack_index(the_repository->objects->sources);
227
strbuf_addf(&buf, "%s.pack", base_name);
228
- if (m && midx_contains_pack(m, buf.buf))
228
+ if (m && m->local && midx_contains_pack(m, buf.buf))
229
clear_midx_file(the_repository);
230
strbuf_insertf(&buf, 0, "%s/", dir_name);
231
unlink_pack_path(buf.buf, 1);
@@ -1531,7 +1531,7 @@ int cmd_repack(int argc,
1531
* midx_has_unknown_packs() will make the decision for
1532
* us.
1533
*/
1534
- if (!get_local_multi_pack_index(the_repository))
1534
+ if (!get_multi_pack_index(the_repository->objects->sources))
1535
midx_must_contain_cruft = 1;
1536
}
1537
@@ -1614,9 +1614,9 @@ int cmd_repack(int argc,
1614
1615
string_list_sort(&names);
1616
1617
- if (get_local_multi_pack_index(the_repository)) {
1617
+ if (get_multi_pack_index(the_repository->objects->sources)) {
1618
struct multi_pack_index *m =
1619
- get_local_multi_pack_index(the_repository);
1619
+ get_multi_pack_index(the_repository->objects->sources);
1620
1621
ALLOC_ARRAY(midx_pack_names,
1622
m->num_packs + m->num_packs_in_base);
midx-write.c
+2
-20
@@ -916,26 +916,8 @@ cleanup:
916
static struct multi_pack_index *lookup_multi_pack_index(struct repository *r,
917
const char *object_dir)
918
{
919
- struct multi_pack_index *result = NULL;
920
- struct multi_pack_index *cur;
921
- char *obj_dir_real = real_pathdup(object_dir, 1);
922
- struct strbuf cur_path_real = STRBUF_INIT;
923
-
924
- /* Ensure the given object_dir is local, or a known alternate. */
925
- odb_find_source(r->objects, obj_dir_real);
926
-
927
- for (cur = get_multi_pack_index(r); cur; cur = cur->next) {
928
- strbuf_realpath(&cur_path_real, cur->object_dir, 1);
929
- if (!strcmp(obj_dir_real, cur_path_real.buf)) {
930
- result = cur;
931
- goto cleanup;
932
- }
933
- }
934
-
935
-cleanup:
936
- free(obj_dir_real);
937
- strbuf_release(&cur_path_real);
938
- return result;
919
+ struct odb_source *source = odb_find_source(r->objects, object_dir);
920
+ return get_multi_pack_index(source);
921
}
922
923
static int fill_packs_from_midx(struct write_midx_context *ctx,
object-name.c
+15
-7
@@ -198,16 +198,20 @@ static void unique_in_pack(struct packed_git *p,
198
199
static void find_short_packed_object(struct disambiguate_state *ds)
200
{
201
- struct multi_pack_index *m;
201
+ struct odb_source *source;
202
struct packed_git *p;
203
204
/* Skip, unless oids from the storage hash algorithm are wanted */
205
if (ds->bin_pfx.algo && (&hash_algos[ds->bin_pfx.algo] != ds->repo->hash_algo))
206
return;
207
208
- for (m = get_multi_pack_index(ds->repo); m && !ds->ambiguous;
209
- m = m->next)
210
- unique_in_midx(m, ds);
208
+ odb_prepare_alternates(ds->repo->objects);
209
+ for (source = ds->repo->objects->sources; source && !ds->ambiguous; source = source->next) {
210
+ struct multi_pack_index *m = get_multi_pack_index(source);
211
+ if (m)
212
+ unique_in_midx(m, ds);
213
+ }
214
+
215
for (p = get_packed_git(ds->repo); p && !ds->ambiguous;
216
p = p->next)
217
unique_in_pack(p, ds);
@@ -792,11 +796,15 @@ static void find_abbrev_len_for_pack(struct packed_git *p,
796
797
static void find_abbrev_len_packed(struct min_abbrev_data *mad)
798
{
795
- struct multi_pack_index *m;
799
struct packed_git *p;
800
798
- for (m = get_multi_pack_index(mad->repo); m; m = m->next)
799
- find_abbrev_len_for_midx(m, mad);
801
+ odb_prepare_alternates(mad->repo->objects);
802
+ for (struct odb_source *source = mad->repo->objects->sources; source; source = source->next) {
803
+ struct multi_pack_index *m = get_multi_pack_index(source);
804
+ if (m)
805
+ find_abbrev_len_for_midx(m, mad);
806
+ }
807
+
808
for (p = get_packed_git(mad->repo); p; p = p->next)
809
find_abbrev_len_for_pack(p, mad);
810
}
pack-bitmap.c
+15
-6
@@ -691,13 +691,15 @@ static int open_pack_bitmap(struct repository *r,
691
static int open_midx_bitmap(struct repository *r,
692
struct bitmap_index *bitmap_git)
693
{
694
+ struct odb_source *source;
695
int ret = -1;
695
- struct multi_pack_index *midx;
696
697
assert(!bitmap_git->map);
698
699
- for (midx = get_multi_pack_index(r); midx; midx = midx->next) {
700
- if (!open_midx_bitmap_1(bitmap_git, midx))
699
+ odb_prepare_alternates(r->objects);
700
+ for (source = r->objects->sources; source; source = source->next) {
701
+ struct multi_pack_index *midx = get_multi_pack_index(source);
702
+ if (midx && !open_midx_bitmap_1(bitmap_git, midx))
703
ret = 0;
704
}
705
return ret;
@@ -3305,11 +3307,18 @@ static int verify_bitmap_file(const struct git_hash_algo *algop,
3307
3308
int verify_bitmap_files(struct repository *r)
3309
{
3310
+ struct odb_source *source;
3311
int res = 0;
3312
3310
- for (struct multi_pack_index *m = get_multi_pack_index(r);
3311
- m; m = m->next) {
3312
- char *midx_bitmap_name = midx_bitmap_filename(m);
3313
+ odb_prepare_alternates(r->objects);
3314
+ for (source = r->objects->sources; source; source = source->next) {
3315
+ struct multi_pack_index *m = get_multi_pack_index(source);
3316
+ char *midx_bitmap_name;
3317
+
3318
+ if (!m)
3319
+ continue;
3320
+
3321
+ midx_bitmap_name = midx_bitmap_filename(m);
3322
res |= verify_bitmap_file(r->hash_algo, midx_bitmap_name);
3323
free(midx_bitmap_name);
3324
}
packfile.c
+12
-19
@@ -963,14 +963,18 @@ static void prepare_packed_git(struct repository *r);
963
unsigned long repo_approximate_object_count(struct repository *r)
964
{
965
if (!r->objects->approximate_object_count_valid) {
966
- unsigned long count;
967
- struct multi_pack_index *m;
966
+ struct odb_source *source;
967
+ unsigned long count = 0;
968
struct packed_git *p;
969
970
prepare_packed_git(r);
971
- count = 0;
972
- for (m = get_multi_pack_index(r); m; m = m->next)
973
- count += m->num_objects;
971
+
972
+ for (source = r->objects->sources; source; source = source->next) {
973
+ struct multi_pack_index *m = get_multi_pack_index(source);
974
+ if (m)
975
+ count += m->num_objects;
976
+ }
977
+
978
for (p = r->objects->packed_git; p; p = p->next) {
979
if (open_pack_index(p))
980
continue;
@@ -1074,21 +1078,10 @@ struct packed_git *get_packed_git(struct repository *r)
1078
return r->objects->packed_git;
1079
}
1080
1077
-struct multi_pack_index *get_multi_pack_index(struct repository *r)
1078
-{
1079
- prepare_packed_git(r);
1080
- return r->objects->multi_pack_index;
1081
-}
1082
-
1083
-struct multi_pack_index *get_local_multi_pack_index(struct repository *r)
1081
+struct multi_pack_index *get_multi_pack_index(struct odb_source *source)
1082
{
1085
- struct multi_pack_index *m = get_multi_pack_index(r);
1086
-
1087
- /* no need to iterate; we always put the local one first (if any) */
1088
- if (m && m->local)
1089
- return m;
1090
-
1091
- return NULL;
1083
+ prepare_packed_git(source->odb->repo);
1084
+ return source->midx;
1085
}
1086
1087
struct packed_git *get_all_packs(struct repository *r)
packfile.h
+1
-2
@@ -147,8 +147,7 @@ void install_packed_git(struct repository *r, struct packed_git *pack);
147
148
struct packed_git *get_packed_git(struct repository *r);
149
struct list_head *get_packed_git_mru(struct repository *r);
150
-struct multi_pack_index *get_multi_pack_index(struct repository *r);
151
-struct multi_pack_index *get_local_multi_pack_index(struct repository *r);
150
+struct multi_pack_index *get_multi_pack_index(struct odb_source *source);
151
struct packed_git *get_all_packs(struct repository *r);
152
153
/*