git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] midx-write: skip empty incremental layers

From
PPPia Park <pia@pierre.co>
Date
Sep 8, 2026, 01:46 UTC
Message-ID
<20260908014720.19705-1-pia@pierre.co>

An incremental MIDX write can find new packs without finding any new objects, either because the packs are empty or because their objects are already indexed by an earlier layer.

The existing early exit checks the number of packs, so these cases publish a zero-object layer without a reverse index. A subsequent incremental write with --bitmap fails when loading that reverse index.

Reproducible on master as of b8242b093d9e941a34460d715e3ce616a34ac3fe (2026-09-07), using:

    git init --bare --object-format=sha1 empty.git &&
    (
        cd empty.git &&
        git config midx.version 2 &&
        git pack-objects objects/pack/pack </dev/null &&
        git multi-pack-index write --incremental --bitmap &&
        git multi-pack-index write --incremental --bitmap
    )

The first write succeeds but publishes the empty layer 3c8853aad425100c5ee2ee22209bb0bb3df9ca37. The second exits with status 255, reporting "could not load reverse index for MIDX".

Return success through the existing cleanup path when
compute_sorted_entries() finds no entries for a non-compacting
incremental write. This prevents publishing an empty layer that causes
subsequent incremental writes with --bitmap to fail with exit status
255. Exit before acquiring a lock or creating a temporary MIDX file,
leaving the existing chain untouched.

Add regression tests for empty initial layers, empty packs, and packs containing only duplicate objects. Check silent success, preservation of the existing chain and file list, and subsequent writes that add new objects.

Signed-off-by: Pia Park <pia@pierre.co>
---
Built with DEVELOPER=1 and ran these scripts before and after:
  t5319-multi-pack-index.sh
  t5326-multi-pack-bitmaps.sh
  t5327-multi-pack-bitmaps-rev.sh
  t5332-multi-pack-reuse.sh
  t5334-incremental-multi-pack-index.sh
  t5335-compact-multi-pack-index.sh
  t7700-repack.sh
  t7705-repack-incremental-midx.sh

All 881 baseline tests and all 884 tests with the patch passed. The three new regressions fail on the unpatched build. Test lint and whitespace checks passed.

Both empty and duplicate-only pack reproductions also fail on a fresh, unmodified build of upstream master at the base commit shown below.

 midx-write.c                            |  5 +++
 t/t5334-incremental-multi-pack-index.sh | 58 +++++++++++++++++++++++++
 2 files changed, 63 insertions(+)
diff --git a/midx-write.c b/midx-write.c
index 8537102254..cdb2ef0474 100644
--- a/midx-write.c
+++ b/midx-write.c
@@ -1518,6 +1518,11 @@ static int write_midx_internal(struct write_midx_opts *opts)
 
 	compute_sorted_entries(&ctx, start_pack);
 
+	if (ctx.incremental && !ctx.compact && !ctx.entries_nr) {
+		result = 0;
+		goto cleanup;
+	}
+
 	ctx.large_offsets_needed = 0;
 	for (size_t i = 0; i < ctx.entries_nr; i++) {
 		if (ctx.entries[i].offset > 0x7fffffff)
diff --git a/t/t5334-incremental-multi-pack-index.sh b/t/t5334-incremental-multi-pack-index.sh
index f0b82b5f65..4bdfa61d38 100755
--- a/t/t5334-incremental-multi-pack-index.sh
+++ b/t/t5334-incremental-multi-pack-index.sh
@@ -195,4 +195,62 @@ 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>err &&
+			test_must_be_empty out &&
+			test_must_be_empty err &&
+			test_dir_is_empty "$midxdir" || return 1
+		done &&
+
+		write_midx_layer &&
+		test_line_count = 1 "$midx_chain" &&
+		git multi-pack-index verify
+	)
+'
+
+for pack in empty duplicate
+do
+	test_expect_success "skip MIDX layer with $pack pack" '
+		git init "$pack-pack" &&
+		(
+			cd "$pack-pack" &&
+			git config maintenance.auto false &&
+			write_midx_layer &&
+
+			if test "$pack" = duplicate
+			then
+				git rev-parse HEAD^{tree} >in
+			else
+				>in
+			fi &&
+			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>err &&
+				test_must_be_empty out &&
+				test_must_be_empty err &&
+				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
+		)
+	'
+done
+
 test_done

base-commit: b8242b093d9e941a34460d715e3ce616a34ac3fe
-- 
2.55.0
Next: Taylor Blau
Message 1 of 10 in “midx-write: skip empty incremental layers”
  1. midx-write: skip empty incremental layersPia Park, Sep 8, 2026
  2. Taylor BlauSep 8, 2026
  3. midx-write: skip writes with no object entriesPia Park, Sep 8, 2026
  4. Taylor BlauSep 8, 2026
  5. midx-write: skip writes with no object entriesPia Park, Oct 29, 2026
  6. Taylor BlauOct 29, 2026
  7. Junio C HamanoOct 29, 2026
  8. Pia ParkSep 15, 2026
  9. Junio C HamanoOct 27, 2026
  10. Taylor BlauOct 28, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.