repack-geometry: prepare for incremental MIDX repacking
Teach `pack_geometry_init()` to optionally restrict the set of repacking candidates to only packs in the tip MIDX layer when a `midx_layer_threshold` is configured. If the tip layer has fewer packs than the threshold, those packs are excluded entirely; otherwise only packs in that layer participate in the geometric repack. Also track whether any tip-layer packs were included in the rollup (`midx_tip_rewritten`), which a subsequent commit will use to decide how to update the MIDX chain after repacking. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Taylor Blau committed
May 19, 2026 at 11:58 UTC
d0ac3969f4b8a859d23c9f45cab873cbbf8cdfb8
2 files changed
+39
repack-geometry.c
+35
@@ -4,6 +4,7 @@
4
#include "repack.h"
5
#include "repository.h"
6
#include "hex.h"
7
+#include "midx.h"
8
#include "packfile.h"
9
10
static uint32_t pack_geometry_weight(struct packed_git *p)
@@ -31,8 +32,28 @@ void pack_geometry_init(struct pack_geometry *geometry,
32
{
33
struct packed_git *p;
34
struct strbuf buf = STRBUF_INIT;
35
+ struct multi_pack_index *m = get_multi_pack_index(existing->source);
36
37
repo_for_each_pack(existing->repo, p) {
38
+ if (geometry->midx_layer_threshold_set && m &&
39
+ p->multi_pack_index) {
40
+ /*
41
+ * When writing MIDX layers incrementally,
42
+ * ignore packs unless they are in the most
43
+ * recent MIDX layer *and* there are at least
44
+ * 'midx_layer_threshold' packs in that layer.
45
+ *
46
+ * Otherwise 'p' is either in an older layer, or
47
+ * the youngest layer does not have enough packs
48
+ * to consider its packs as candidates for
49
+ * repacking. In either of those cases we want
50
+ * to ignore the pack.
51
+ */
52
+ if (m->num_packs < geometry->midx_layer_threshold ||
53
+ !midx_layer_contains_pack(m, pack_basename(p)))
54
+ continue;
55
+ }
56
+
57
if (args->local && !p->pack_local)
58
/*
59
* When asked to only repack local packfiles we skip
@@ -173,6 +194,20 @@ void pack_geometry_split(struct pack_geometry *geometry)
194
geometry->promisor_split = compute_pack_geometry_split(geometry->promisor_pack,
195
geometry->promisor_pack_nr,
196
geometry->split_factor);
197
+ for (uint32_t i = 0; i < geometry->split; i++) {
198
+ struct packed_git *p = geometry->pack[i];
199
+ /*
200
+ * During incremental MIDX/bitmap repacking, any packs
201
+ * included in the rollup are either (a) not MIDX'd, or
202
+ * (b) contained in the tip layer iff it has at least
203
+ * the threshold number of packs.
204
+ *
205
+ * In the latter case, we can safely conclude that the
206
+ * tip of the MIDX chain will be rewritten.
207
+ */
208
+ if (p->multi_pack_index)
209
+ geometry->midx_tip_rewritten = true;
210
+ }
211
}
212
213
struct packed_git *pack_geometry_preferred_pack(struct pack_geometry *geometry)
repack.h
+4
@@ -108,6 +108,10 @@ struct pack_geometry {
108
uint32_t promisor_pack_nr, promisor_pack_alloc;
109
uint32_t promisor_split;
110
111
+ uint32_t midx_layer_threshold;
112
+ bool midx_layer_threshold_set;
113
+ bool midx_tip_rewritten;
114
+
115
int split_factor;
116
};
117