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

[PATCH 1/2] midx: fix `BUG()` when getting preferred pack without a reverse index

From
Patrick Steinhardt <ps@pks.im>
Date
Dec 8, 2025, 18:27 UTC
Message-ID
<20251208-pks-skip-noop-rewrite-v1-1-430d52dba9f0@pks.im>
In-Reply-To
<20251208-pks-skip-noop-rewrite-v1-0-430d52dba9f0@pks.im>

The function `midx_preferred_pack()` returns the preferred pack for a given multi-pack index. To compute the preferred pack we:

  1. Look up the position of the first object indexed by the multi-pack
     index.
  2. Convert this position from pseudo-pack order into MIDX order.
  3. We then look up pack that corresponds to this MIDX index.

This reliably returns the preferred pack given that all of its contained objects will be up front in pseudo-pack order.

The second step that turns the pseudo-pack order into MIDX order requires the reverse index though, which may not exist for example when the MIDX does not have a bitmap. And in that case one may easily hit a bug:

    BUG: ../pack-revindex.c:491: pack_pos_to_midx: reverse index not yet loaded

In theory, `midx_preferred_pack()` already knows to handle the case where no reverse index exists, as it calls `load_midx_revindex()` before calling into `midx_preferred_pack()`. But we only check for negative return values there, even though the function returns a positive error code in case the reverse index does not exist.

Fix the issue by testing for a non-zero return value instead, same as all the other callers of this function already do. While at it, document the return value of `load_midx_revindex()`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 midx.c                      |  2 +-
 pack-revindex.h             |  3 ++-
 t/t5319-multi-pack-index.sh | 13 +++++++++++++
 3 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/midx.c b/midx.c
index 24e1e72175..b681b18fc1 100644
--- a/midx.c
+++ b/midx.c
@@ -686,7 +686,7 @@ int midx_preferred_pack(struct multi_pack_index *m, uint32_t *pack_int_id)
 {
 	if (m->preferred_pack_idx == -1) {
 		uint32_t midx_pos;
-		if (load_midx_revindex(m) < 0) {
+		if (load_midx_revindex(m)) {
 			m->preferred_pack_idx = -2;
 			return -1;
 		}
diff --git a/pack-revindex.h b/pack-revindex.h
index 422c2487ae..0042892091 100644
--- a/pack-revindex.h
+++ b/pack-revindex.h
@@ -72,7 +72,8 @@ int verify_pack_revindex(struct packed_git *p);
  * multi-pack index by mmap-ing it and assigning pointers in the
  * multi_pack_index to point at it.
  *
- * A negative number is returned on error.
+ * A negative number is returned on error. A positive number is returned in
+ * case the multi-pack-index does not have a reverse index.
  */
 int load_midx_revindex(struct multi_pack_index *m);
 
diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh
index 93f319a4b2..9492a9737b 100755
--- a/t/t5319-multi-pack-index.sh
+++ b/t/t5319-multi-pack-index.sh
@@ -350,7 +350,20 @@ test_expect_success 'preferred pack from existing MIDX without bitmaps' '
 		# the new MIDX
 		git multi-pack-index write --preferred-pack=pack-$pack.pack
 	)
+'
 
+test_expect_success 'preferred pack cannot be determined without bitmap' '
+	test_when_finished "rm -fr preferred-can-be-queried" &&
+	git init preferred-can-be-queried &&
+	(
+		cd preferred-can-be-queried &&
+		test_commit initial &&
+		git repack -Adl --write-midx --no-write-bitmap-index &&
+		test_must_fail test-tool read-midx --preferred-pack .git/objects 2>err &&
+		test_grep "could not determine MIDX preferred pack" err &&
+		git repack -Adl --write-midx --write-bitmap-index &&
+		test-tool read-midx --preferred-pack .git/objects
+	)
 '
 
 test_expect_success 'verify multi-pack-index success' '
-- 
2.52.0.270.g3f4935d65f.dirty
Previous: Patrick SteinhardtNext: Taylor Blau
Message 2 of 16 in “builtin/repack: avoid rewriting up-to-date MIDX”
  1. 0/2 builtin/repack: avoid rewriting up-to-date MIDXPatrick Steinhardt, Dec 8, 2025
  2. 1/2 midx: fix `BUG()` when getting preferred pack without a reverse indexPatrick Steinhardt, Dec 8, 2025
  3. Taylor BlauDec 10, 2025
  4. Patrick SteinhardtDec 10, 2025
  5. Taylor BlauDec 18, 2025
  6. 2/2 builtin/repack: don't regenerate MIDX unless neededPatrick Steinhardt, Dec 8, 2025
  7. Taylor BlauDec 10, 2025
  8. Patrick SteinhardtDec 10, 2025
  9. 0/3 builtin/repack: avoid rewriting up-to-date MIDXPatrick Steinhardt, Dec 10, 2025
  10. 1/3 midx: fix `BUG()` when getting preferred pack without a reverse indexPatrick Steinhardt, Dec 10, 2025
  11. 2/3 midx-write: extract function to test whether MIDX needs updatingPatrick Steinhardt, Dec 10, 2025
  12. 3/3 midx-write: skip rewriting MIDX with `--stdin-packs` unless neededPatrick Steinhardt, Dec 10, 2025
  13. Junio C HamanoDec 11, 2025
  14. Patrick SteinhardtDec 12, 2025
  15. Taylor BlauDec 18, 2025
  16. Patrick SteinhardtDec 19, 2025

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.