midx: pass custom '--base' through incremental writes

The 'multi-pack-index' builtin parses '--base' for incremental writes,
but the normal write path does not pass that value through to
`write_midx_file()`.

As a result, something like:

    $ git multi-pack-index write --incremental --base=<base>

behaves as if no custom base had been given (unless the caller used the
'--stdin-packs' path).

Thread the parsed base through `write_midx_file()`, and update the
repack caller to pass NULL for the new argument where no custom base
selection is needed.

This exposes a pre-existing problem in incremental writes with custom
bases: the writer skips packs from the full existing MIDX chain, even
when the caller selected an older base or no base at all.

The affected t5334 cases fail while trying to write MIDX bitmaps. The
detached layer omits packs above the selected base, and thus the
resulting MIDX does not have a reachability closure, making it
impossible to generate reachability bitmaps.

Mark those tests as expected failures accordingly. The following commit
will fix the broken behavior and restore these tests.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
seen
Taylor Blau 2026-06-12 16:07:11 -04:00 committed by Junio C Hamano
parent acfdb54eb3
commit 8e519b8756
5 changed files with 25 additions and 8 deletions

View File

@ -224,7 +224,8 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
}

ret = write_midx_file(source, opts.preferred_pack,
opts.refs_snapshot, opts.flags);
opts.refs_snapshot, opts.incremental_base,
opts.flags);

free(opts.refs_snapshot);
return ret;

View File

@ -629,7 +629,7 @@ int cmd_repack(int argc,
unsigned flags = 0;
if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL, 0))
flags |= MIDX_WRITE_INCREMENTAL;
write_midx_file(existing.source, NULL, NULL, flags);
write_midx_file(existing.source, NULL, NULL, NULL, flags);
}

cleanup:

View File

@ -1850,12 +1850,14 @@ cleanup:
int write_midx_file(struct odb_source *source,
const char *preferred_pack_name,
const char *refs_snapshot,
const char *incremental_base,
unsigned flags)
{
struct write_midx_opts opts = {
.source = source,
.preferred_pack_name = preferred_pack_name,
.refs_snapshot = refs_snapshot,
.incremental_base = incremental_base,
.flags = flags,
};


2
midx.h
View File

@ -131,7 +131,7 @@ int prepare_multi_pack_index_one(struct odb_source *source);
*/
int write_midx_file(struct odb_source *source,
const char *preferred_pack_name, const char *refs_snapshot,
unsigned flags);
const char *incremental_base, unsigned flags);
int write_midx_file_only(struct odb_source *source,
struct string_list *packs_to_include,
const char *preferred_pack_name,

View File

@ -119,7 +119,7 @@ test_expect_success 'write MIDX layer with --base without --no-write-chain-file'
test_grep "cannot use --base without --no-write-chain-file" err
'

test_expect_success 'write MIDX layer with --base=none and --no-write-chain-file' '
test_expect_failure 'write MIDX layer with --base=none and --no-write-chain-file' '
test_commit base-none &&
git repack -d &&

@ -128,19 +128,33 @@ test_expect_success 'write MIDX layer with --base=none and --no-write-chain-file
--no-write-chain-file --base=none)" &&

test_cmp "$midx_chain.bak" "$midx_chain" &&
test_path_is_file "$midxdir/multi-pack-index-$layer.midx"
test_path_is_file "$midxdir/multi-pack-index-$layer.midx" &&

echo "$layer" >"$midx_chain" &&
test-tool read-midx --show-objects "$objdir" "$layer" >midx.objects &&
test_grep "^$(git rev-parse 2.2) " midx.objects &&
cp "$midx_chain.bak" "$midx_chain"
'

test_expect_success 'write MIDX layer with --base=<hash> and --no-write-chain-file' '
test_expect_failure 'write MIDX layer with --base=<hash> and --no-write-chain-file' '
test_commit base-hash &&
git repack -d &&

cp "$midx_chain" "$midx_chain.bak" &&
base="$(nth_line 1 "$midx_chain")" &&
layer="$(git multi-pack-index write --bitmap --incremental \
--no-write-chain-file --base="$(nth_line 1 "$midx_chain")")" &&
--no-write-chain-file --base="$base")" &&

test_cmp "$midx_chain.bak" "$midx_chain" &&
test_path_is_file "$midxdir/multi-pack-index-$layer.midx"
test_path_is_file "$midxdir/multi-pack-index-$layer.midx" &&

{
echo "$base" &&
echo "$layer"
} >"$midx_chain" &&
test-tool read-midx --show-objects "$objdir" "$layer" >midx.objects &&
test_grep "^$(git rev-parse 2.2) " midx.objects &&
cp "$midx_chain.bak" "$midx_chain"
'

for reuse in false single multi