From: Pia Park Date: Thu, 29 Oct 2026 08:26:17 GMT Subject: [PATCH v3] midx-write: skip writes with no object entries Message-ID: <97eca05600afc5828e3f27c6fcfd3f7872ca326b.1793260625.git.pia@pierre.co> In-Reply-To: A MIDX write can find packs without finding any objects, either because the packs are empty or because an incremental write finds only objects already indexed by an earlier layer. The existing early exit checks only the number of packs, so these cases publish a zero-object MIDX without a reverse index. Empty MIDXs were already published by 662148c435 (midx: write object offsets, 2018-07-12); the failure mode appeared in 27afc272c4 (midx: implement writing incremental MIDX bitmaps, 2025-03-20), when incremental bitmap writes began loading reverse indexes from prior layers. Reproducible on master as of b8242b093d (The 23rd batch, 2026-09-07), starting with a non-incremental write: git init --bare --object-format=sha1 empty.git && ( cd empty.git && git pack-objects objects/pack/pack --- The implementation is unchanged from v2. I held off on the preparatory patch to return success when no packs are present because it raises the question of what to do with an existing MIDX, discussed below. Changes since v2: * Simplify the tests as Taylor suggested: drop directory listings, output checks, and subsequent writes already covered elsewhere. * Rename the initial-layer test to make its empty pack explicit, and distinguish the intermediate-layer tests from it. * Add cleanup for the bare repository created by the new t5319 test. * Update the commit message's description of the tests. The initial-layer test does contain a pack: "git pack-objects" with empty input writes a pack containing zero objects. There is also a related question about existing MIDX files. With a non-incremental --stdin-packs write selecting an empty pack, this patch returns success and preserves the old MIDX. If its packs were deleted, verification still reports those missing packs. I reproduced this on the patched build. An empty --stdin-packs list also preserves the old MIDX, but continues to report the existing no-pack-files error. If we make the no-packs case return success too, should an empty non-incremental replacement remove the existing MIDX and its associated files? That cleanup question also applies to the empty-pack case above. Incremental writes would still need to preserve their existing chain. I've left both the no-packs status change and removal of existing MIDX files out of this version; would you prefer to address them separately? All 885 tests across the eight MIDX, bitmap, and repack scripts pass, along with test-lint and whitespace checks. midx-write.c | 5 +-- t/t5319-multi-pack-index.sh | 15 +++++++ t/t5326-multi-pack-bitmaps.sh | 9 ++--- t/t5334-incremental-multi-pack-index.sh | 52 +++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 9 deletions(-) diff --git a/midx-write.c b/midx-write.c index 8537102254..3038bbfad2 100644 --- a/midx-write.c +++ b/midx-write.c @@ -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) { diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh index 68143cb5b7..3d65fafe62 100755 --- a/t/t5319-multi-pack-index.sh +++ b/t/t5319-multi-pack-index.sh @@ -54,6 +54,21 @@ 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' ' + test_when_finished "rm -rf empty.git" && + git init --bare empty.git && + ( + cd empty.git && + git pack-objects objects/pack/pack err && + in && + git pack-objects $packdir/pack