]> git.ipfire.org Git - thirdparty/git.git/blob - t/t5332-multi-pack-reuse.sh
Merge branch 'jh/sparse-index-expand-to-path-fix'
[thirdparty/git.git] / t / t5332-multi-pack-reuse.sh
1 #!/bin/sh
2
3 test_description='pack-objects multi-pack reuse'
4
5 TEST_PASSES_SANITIZE_LEAK=true
6 . ./test-lib.sh
7 . "$TEST_DIRECTORY"/lib-bitmap.sh
8
9 objdir=.git/objects
10 packdir=$objdir/pack
11
12 test_pack_reused () {
13 test_trace2_data pack-objects pack-reused "$1"
14 }
15
16 test_packs_reused () {
17 test_trace2_data pack-objects packs-reused "$1"
18 }
19
20
21 # pack_position <object> </path/to/pack.idx
22 pack_position () {
23 git show-index >objects &&
24 grep "$1" objects | cut -d" " -f1
25 }
26
27 test_expect_success 'preferred pack is reused for single-pack reuse' '
28 test_config pack.allowPackReuse single &&
29
30 for i in A B
31 do
32 test_commit "$i" &&
33 git repack -d || return 1
34 done &&
35
36 git multi-pack-index write --bitmap &&
37
38 : >trace2.txt &&
39 GIT_TRACE2_EVENT="$PWD/trace2.txt" \
40 git pack-objects --stdout --revs --all >/dev/null &&
41
42 test_pack_reused 3 <trace2.txt &&
43 test_packs_reused 1 <trace2.txt
44 '
45
46 test_expect_success 'enable multi-pack reuse' '
47 git config pack.allowPackReuse multi
48 '
49
50 test_expect_success 'reuse all objects from subset of bitmapped packs' '
51 test_commit C &&
52 git repack -d &&
53
54 git multi-pack-index write --bitmap &&
55
56 cat >in <<-EOF &&
57 $(git rev-parse C)
58 ^$(git rev-parse A)
59 EOF
60
61 : >trace2.txt &&
62 GIT_TRACE2_EVENT="$PWD/trace2.txt" \
63 git pack-objects --stdout --revs <in >/dev/null &&
64
65 test_pack_reused 6 <trace2.txt &&
66 test_packs_reused 2 <trace2.txt
67 '
68
69 test_expect_success 'reuse all objects from all packs' '
70 : >trace2.txt &&
71 GIT_TRACE2_EVENT="$PWD/trace2.txt" \
72 git pack-objects --stdout --revs --all >/dev/null &&
73
74 test_pack_reused 9 <trace2.txt &&
75 test_packs_reused 3 <trace2.txt
76 '
77
78 test_expect_success 'reuse objects from first pack with middle gap' '
79 for i in D E F
80 do
81 test_commit "$i" || return 1
82 done &&
83
84 # Set "pack.window" to zero to ensure that we do not create any
85 # deltas, which could alter the amount of pack reuse we perform
86 # (if, for e.g., we are not sending one or more bases).
87 D="$(git -c pack.window=0 pack-objects --all --unpacked $packdir/pack)" &&
88
89 d_pos="$(pack_position $(git rev-parse D) <$packdir/pack-$D.idx)" &&
90 e_pos="$(pack_position $(git rev-parse E) <$packdir/pack-$D.idx)" &&
91 f_pos="$(pack_position $(git rev-parse F) <$packdir/pack-$D.idx)" &&
92
93 # commits F, E, and D, should appear in that order at the
94 # beginning of the pack
95 test $f_pos -lt $e_pos &&
96 test $e_pos -lt $d_pos &&
97
98 # Ensure that the pack we are constructing sorts ahead of any
99 # other packs in lexical/bitmap order by choosing it as the
100 # preferred pack.
101 git multi-pack-index write --bitmap --preferred-pack="pack-$D.idx" &&
102
103 cat >in <<-EOF &&
104 $(git rev-parse E)
105 ^$(git rev-parse D)
106 EOF
107
108 : >trace2.txt &&
109 GIT_TRACE2_EVENT="$PWD/trace2.txt" \
110 git pack-objects --stdout --delta-base-offset --revs <in >/dev/null &&
111
112 test_pack_reused 3 <trace2.txt &&
113 test_packs_reused 1 <trace2.txt
114 '
115
116 test_expect_success 'reuse objects from middle pack with middle gap' '
117 rm -fr $packdir/multi-pack-index* &&
118
119 # Ensure that the pack we are constructing sort into any
120 # position *but* the first one, by choosing a different pack as
121 # the preferred one.
122 git multi-pack-index write --bitmap --preferred-pack="pack-$A.idx" &&
123
124 cat >in <<-EOF &&
125 $(git rev-parse E)
126 ^$(git rev-parse D)
127 EOF
128
129 : >trace2.txt &&
130 GIT_TRACE2_EVENT="$PWD/trace2.txt" \
131 git pack-objects --stdout --delta-base-offset --revs <in >/dev/null &&
132
133 test_pack_reused 3 <trace2.txt &&
134 test_packs_reused 1 <trace2.txt
135 '
136
137 test_expect_success 'omit delta with uninteresting base (same pack)' '
138 git repack -adk &&
139
140 test_seq 32 >f &&
141 git add f &&
142 test_tick &&
143 git commit -m "delta" &&
144 delta="$(git rev-parse HEAD)" &&
145
146 test_seq 64 >f &&
147 test_tick &&
148 git commit -a -m "base" &&
149 base="$(git rev-parse HEAD)" &&
150
151 test_commit other &&
152
153 git repack -d &&
154
155 have_delta "$(git rev-parse $delta:f)" "$(git rev-parse $base:f)" &&
156
157 git multi-pack-index write --bitmap &&
158
159 cat >in <<-EOF &&
160 $(git rev-parse other)
161 ^$base
162 EOF
163
164 : >trace2.txt &&
165 GIT_TRACE2_EVENT="$PWD/trace2.txt" \
166 git pack-objects --stdout --delta-base-offset --revs <in >/dev/null &&
167
168 # We can only reuse the 3 objects corresponding to "other" from
169 # the latest pack.
170 #
171 # This is because even though we want "delta", we do not want
172 # "base", meaning that we have to inflate the delta/base-pair
173 # corresponding to the blob in commit "delta", which bypasses
174 # the pack-reuse mechanism.
175 #
176 # The remaining objects from the other pack are similarly not
177 # reused because their objects are on the uninteresting side of
178 # the query.
179 test_pack_reused 3 <trace2.txt &&
180 test_packs_reused 1 <trace2.txt
181 '
182
183 test_expect_success 'omit delta from uninteresting base (cross pack)' '
184 cat >in <<-EOF &&
185 $(git rev-parse $base)
186 ^$(git rev-parse $delta)
187 EOF
188
189 P="$(git pack-objects --revs $packdir/pack <in)" &&
190
191 git multi-pack-index write --bitmap --preferred-pack="pack-$P.idx" &&
192
193 : >trace2.txt &&
194 GIT_TRACE2_EVENT="$PWD/trace2.txt" \
195 git pack-objects --stdout --delta-base-offset --all >/dev/null &&
196
197 packs_nr="$(find $packdir -type f -name "pack-*.pack" | wc -l)" &&
198 objects_nr="$(git rev-list --count --all --objects)" &&
199
200 test_pack_reused $(($objects_nr - 1)) <trace2.txt &&
201 test_packs_reused $packs_nr <trace2.txt
202 '
203
204 test_done