3 test_description
='pack-objects multi-pack reuse'
5 TEST_PASSES_SANITIZE_LEAK
=true
7 .
"$TEST_DIRECTORY"/lib-bitmap.sh
9 GIT_TEST_MULTI_PACK_INDEX
=0
10 GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL
=0
15 test_trace2_data pack-objects pack-reused
"$1"
18 test_packs_reused
() {
19 test_trace2_data pack-objects packs-reused
"$1"
23 # pack_position <object> </path/to/pack.idx
25 git show-index
>objects
&&
26 grep "$1" objects | cut
-d" " -f1
29 # test_pack_objects_reused_all <pack-reused> <packs-reused>
30 test_pack_objects_reused_all
() {
32 GIT_TRACE2_EVENT
="$PWD/trace2.txt" \
33 git pack-objects
--stdout --revs --all --delta-base-offset \
36 test_pack_reused
"$1" <trace2.txt
&&
37 test_packs_reused
"$2" <trace2.txt
&&
39 git index-pack
--strict -o got.idx got.pack
42 # test_pack_objects_reused <pack-reused> <packs-reused>
43 test_pack_objects_reused
() {
45 GIT_TRACE2_EVENT
="$PWD/trace2.txt" \
46 git pack-objects
--stdout --revs >got.pack
&&
48 test_pack_reused
"$1" <trace2.txt
&&
49 test_packs_reused
"$2" <trace2.txt
&&
51 git index-pack
--strict -o got.idx got.pack
54 test_expect_success
'preferred pack is reused for single-pack reuse' '
55 test_config pack.allowPackReuse single &&
60 git repack -d || return 1
63 git multi-pack-index write --bitmap &&
65 test_pack_objects_reused_all 3 1
68 test_expect_success
'multi-pack reuse is disabled by default' '
69 test_pack_objects_reused_all 3 1
72 test_expect_success
'feature.experimental implies multi-pack reuse' '
73 test_config feature.experimental true &&
75 test_pack_objects_reused_all 6 2
78 test_expect_success
'multi-pack reuse can be disabled with feature.experimental' '
79 test_config feature.experimental true &&
80 test_config pack.allowPackReuse single &&
82 test_pack_objects_reused_all 3 1
85 test_expect_success
'enable multi-pack reuse' '
86 git config pack.allowPackReuse multi
89 test_expect_success
'reuse all objects from subset of bitmapped packs' '
93 git multi-pack-index write --bitmap &&
100 test_pack_objects_reused 6 2 <in
103 test_expect_success
'reuse all objects from all packs' '
104 test_pack_objects_reused_all 9 3
107 test_expect_success
'reuse objects from first pack with middle gap' '
110 test_commit "$i" || return 1
113 # Set "pack.window" to zero to ensure that we do not create any
114 # deltas, which could alter the amount of pack reuse we perform
115 # (if, for e.g., we are not sending one or more bases).
116 D="$(git -c pack.window=0 pack-objects --all --unpacked $packdir/pack)" &&
118 d_pos="$(pack_position $(git rev-parse D) <$packdir/pack-$D.idx)" &&
119 e_pos="$(pack_position $(git rev-parse E) <$packdir/pack-$D.idx)" &&
120 f_pos="$(pack_position $(git rev-parse F) <$packdir/pack-$D.idx)" &&
122 # commits F, E, and D, should appear in that order at the
123 # beginning of the pack
124 test $f_pos -lt $e_pos &&
125 test $e_pos -lt $d_pos &&
127 # Ensure that the pack we are constructing sorts ahead of any
128 # other packs in lexical/bitmap order by choosing it as the
130 git multi-pack-index write --bitmap --preferred-pack="pack-$D.idx" &&
137 test_pack_objects_reused 3 1 <in
140 test_expect_success
'reuse objects from middle pack with middle gap' '
141 rm -fr $packdir/multi-pack-index* &&
143 # Ensure that the pack we are constructing sort into any
144 # position *but* the first one, by choosing a different pack as
146 git multi-pack-index write --bitmap --preferred-pack="pack-$A.idx" &&
153 test_pack_objects_reused 3 1 <in
156 test_expect_success
'omit delta with uninteresting base (same pack)' '
162 git commit -m "delta" &&
163 delta="$(git rev-parse HEAD)" &&
167 git commit -a -m "base" &&
168 base="$(git rev-parse HEAD)" &&
174 have_delta "$(git rev-parse $delta:f)" "$(git rev-parse $base:f)" &&
176 git multi-pack-index write --bitmap &&
179 $(git rev-parse other)
183 # We can only reuse the 3 objects corresponding to "other" from
186 # This is because even though we want "delta", we do not want
187 # "base", meaning that we have to inflate the delta/base-pair
188 # corresponding to the blob in commit "delta", which bypasses
189 # the pack-reuse mechanism.
191 # The remaining objects from the other pack are similarly not
192 # reused because their objects are on the uninteresting side of
194 test_pack_objects_reused 3 1 <in
197 test_expect_success
'omit delta from uninteresting base (cross pack)' '
199 $(git rev-parse $base)
200 ^$(git rev-parse $delta)
203 P="$(git pack-objects --revs $packdir/pack <in)" &&
205 git multi-pack-index write --bitmap --preferred-pack="pack-$P.idx" &&
207 packs_nr="$(find $packdir -type f -name "pack-*.pack" | wc -l)" &&
208 objects_nr="$(git rev-list --count --all --objects)" &&
210 test_pack_objects_reused_all $(($objects_nr - 1)) $packs_nr
213 test_expect_success
'non-omitted delta in MIDX preferred pack' '
214 test_config pack.allowPackReuse single &&
216 cat >p1.objects <<-EOF &&
217 $(git rev-parse $base)
218 ^$(git rev-parse $delta^)
220 cat >p2.objects <<-EOF &&
224 p1="$(git pack-objects --revs $packdir/pack <p1.objects)" &&
225 p2="$(git pack-objects --revs $packdir/pack <p2.objects)" &&
231 git multi-pack-index write --bitmap --stdin-packs \
232 --preferred-pack=pack-$p1.pack <in &&
234 git show-index <$packdir/pack-$p1.idx >expect &&
236 test_pack_objects_reused_all $(wc -l <expect) 1
239 test_expect_success
'duplicate objects' '
240 git init duplicate-objects &&
242 cd duplicate-objects &&
244 git config pack.allowPackReuse multi &&
250 git rev-parse HEAD^{tree} >in &&
251 p="$(git pack-objects $packdir/pack <in)" &&
253 git multi-pack-index write --bitmap --preferred-pack=pack-$p.idx &&
255 objects_nr="$(git rev-list --count --all --objects)" &&
256 packs_nr="$(find $packdir -type f -name "pack-*.pack" | wc -l)" &&
258 test_pack_objects_reused_all $objects_nr $packs_nr