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
index 7cebd0cb45..2408b8a3cc 100644
--- a/repack-geometry.c
+++ b/repack-geometry.c
@@ -4,6 +4,7 @@
#include "repack.h"
#include "repository.h"
#include "hex.h"
+#include "midx.h"
#include "packfile.h"
static uint32_t pack_geometry_weight(struct packed_git *p)
@@ -31,8 +32,28 @@ void pack_geometry_init(struct pack_geometry *geometry,
{
struct packed_git *p;
struct strbuf buf = STRBUF_INIT;
+ struct multi_pack_index *m = get_multi_pack_index(existing->source);
repo_for_each_pack(existing->repo, p) {
+ if (geometry->midx_layer_threshold_set && m &&
+ p->multi_pack_index) {
+ /*
+ * When writing MIDX layers incrementally,
+ * ignore packs unless they are in the most
+ * recent MIDX layer *and* there are at least
+ * 'midx_layer_threshold' packs in that layer.
+ *
+ * Otherwise 'p' is either in an older layer, or
+ * the youngest layer does not have enough packs
+ * to consider its packs as candidates for
+ * repacking. In either of those cases we want
+ * to ignore the pack.
+ */
+ if (m->num_packs < geometry->midx_layer_threshold ||
+ !midx_layer_contains_pack(m, pack_basename(p)))
+ continue;
+ }
+
if (args->local && !p->pack_local)
/*
* When asked to only repack local packfiles we skip
@@ -173,6 +194,20 @@ void pack_geometry_split(struct pack_geometry *geometry)
geometry->promisor_split = compute_pack_geometry_split(geometry->promisor_pack,
geometry->promisor_pack_nr,
geometry->split_factor);
+ for (uint32_t i = 0; i < geometry->split; i++) {
+ struct packed_git *p = geometry->pack[i];
+ /*
+ * During incremental MIDX/bitmap repacking, any packs
+ * included in the rollup are either (a) not MIDX'd, or
+ * (b) contained in the tip layer iff it has at least
+ * the threshold number of packs.
+ *
+ * In the latter case, we can safely conclude that the
+ * tip of the MIDX chain will be rewritten.
+ */
+ if (p->multi_pack_index)
+ geometry->midx_tip_rewritten = true;
+ }
}
struct packed_git *pack_geometry_preferred_pack(struct pack_geometry *geometry)
repack.h
+4
index c0e9f0ca64..77d24ee45f 100644
--- a/repack.h
+++ b/repack.h
@@ -108,6 +108,10 @@ struct pack_geometry {
uint32_t promisor_pack_nr, promisor_pack_alloc;
uint32_t promisor_split;
+ uint32_t midx_layer_threshold;
+ bool midx_layer_threshold_set;
+ bool midx_tip_rewritten;
+
int split_factor;
};