Skip to content

Commit 9ad29df

Browse files
ttaylorrgitster
authored andcommitted
repack: mark non-MIDX packs above the split as excluded-open
In 5ee86c2 (repack: exclude cruft pack(s) from the MIDX where possible, 2025-06-23), geometric repacking learned to exclude cruft packs from the MIDX when 'repack.midxMustContainCruft' is set to 'false'. This works because packs generated with '--stdin-packs=follow' rescue any once-unreachable objects that later become reachable, making the resulting packs closed under reachability without needing the cruft pack in the MIDX. However, packs above the geometric split that were not part of the previous MIDX may not have full object closure. When such packs are marked as excluded-closed ('^'), pack-objects treats them as a reachability boundary and does not traverse through them during the follow pass, potentially leaving the resulting pack without full closure. Fix this by marking packs above the geometric split that were not in the previous MIDX as excluded-open ('!') instead of excluded-closed ('^'). This causes pack-objects to walk through their commits during the follow pass, rescuing any reachable objects not present in the closed-excluded packs. Note that MIDXs which were generated prior to this change and are unlucky enough to not be closed under reachability may still exhibit this bug, as we treat all MIDX'd packs as closed. That is true in an overwhelming number of cases, since in order to have a non-closed MIDX you would have to: - Generate a pack via an earlier geometric repack that is not closed under reachability. - Store that pack in the MIDX. - Avoid picking any commits to receive reachability bitmaps which happen to reach objects from which the missing objects are reachable. In the extremely rare chance that all of the above should happen, an all-into-one repack will resolve the issue. Unfortunately, there is no perfect way to determine whether a MIDX'd pack is closed outside of ensuring that there is a '1' bit in at least one bitmap for every bit position corresponding to objects in that pack. While this is possible to do, this approach would treat MIDX'd packs as open in cases where there is at least one object that is not reachable from the subset of commits selected for bitmapping. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 3f7c0e7 commit 9ad29df

2 files changed

Lines changed: 18 additions & 3 deletions

File tree

builtin/repack.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,23 @@ int cmd_repack(int argc,
369369
*/
370370
for (i = 0; i < geometry.split; i++)
371371
fprintf(in, "%s\n", pack_basename(geometry.pack[i]));
372-
for (i = geometry.split; i < geometry.pack_nr; i++)
373-
fprintf(in, "^%s\n", pack_basename(geometry.pack[i]));
372+
for (i = geometry.split; i < geometry.pack_nr; i++) {
373+
const char *basename = pack_basename(geometry.pack[i]);
374+
char marker = '^';
375+
376+
if (!midx_must_contain_cruft &&
377+
!string_list_has_string(&existing.midx_packs,
378+
basename)) {
379+
/*
380+
* Assume non-MIDX'd packs are not
381+
* necessarily closed under
382+
* reachability.
383+
*/
384+
marker = '!';
385+
}
386+
387+
fprintf(in, "%c%s\n", marker, basename);
388+
}
374389
fclose(in);
375390
}
376391

t/t7704-repack-cruft.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,7 @@ test_expect_success 'repack --write-midx includes cruft when already geometric'
869869
)
870870
'
871871

872-
test_expect_failure 'repack rescues once-cruft objects above geometric split' '
872+
test_expect_success 'repack rescues once-cruft objects above geometric split' '
873873
git config repack.midxMustContainCruft false &&
874874
875875
test_commit reachable &&

0 commit comments

Comments
 (0)