Merge branch 'tb/open-midx-bitmap-fallback'

Gracefully deal with a stale MIDX file that lists a packfile that
no longer exists.

* tb/open-midx-bitmap-fallback:
  pack-bitmap.c: gracefully degrade on failure to load MIDX'd pack
This commit is contained in:
Junio C Hamano
2023-06-23 11:21:17 -07:00
2 changed files with 40 additions and 3 deletions

View File

@ -387,9 +387,11 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,
} }
for (i = 0; i < bitmap_git->midx->num_packs; i++) { for (i = 0; i < bitmap_git->midx->num_packs; i++) {
if (prepare_midx_pack(the_repository, bitmap_git->midx, i)) if (prepare_midx_pack(the_repository, bitmap_git->midx, i)) {
die(_("could not open pack %s"), warning(_("could not open pack %s"),
bitmap_git->midx->pack_names[i]); bitmap_git->midx->pack_names[i]);
goto cleanup;
}
} }
preferred = bitmap_git->midx->packs[midx_preferred_pack(bitmap_git)]; preferred = bitmap_git->midx->packs[midx_preferred_pack(bitmap_git)];

View File

@ -478,4 +478,39 @@ test_expect_success 'git fsck correctly identifies good and bad bitmaps' '
grep "bitmap file '\''$packbitmap'\'' has invalid checksum" err grep "bitmap file '\''$packbitmap'\'' has invalid checksum" err
' '
test_expect_success 'corrupt MIDX with bitmap causes fallback' '
git init corrupt-midx-bitmap &&
(
cd corrupt-midx-bitmap &&
test_commit first &&
git repack -d &&
test_commit second &&
git repack -d &&
git multi-pack-index write --bitmap &&
checksum=$(midx_checksum $objdir) &&
for f in $midx $midx-$checksum.bitmap
do
mv $f $f.bak || return 1
done &&
# pack everything together, invalidating the MIDX
git repack -ad &&
# then restore the now-stale MIDX
for f in $midx $midx-$checksum.bitmap
do
mv $f.bak $f || return 1
done &&
git rev-list --count --objects --use-bitmap-index HEAD >out 2>err &&
# should attempt opening the broken pack twice (once
# from the attempt to load it via the stale bitmap, and
# again when attempting to load it from the stale MIDX)
# before falling back to the non-MIDX case
test 2 -eq $(grep -c "could not open pack" err) &&
test 6 -eq $(cat out)
)
'
test_done test_done