Merge branch 'pp/midx-write-skip-empty' into jch

The `git multi-pack-index write` command has been updated to
silently return success when there are no object entries to index.
This avoids writing empty `multi-pack-index` layers, which
previously caused subsequent incremental midx writes using the
`--bitmap` option to fail when attempting to load the missing
reverse index.

* pp/midx-write-skip-empty:
  midx-write: skip writes with no object entries
jch
Junio C Hamano 2026-09-21 10:04:04 -07:00
commit 2f38fa1473
4 changed files with 119 additions and 9 deletions

View File

@ -1617,9 +1617,8 @@ static int write_midx_internal(struct write_midx_opts *opts)
}

if (!ctx.entries_nr) {
if (opts->flags & MIDX_WRITE_BITMAP)
warning(_("refusing to write multi-pack .bitmap without any objects"));
opts->flags &= ~(MIDX_WRITE_REV_INDEX | MIDX_WRITE_BITMAP);
result = 0;
goto cleanup;
}

if (ctx.incremental) {

View File

@ -54,6 +54,41 @@ test_expect_success "don't write midx with no packs" '
test_path_is_missing pack/multi-pack-index
'

test_expect_success 'skip non-incremental MIDX with no objects' '
git init --bare empty.git &&
(
cd empty.git &&
git pack-objects objects/pack/pack </dev/null &&
ls objects/pack >files.expect &&

for bitmap in "" --bitmap
do
git multi-pack-index write $bitmap >out 2>&1 &&
test_must_be_empty out &&
test_path_is_missing objects/pack/multi-pack-index &&
ls objects/pack >files.actual &&
test_cmp files.expect files.actual || return 1
done &&

git multi-pack-index write --incremental --bitmap &&
test_dir_is_empty objects/pack/multi-pack-index.d &&

echo blob | git hash-object -w --stdin >in &&
git pack-objects objects/pack/pack <in &&
git multi-pack-index write --incremental --bitmap &&
test_line_count = 1 objects/pack/multi-pack-index.d/multi-pack-index-chain &&
git multi-pack-index verify &&

echo another | git hash-object -w --stdin >in &&
git pack-objects objects/pack/pack <in &&
git multi-pack-index write --bitmap &&
test_path_is_file objects/pack/multi-pack-index &&
midx="$(midx_checksum objects)" &&
test_path_is_file objects/pack/multi-pack-index-$midx.bitmap &&
git multi-pack-index verify
)
'

test_expect_success SHA1 'warn if a midx contains no oid' '
cp "$TEST_DIRECTORY"/t5319/no-objects.midx $objdir/pack/multi-pack-index &&
test_must_fail git multi-pack-index verify &&

View File

@ -305,7 +305,7 @@ test_midx_bitmap_cases () {
)
'

test_expect_success 'no .bitmap is written without any objects' '
test_expect_success 'no MIDX or .bitmap is written without any objects' '
rm -fr repo &&
git init repo &&
test_when_finished "rm -fr repo" &&
@ -318,13 +318,14 @@ test_midx_bitmap_cases () {
pack-$empty.idx
EOF

ls $objdir/pack >files.expect &&
git multi-pack-index write --bitmap --stdin-packs \
<packs 2>err &&
<packs >out 2>&1 &&

test_grep "bitmap without any objects" err &&

test_path_is_file $midx &&
test_path_is_missing $midx-$(midx_checksum $objdir).bitmap
test_must_be_empty out &&
test_path_is_missing $midx &&
ls $objdir/pack >files.actual &&
test_cmp files.expect files.actual
)
'


View File

@ -195,4 +195,79 @@ test_expect_success 'non-incremental write with existing incremental chain' '
)
'

test_expect_success 'skip initial MIDX layer with no objects' '
git init empty &&
(
cd empty &&
git config maintenance.auto false &&
git pack-objects $packdir/pack </dev/null &&

for bitmap in --bitmap --no-bitmap
do
git multi-pack-index write --incremental "$bitmap" >out 2>&1 &&
test_must_be_empty out &&
test_dir_is_empty "$midxdir" || return 1
done &&

write_midx_layer &&
test_line_count = 1 "$midx_chain" &&
git multi-pack-index verify
)
'

test_expect_success 'skip MIDX layer with empty pack' '
git init empty-pack &&
(
cd empty-pack &&
git config maintenance.auto false &&
write_midx_layer &&

git pack-objects $packdir/pack </dev/null &&
cp "$midx_chain" chain.expect &&
ls "$packdir" "$midxdir" >files.expect &&

for bitmap in --bitmap --no-bitmap
do
git multi-pack-index write --incremental "$bitmap" >out 2>&1 &&
test_must_be_empty out &&
test_cmp chain.expect "$midx_chain" &&
ls "$packdir" "$midxdir" >files.actual &&
test_cmp files.expect files.actual || return 1
done &&

write_midx_layer &&
test_line_count = 2 "$midx_chain" &&
git multi-pack-index verify &&
git rev-list --test-bitmap 2.2
)
'

test_expect_success 'skip MIDX layer with duplicate pack' '
git init duplicate-pack &&
(
cd duplicate-pack &&
git config maintenance.auto false &&
write_midx_layer &&

git rev-parse HEAD^{tree} >in &&
git pack-objects $packdir/pack <in &&
cp "$midx_chain" chain.expect &&
ls "$packdir" "$midxdir" >files.expect &&

for bitmap in --bitmap --no-bitmap
do
git multi-pack-index write --incremental "$bitmap" >out 2>&1 &&
test_must_be_empty out &&
test_cmp chain.expect "$midx_chain" &&
ls "$packdir" "$midxdir" >files.actual &&
test_cmp files.expect files.actual || return 1
done &&

write_midx_layer &&
test_line_count = 2 "$midx_chain" &&
git multi-pack-index verify &&
git rev-list --test-bitmap 2.2
)
'

test_done