diff options
Diffstat (limited to 't/t5332-multi-pack-reuse.sh')
-rwxr-xr-x | t/t5332-multi-pack-reuse.sh | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/t/t5332-multi-pack-reuse.sh b/t/t5332-multi-pack-reuse.sh new file mode 100755 index 0000000..3c20738 --- /dev/null +++ b/t/t5332-multi-pack-reuse.sh @@ -0,0 +1,207 @@ +#!/bin/sh + +test_description='pack-objects multi-pack reuse' + +TEST_PASSES_SANITIZE_LEAK=true +. ./test-lib.sh +. "$TEST_DIRECTORY"/lib-bitmap.sh + +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_done |