[PATCH v2 3/8] repack: retain cruft packs in MIDXs after incremental repacks
HOTtoday
From: Taylor Blau <hidden>
Date: 2026-10-01 04:11:47
Subsystem:
the rest · Maintainer:
Linus Torvalds
An incremental repack can write a commit and tree into a new pack while leaving objects they reach in an existing cruft pack. For example, a commit can make a previously unreachable blob reachable again. Since 'repack' will invoke 'pack-objects' with '--incremental', it will not copy the blob out of its cruft pack. When the 'repack.midxMustContainCruft' configuration is set to "false", writing the first MIDX after such a repack may omit that cruft pack. The new pack bypasses the `!names.nr` fallback, and there are no previous MIDX packs for `midx_has_unknown_packs()` to check. Selecting the new commit for bitmap coverage then fails because its reachable objects are not all in the MIDX. The omission dates all the way back to 5ee86c273bf (repack: exclude cruft pack(s) from the MIDX where possible, 2025-06-23). It relies on geometric repacking to copy once-cruft objects with '--stdin-packs=follow'. However, an ordinary incremental repack makes no such guarantee. Require the MIDX to include cruft packs in that case, even when a new pack was written. This fixes ordinary '--write-midx'. The separate '--write-midx=incremental' writer does not consult this flag and needs its own handling. Exercise this with the existing fixture that makes a cruft commit reachable again and adds a new (unpacked) commit on top, and ensure that the incremental repack is able to successfully write a reachability bitmap. Signed-off-by: Taylor Blau <redacted> --- builtin/repack.c | 6 ++++++ t/t7704-repack-cruft.sh | 11 +++++++++++ 2 files changed, 17 insertions(+)
diff --git a/builtin/repack.c b/builtin/repack.c
index c4360382c1f..b7596d488da 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c@@ -539,6 +539,12 @@ int cmd_repack(int argc, strvec_push(&cmd.args, "--stdin-packs=follow"); strvec_push(&cmd.args, "--unpacked"); } else { + /* + * Incremental repacks do not copy already-packed objects, + * so cruft packs may be required to form a reachability + * closure for the MIDX. + */ + midx_must_contain_cruft = 1; strvec_push(&cmd.args, "--unpacked"); strvec_push(&cmd.args, "--incremental"); }
diff --git a/t/t7704-repack-cruft.sh b/t/t7704-repack-cruft.sh
index b49f22878f7..f7f83e70ffe 100755
--- a/t/t7704-repack-cruft.sh
+++ b/t/t7704-repack-cruft.sh@@ -787,6 +787,17 @@ test_expect_success 'geometric repack rescues descendants of loose trees' ' ) ' +test_expect_success 'incremental repack includes cruft for MIDX bitmaps' ' + setup_cruft_exclude_tests incremental-cruft && + ( + cd incremental-cruft && + + GIT_TEST_MULTI_PACK_INDEX=0 \ + git repack -d --write-midx --write-bitmap-index && + git rev-list --test-bitmap HEAD + ) +' + test_expect_success 'repack --write-midx includes cruft when instructed' ' setup_cruft_exclude_tests exclude-cruft-when-instructed && (
--
2.56.0.8.ga42f775cbe2