aboutsummaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2026-03-25 12:58:04 -0700
committerJunio C Hamano <gitster@pobox.com>2026-03-25 12:58:04 -0700
commit105a22cf692a08604bc294ec2c164528889837b0 (patch)
treebb66ea13bcb7b2c9e1bcb7a3c294285579994f2a /t
parentce74208c2fa13943fffa58f168ac27a76d0eb789 (diff)
parentd54da84bd9de09fc339accff553f1fc8a5539154 (diff)
downloadgit-105a22cf692a08604bc294ec2c164528889837b0.tar.xz
Merge branch 'tb/incremental-midx-part-3.2'
Further work on incremental repacking using MIDX/bitmap * tb/incremental-midx-part-3.2: midx: enable reachability bitmaps during MIDX compaction midx: implement MIDX compaction t/helper/test-read-midx.c: plug memory leak when selecting layer midx-write.c: factor fanout layering from `compute_sorted_entries()` midx-write.c: enumerate `pack_int_id` values directly midx-write.c: extract `fill_pack_from_midx()` midx-write.c: introduce `midx_pack_perm()` helper midx: do not require packs to be sorted in lexicographic order midx-write.c: introduce `struct write_midx_opts` midx-write.c: don't use `pack_perm` when assigning `bitmap_pos` t/t5319-multi-pack-index.sh: fix copy-and-paste error in t5319.39 git-multi-pack-index(1): align SYNOPSIS with 'git multi-pack-index -h' git-multi-pack-index(1): remove non-existent incompatibility builtin/multi-pack-index.c: make '--progress' a common option midx: introduce `midx_get_checksum_hex()` midx: rename `get_midx_checksum()` to `midx_get_checksum_hash()` midx: mark `get_midx_checksum()` arguments as const
Diffstat (limited to 't')
-rw-r--r--t/helper/test-read-midx.c21
-rw-r--r--t/meson.build1
-rw-r--r--t/t0450/adoc-help-mismatches1
-rwxr-xr-xt/t5319-multi-pack-index.sh18
-rwxr-xr-xt/t5335-compact-multi-pack-index.sh293
5 files changed, 318 insertions, 16 deletions
diff --git a/t/helper/test-read-midx.c b/t/helper/test-read-midx.c
index 6de5d1665a..388d29e2b5 100644
--- a/t/helper/test-read-midx.c
+++ b/t/helper/test-read-midx.c
@@ -26,18 +26,22 @@ static int read_midx_file(const char *object_dir, const char *checksum,
int show_objects)
{
uint32_t i;
- struct multi_pack_index *m;
+ struct multi_pack_index *m, *tip;
+ int ret = 0;
- m = setup_midx(object_dir);
+ m = tip = setup_midx(object_dir);
if (!m)
return 1;
if (checksum) {
- while (m && strcmp(hash_to_hex(get_midx_checksum(m)), checksum))
+ while (m && strcmp(midx_get_checksum_hex(m), checksum))
m = m->base_midx;
- if (!m)
- return 1;
+ if (!m) {
+ ret = error(_("could not find MIDX with checksum %s"),
+ checksum);
+ goto out;
+ }
}
printf("header: %08x %d %d %d %d\n",
@@ -82,9 +86,10 @@ static int read_midx_file(const char *object_dir, const char *checksum,
}
}
- close_midx(m);
+out:
+ close_midx(tip);
- return 0;
+ return ret;
}
static int read_midx_checksum(const char *object_dir)
@@ -94,7 +99,7 @@ static int read_midx_checksum(const char *object_dir)
m = setup_midx(object_dir);
if (!m)
return 1;
- printf("%s\n", hash_to_hex(get_midx_checksum(m)));
+ printf("%s\n", midx_get_checksum_hex(m));
close_midx(m);
return 0;
diff --git a/t/meson.build b/t/meson.build
index bafb8e63a9..919a0ae4cb 100644
--- a/t/meson.build
+++ b/t/meson.build
@@ -626,6 +626,7 @@ integration_tests = [
't5332-multi-pack-reuse.sh',
't5333-pseudo-merge-bitmaps.sh',
't5334-incremental-multi-pack-index.sh',
+ 't5335-compact-multi-pack-index.sh',
't5351-unpack-large-objects.sh',
't5400-send-pack.sh',
't5401-update-hooks.sh',
diff --git a/t/t0450/adoc-help-mismatches b/t/t0450/adoc-help-mismatches
index 8ee2d3f7c8..e8d6c13ccd 100644
--- a/t/t0450/adoc-help-mismatches
+++ b/t/t0450/adoc-help-mismatches
@@ -33,7 +33,6 @@ merge
merge-file
merge-index
merge-one-file
-multi-pack-index
name-rev
notes
push
diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh
index a7c79225f6..58e0b685b1 100755
--- a/t/t5319-multi-pack-index.sh
+++ b/t/t5319-multi-pack-index.sh
@@ -21,7 +21,7 @@ midx_read_expect () {
EXTRA_CHUNKS="$5"
{
cat <<-EOF &&
- header: 4d494458 1 $HASH_LEN $NUM_CHUNKS $NUM_PACKS
+ header: 4d494458 2 $HASH_LEN $NUM_CHUNKS $NUM_PACKS
chunks: pack-names oid-fanout oid-lookup object-offsets$EXTRA_CHUNKS
num_objects: $NUM_OBJECTS
packs:
@@ -512,12 +512,7 @@ test_expect_success 'verify invalid chunk offset' '
"improper chunk offset(s)"
'
-test_expect_success 'verify packnames out of order' '
- corrupt_midx_and_verify $MIDX_BYTE_PACKNAME_ORDER "z" $objdir \
- "pack names out of order"
-'
-
-test_expect_success 'verify packnames out of order' '
+test_expect_success 'verify missing pack' '
corrupt_midx_and_verify $MIDX_BYTE_PACKNAME_ORDER "a" $objdir \
"failed to load pack"
'
@@ -578,6 +573,15 @@ test_expect_success 'verify incorrect checksum' '
$objdir "incorrect checksum"
'
+test_expect_success 'setup for v1-specific fsck tests' '
+ git -c midx.version=1 multi-pack-index write
+'
+
+test_expect_success 'verify packnames out of order (v1)' '
+ corrupt_midx_and_verify $MIDX_BYTE_PACKNAME_ORDER "z" $objdir \
+ "pack names out of order"
+'
+
test_expect_success 'repack progress off for redirected stderr' '
GIT_PROGRESS_DELAY=0 git multi-pack-index --object-dir=$objdir repack 2>err &&
test_line_count = 0 err
diff --git a/t/t5335-compact-multi-pack-index.sh b/t/t5335-compact-multi-pack-index.sh
new file mode 100755
index 0000000000..40f3844282
--- /dev/null
+++ b/t/t5335-compact-multi-pack-index.sh
@@ -0,0 +1,293 @@
+#!/bin/sh
+
+test_description='multi-pack-index compaction'
+
+. ./test-lib.sh
+
+GIT_TEST_MULTI_PACK_INDEX=0
+GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=0
+GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL=0
+
+objdir=.git/objects
+packdir=$objdir/pack
+midxdir=$packdir/multi-pack-index.d
+midx_chain=$midxdir/multi-pack-index-chain
+
+nth_line() {
+ local n="$1"
+ shift
+ awk "NR==$n" "$@"
+}
+
+write_packs () {
+ for c in "$@"
+ do
+ test_commit "$c" &&
+
+ git pack-objects --all --unpacked $packdir/pack-$c &&
+ git prune-packed &&
+
+ git multi-pack-index write --incremental --bitmap || return 1
+ done
+}
+
+test_midx_layer_packs () {
+ local checksum="$1" &&
+ shift &&
+
+ test-tool read-midx $objdir "$checksum" >out &&
+
+ printf "%s\n" "$@" >expect &&
+ # NOTE: do *not* pipe through sort here, we want to ensure the
+ # order of packs is preserved during compaction.
+ grep "^pack-" out | cut -d"-" -f2 >actual &&
+
+ test_cmp expect actual
+}
+
+test_midx_layer_object_uniqueness () {
+ : >objs.all
+ while read layer
+ do
+ test-tool read-midx --show-objects $objdir "$layer" >out &&
+ grep "\.pack$" out | cut -d" " -f1 | sort >objs.layer &&
+ test_stdout_line_count = 0 comm -12 objs.all objs.layer &&
+ cat objs.all objs.layer | sort >objs.tmp &&
+ mv objs.tmp objs.all || return 1
+ done <$midx_chain
+}
+
+test_expect_success 'MIDX compaction with lex-ordered pack names' '
+ git init midx-compact-lex-order &&
+ (
+ cd midx-compact-lex-order &&
+
+ git config maintenance.auto false &&
+
+ write_packs A B C D E &&
+ test_line_count = 5 $midx_chain &&
+
+ git multi-pack-index compact --incremental --bitmap \
+ "$(nth_line 2 "$midx_chain")" \
+ "$(nth_line 4 "$midx_chain")" &&
+ test_line_count = 3 $midx_chain &&
+
+ test_midx_layer_packs "$(nth_line 1 "$midx_chain")" A &&
+ test_midx_layer_packs "$(nth_line 2 "$midx_chain")" B C D &&
+ test_midx_layer_packs "$(nth_line 3 "$midx_chain")" E &&
+
+ test_midx_layer_object_uniqueness
+ )
+'
+
+test_expect_success 'MIDX compaction with non-lex-ordered pack names' '
+ git init midx-compact-non-lex-order &&
+ (
+ cd midx-compact-non-lex-order &&
+
+ git config maintenance.auto false &&
+
+ write_packs D C A B E &&
+ test_line_count = 5 $midx_chain &&
+
+ git multi-pack-index compact --incremental --bitmap \
+ "$(nth_line 2 "$midx_chain")" \
+ "$(nth_line 4 "$midx_chain")" &&
+ test_line_count = 3 $midx_chain &&
+
+ test_midx_layer_packs "$(nth_line 1 "$midx_chain")" D &&
+ test_midx_layer_packs "$(nth_line 2 "$midx_chain")" C A B &&
+ test_midx_layer_packs "$(nth_line 3 "$midx_chain")" E &&
+
+ test_midx_layer_object_uniqueness
+ )
+'
+
+test_expect_success 'setup for bogus MIDX compaction scenarios' '
+ git init midx-compact-bogus &&
+ (
+ cd midx-compact-bogus &&
+
+ git config maintenance.auto false &&
+
+ write_packs A B C
+ )
+'
+
+test_expect_success 'MIDX compaction with missing endpoints' '
+ (
+ cd midx-compact-bogus &&
+
+ test_must_fail git multi-pack-index compact --incremental \
+ "<missing>" "<missing>" 2>err &&
+ test_grep "could not find MIDX: <missing>" err &&
+
+ test_must_fail git multi-pack-index compact --incremental \
+ "<missing>" "$(nth_line 2 "$midx_chain")" 2>err &&
+ test_grep "could not find MIDX: <missing>" err &&
+
+ test_must_fail git multi-pack-index compact --incremental \
+ "$(nth_line 2 "$midx_chain")" "<missing>" 2>err &&
+ test_grep "could not find MIDX: <missing>" err
+ )
+'
+
+test_expect_success 'MIDX compaction with reversed endpoints' '
+ (
+ cd midx-compact-bogus &&
+
+ from="$(nth_line 3 "$midx_chain")" &&
+ to="$(nth_line 1 "$midx_chain")" &&
+
+ test_must_fail git multi-pack-index compact --incremental \
+ "$from" "$to" 2>err &&
+
+ test_grep "MIDX $from must be an ancestor of $to" err
+ )
+'
+
+test_expect_success 'MIDX compaction with identical endpoints' '
+ (
+ cd midx-compact-bogus &&
+
+ from="$(nth_line 3 "$midx_chain")" &&
+ to="$(nth_line 3 "$midx_chain")" &&
+
+ test_must_fail git multi-pack-index compact --incremental \
+ "$from" "$to" 2>err &&
+
+ test_grep "MIDX compaction endpoints must be unique" err
+ )
+'
+
+test_expect_success 'MIDX compaction with midx.version=1' '
+ (
+ cd midx-compact-bogus &&
+
+ test_must_fail git -c midx.version=1 multi-pack-index compact \
+ "$(nth_line 1 "$midx_chain")" \
+ "$(nth_line 2 "$midx_chain")" 2>err &&
+
+ test_grep "fatal: cannot perform MIDX compaction with v1 format" err
+ )
+'
+
+midx_objs_by_pack () {
+ awk '/\.pack$/ { split($3, a, "-"); print a[2], $1 }' | sort
+}
+
+tag_objs_from_pack () {
+ objs="$(git rev-list --objects --no-object-names "$2")" &&
+ printf "$1 %s\n" $objs | sort
+}
+
+test_expect_success 'MIDX compaction preserves pack object selection' '
+ git init midx-compact-preserve-selection &&
+ (
+ cd midx-compact-preserve-selection &&
+
+ git config maintenance.auto false &&
+
+ test_commit A &&
+ test_commit B &&
+
+ # Create two packs, one containing just the objects from
+ # A, and another containing all objects from the
+ # repository.
+ p1="$(echo A | git pack-objects --revs --delta-base-offset \
+ $packdir/pack-1)" &&
+ p0="$(echo B | git pack-objects --revs --delta-base-offset \
+ $packdir/pack-0)" &&
+
+ echo "pack-1-$p1.idx" | git multi-pack-index write \
+ --incremental --bitmap --stdin-packs &&
+ echo "pack-0-$p0.idx" | git multi-pack-index write \
+ --incremental --bitmap --stdin-packs &&
+
+ write_packs C &&
+
+ git multi-pack-index compact --incremental --bitmap \
+ "$(nth_line 1 "$midx_chain")" \
+ "$(nth_line 2 "$midx_chain")" &&
+
+
+ test-tool read-midx --show-objects $objdir \
+ "$(nth_line 1 "$midx_chain")" >AB.info &&
+ test-tool read-midx --show-objects $objdir \
+ "$(nth_line 2 "$midx_chain")" >C.info &&
+
+ midx_objs_by_pack <AB.info >AB.actual &&
+ midx_objs_by_pack <C.info >C.actual &&
+
+ {
+ tag_objs_from_pack 1 A &&
+ tag_objs_from_pack 0 A..B
+ } | sort >AB.expect &&
+ tag_objs_from_pack C B..C >C.expect &&
+
+ test_cmp AB.expect AB.actual &&
+ test_cmp C.expect C.actual
+ )
+'
+
+test_expect_success 'MIDX compaction with bitmaps' '
+ git init midx-compact-with-bitmaps &&
+ (
+ cd midx-compact-with-bitmaps &&
+
+ git config maintenance.auto false &&
+
+ write_packs foo bar baz quux woot &&
+
+ test-tool read-midx --bitmap $objdir >bitmap.expect &&
+ git multi-pack-index compact --incremental --bitmap \
+ "$(nth_line 2 "$midx_chain")" \
+ "$(nth_line 4 "$midx_chain")" &&
+ test-tool read-midx --bitmap $objdir >bitmap.actual &&
+
+ test_cmp bitmap.expect bitmap.actual &&
+
+ true
+ )
+'
+
+test_expect_success 'MIDX compaction with bitmaps (non-trivial)' '
+ git init midx-compact-with-bitmaps-non-trivial &&
+ (
+ cd midx-compact-with-bitmaps-non-trivial &&
+
+ git config maintenance.auto false &&
+
+ git branch -m main &&
+
+ # D(4)
+ # /
+ # A(1) --- B(2) --- C(3) --- G(7)
+ # \
+ # E(5) --- F(6)
+ write_packs A B C &&
+ git checkout -b side &&
+ write_packs D &&
+ git checkout -b other B &&
+ write_packs E F &&
+ git checkout main &&
+ write_packs G &&
+
+ # Compact layers 2-4, leaving us with:
+ #
+ # [A, [B, C, D], E, F, G]
+ git multi-pack-index compact --incremental --bitmap \
+ "$(nth_line 2 "$midx_chain")" \
+ "$(nth_line 4 "$midx_chain")" &&
+
+ # Then compact the top two layers, condensing the above
+ # such that the new 4th layer contains F and G.
+ #
+ # [A, [B, C, D], E, [F, G]]
+ git multi-pack-index compact --incremental --bitmap \
+ "$(nth_line 4 "$midx_chain")" \
+ "$(nth_line 5 "$midx_chain")"
+ )
+'
+
+test_done