
Now that the rest of the MIDX subsystem and relevant callers have been updated to learn about how to read and process incremental MIDX chains, let's finally update the implementation in `write_midx_internal()` to be able to write incremental MIDX chains. This new feature is available behind the `--incremental` option for the `multi-pack-index` builtin, like so: $ git multi-pack-index write --incremental The implementation for doing so is relatively straightforward, and boils down to a handful of different kinds of changes implemented in this patch: - The `compute_sorted_entries()` function is taught to reject objects which appear in any existing MIDX layer. - Functions like `write_midx_revindex()` are adjusted to write pack_order values which are offset by the number of objects in the base MIDX layer. - The end of `write_midx_internal()` is adjusted to move non-incremental MIDX files when necessary (i.e. when creating an incremental chain with an existing non-incremental MIDX in the repository). There are a handful of other changes that are introduced, like new functions to clear incremental MIDX files that are unrelated to the current chain (using the same "keep_hash" mechanism as in the non-incremental case). The tests explicitly exercising the new incremental MIDX feature are relatively limited for two reasons: 1. Most of the "interesting" behavior is already thoroughly covered in t5319-multi-pack-index.sh, which handles the core logic of reading objects through a MIDX. The new tests in t5334-incremental-multi-pack-index.sh are mostly focused on creating and destroying incremental MIDXs, as well as stitching their results together across layers. 2. A new GIT_TEST environment variable is added called "GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL", which modifies the entire test suite to write incremental MIDXs after repacking when combined with the "GIT_TEST_MULTI_PACK_INDEX" variable. This exercises the long tail of other interesting behavior that is defined implicitly throughout the rest of the CI suite. It is likewise added to the linux-TEST-vars job. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
236 lines
5.7 KiB
Bash
Executable File
236 lines
5.7 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
test_description='pack-objects multi-pack reuse'
|
|
|
|
TEST_PASSES_SANITIZE_LEAK=true
|
|
. ./test-lib.sh
|
|
. "$TEST_DIRECTORY"/lib-bitmap.sh
|
|
|
|
GIT_TEST_MULTI_PACK_INDEX=0
|
|
GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL=0
|
|
objdir=.git/objects
|
|
packdir=$objdir/pack
|
|
|
|
test_pack_reused () {
|
|
test_trace2_data pack-objects pack-reused "$1"
|
|
}
|
|
|
|
test_packs_reused () {
|
|
test_trace2_data pack-objects packs-reused "$1"
|
|
}
|
|
|
|
|
|
# pack_position <object> </path/to/pack.idx
|
|
pack_position () {
|
|
git show-index >objects &&
|
|
grep "$1" objects | cut -d" " -f1
|
|
}
|
|
|
|
# test_pack_objects_reused_all <pack-reused> <packs-reused>
|
|
test_pack_objects_reused_all () {
|
|
: >trace2.txt &&
|
|
GIT_TRACE2_EVENT="$PWD/trace2.txt" \
|
|
git pack-objects --stdout --revs --all --delta-base-offset \
|
|
>/dev/null &&
|
|
|
|
test_pack_reused "$1" <trace2.txt &&
|
|
test_packs_reused "$2" <trace2.txt
|
|
}
|
|
|
|
# test_pack_objects_reused <pack-reused> <packs-reused>
|
|
test_pack_objects_reused () {
|
|
: >trace2.txt &&
|
|
GIT_TRACE2_EVENT="$PWD/trace2.txt" \
|
|
git pack-objects --stdout --revs >/dev/null &&
|
|
|
|
test_pack_reused "$1" <trace2.txt &&
|
|
test_packs_reused "$2" <trace2.txt
|
|
}
|
|
|
|
test_expect_success 'preferred pack is reused for single-pack reuse' '
|
|
test_config pack.allowPackReuse single &&
|
|
|
|
for i in A B
|
|
do
|
|
test_commit "$i" &&
|
|
git repack -d || return 1
|
|
done &&
|
|
|
|
git multi-pack-index write --bitmap &&
|
|
|
|
test_pack_objects_reused_all 3 1
|
|
'
|
|
|
|
test_expect_success 'multi-pack reuse is disabled by default' '
|
|
test_pack_objects_reused_all 3 1
|
|
'
|
|
|
|
test_expect_success 'feature.experimental implies multi-pack reuse' '
|
|
test_config feature.experimental true &&
|
|
|
|
test_pack_objects_reused_all 6 2
|
|
'
|
|
|
|
test_expect_success 'multi-pack reuse can be disabled with feature.experimental' '
|
|
test_config feature.experimental true &&
|
|
test_config pack.allowPackReuse single &&
|
|
|
|
test_pack_objects_reused_all 3 1
|
|
'
|
|
|
|
test_expect_success 'enable multi-pack reuse' '
|
|
git config pack.allowPackReuse multi
|
|
'
|
|
|
|
test_expect_success 'reuse all objects from subset of bitmapped packs' '
|
|
test_commit C &&
|
|
git repack -d &&
|
|
|
|
git multi-pack-index write --bitmap &&
|
|
|
|
cat >in <<-EOF &&
|
|
$(git rev-parse C)
|
|
^$(git rev-parse A)
|
|
EOF
|
|
|
|
test_pack_objects_reused 6 2 <in
|
|
'
|
|
|
|
test_expect_success 'reuse all objects from all packs' '
|
|
test_pack_objects_reused_all 9 3
|
|
'
|
|
|
|
test_expect_success 'reuse objects from first pack with middle gap' '
|
|
for i in D E F
|
|
do
|
|
test_commit "$i" || return 1
|
|
done &&
|
|
|
|
# Set "pack.window" to zero to ensure that we do not create any
|
|
# deltas, which could alter the amount of pack reuse we perform
|
|
# (if, for e.g., we are not sending one or more bases).
|
|
D="$(git -c pack.window=0 pack-objects --all --unpacked $packdir/pack)" &&
|
|
|
|
d_pos="$(pack_position $(git rev-parse D) <$packdir/pack-$D.idx)" &&
|
|
e_pos="$(pack_position $(git rev-parse E) <$packdir/pack-$D.idx)" &&
|
|
f_pos="$(pack_position $(git rev-parse F) <$packdir/pack-$D.idx)" &&
|
|
|
|
# commits F, E, and D, should appear in that order at the
|
|
# beginning of the pack
|
|
test $f_pos -lt $e_pos &&
|
|
test $e_pos -lt $d_pos &&
|
|
|
|
# Ensure that the pack we are constructing sorts ahead of any
|
|
# other packs in lexical/bitmap order by choosing it as the
|
|
# preferred pack.
|
|
git multi-pack-index write --bitmap --preferred-pack="pack-$D.idx" &&
|
|
|
|
cat >in <<-EOF &&
|
|
$(git rev-parse E)
|
|
^$(git rev-parse D)
|
|
EOF
|
|
|
|
test_pack_objects_reused 3 1 <in
|
|
'
|
|
|
|
test_expect_success 'reuse objects from middle pack with middle gap' '
|
|
rm -fr $packdir/multi-pack-index* &&
|
|
|
|
# Ensure that the pack we are constructing sort into any
|
|
# position *but* the first one, by choosing a different pack as
|
|
# the preferred one.
|
|
git multi-pack-index write --bitmap --preferred-pack="pack-$A.idx" &&
|
|
|
|
cat >in <<-EOF &&
|
|
$(git rev-parse E)
|
|
^$(git rev-parse D)
|
|
EOF
|
|
|
|
test_pack_objects_reused 3 1 <in
|
|
'
|
|
|
|
test_expect_success 'omit delta with uninteresting base (same pack)' '
|
|
git repack -adk &&
|
|
|
|
test_seq 32 >f &&
|
|
git add f &&
|
|
test_tick &&
|
|
git commit -m "delta" &&
|
|
delta="$(git rev-parse HEAD)" &&
|
|
|
|
test_seq 64 >f &&
|
|
test_tick &&
|
|
git commit -a -m "base" &&
|
|
base="$(git rev-parse HEAD)" &&
|
|
|
|
test_commit other &&
|
|
|
|
git repack -d &&
|
|
|
|
have_delta "$(git rev-parse $delta:f)" "$(git rev-parse $base:f)" &&
|
|
|
|
git multi-pack-index write --bitmap &&
|
|
|
|
cat >in <<-EOF &&
|
|
$(git rev-parse other)
|
|
^$base
|
|
EOF
|
|
|
|
# We can only reuse the 3 objects corresponding to "other" from
|
|
# the latest pack.
|
|
#
|
|
# This is because even though we want "delta", we do not want
|
|
# "base", meaning that we have to inflate the delta/base-pair
|
|
# corresponding to the blob in commit "delta", which bypasses
|
|
# the pack-reuse mechanism.
|
|
#
|
|
# The remaining objects from the other pack are similarly not
|
|
# reused because their objects are on the uninteresting side of
|
|
# the query.
|
|
test_pack_objects_reused 3 1 <in
|
|
'
|
|
|
|
test_expect_success 'omit delta from uninteresting base (cross pack)' '
|
|
cat >in <<-EOF &&
|
|
$(git rev-parse $base)
|
|
^$(git rev-parse $delta)
|
|
EOF
|
|
|
|
P="$(git pack-objects --revs $packdir/pack <in)" &&
|
|
|
|
git multi-pack-index write --bitmap --preferred-pack="pack-$P.idx" &&
|
|
|
|
packs_nr="$(find $packdir -type f -name "pack-*.pack" | wc -l)" &&
|
|
objects_nr="$(git rev-list --count --all --objects)" &&
|
|
|
|
test_pack_objects_reused_all $(($objects_nr - 1)) $packs_nr
|
|
'
|
|
|
|
test_expect_success 'non-omitted delta in MIDX preferred pack' '
|
|
test_config pack.allowPackReuse single &&
|
|
|
|
cat >p1.objects <<-EOF &&
|
|
$(git rev-parse $base)
|
|
^$(git rev-parse $delta^)
|
|
EOF
|
|
cat >p2.objects <<-EOF &&
|
|
$(git rev-parse F)
|
|
EOF
|
|
|
|
p1="$(git pack-objects --revs $packdir/pack <p1.objects)" &&
|
|
p2="$(git pack-objects --revs $packdir/pack <p2.objects)" &&
|
|
|
|
cat >in <<-EOF &&
|
|
pack-$p1.idx
|
|
pack-$p2.idx
|
|
EOF
|
|
git multi-pack-index write --bitmap --stdin-packs \
|
|
--preferred-pack=pack-$p1.pack <in &&
|
|
|
|
git show-index <$packdir/pack-$p1.idx >expect &&
|
|
|
|
test_pack_objects_reused_all $(wc -l <expect) 1
|
|
'
|
|
|
|
test_done
|