Skip to content

Commit 506ec2f

Browse files
ttaylorrpeff
authored andcommitted
midx.c: protect against disappearing packs
When a packed object is stored in a multi-pack index, but that pack has racily gone away, the MIDX code simply calls die(), when it could be returning an error to the caller, which would in turn lead to re-scanning the pack directory. A pack can racily disappear, for example, due to a simultaneous 'git repack -ad', You can also reproduce this with two terminals, where one is running: git init while true; do git commit -q --allow-empty -m foo git repack -ad git multi-pack-index write done (in effect, constantly writing new MIDXs), and the other is running: obj=$(git rev-parse HEAD) while true; do echo $obj | git cat-file --batch-check='%(objectsize:disk)' || break done That will sometimes hit the error preparing packfile from multi-pack-index message, which this patch fixes. Right now, that path to discovering a missing pack looks something like 'find_pack_entry()' calling 'fill_midx_entry()' and eventually making its way to call 'nth_midxed_pack_entry()'. 'nth_midxed_pack_entry()' already checks 'is_pack_valid()' and propagates an error if the pack is invalid. So, this works if the pack has gone away between calling 'prepare_midx_pack()' and before calling 'is_pack_valid()', but not if it disappears before then. Catch the case where the pack has already disappeared before 'prepare_midx_pack()' by returning an error in that case, too. Co-authored-by: Jeff King <[email protected]> Signed-off-by: Taylor Blau <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c8a45eb commit 506ec2f

File tree

2 files changed

+8
-2
lines changed

2 files changed

+8
-2
lines changed

midx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ static int nth_midxed_pack_entry(struct repository *r,
285285
pack_int_id = nth_midxed_pack_int_id(m, pos);
286286

287287
if (prepare_midx_pack(r, m, pack_int_id))
288-
die(_("error preparing packfile from multi-pack-index"));
288+
return 0;
289289
p = m->packs[pack_int_id];
290290

291291
/*

t/t5319-multi-pack-index.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ test_expect_success 'repack --batch-size=0 repacks everything' '
547547
)
548548
'
549549

550-
test_expect_success 'load reverse index when missing .idx' '
550+
test_expect_success 'load reverse index when missing .idx, .pack' '
551551
git init repo &&
552552
test_when_finished "rm -fr repo" &&
553553
(
@@ -560,9 +560,15 @@ test_expect_success 'load reverse index when missing .idx' '
560560
git multi-pack-index write &&
561561
562562
git rev-parse HEAD >tip &&
563+
pack=$(ls .git/objects/pack/pack-*.pack) &&
563564
idx=$(ls .git/objects/pack/pack-*.idx) &&
564565
565566
mv $idx $idx.bak &&
567+
git cat-file --batch-check="%(objectsize:disk)" <tip &&
568+
569+
mv $idx.bak $idx &&
570+
571+
mv $pack $pack.bak &&
566572
git cat-file --batch-check="%(objectsize:disk)" <tip
567573
)
568574
'

0 commit comments

Comments
 (0)