]> git.ipfire.org Git - thirdparty/git.git/blob - t/t7703-repack-geometric.sh
t/lib-gpg: require GPGSSH for GPGSSH_VERIFYTIME prereq
[thirdparty/git.git] / t / t7703-repack-geometric.sh
1 #!/bin/sh
2
3 test_description='git repack --geometric works correctly'
4
5 . ./test-lib.sh
6
7 GIT_TEST_MULTI_PACK_INDEX=0
8
9 objdir=.git/objects
10 packdir=$objdir/pack
11 midx=$objdir/pack/multi-pack-index
12
13 test_expect_success '--geometric with no packs' '
14 git init geometric &&
15 test_when_finished "rm -fr geometric" &&
16 (
17 cd geometric &&
18
19 git repack --write-midx --geometric 2 >out &&
20 test_i18ngrep "Nothing new to pack" out
21 )
22 '
23
24 test_expect_success '--geometric with one pack' '
25 git init geometric &&
26 test_when_finished "rm -fr geometric" &&
27 (
28 cd geometric &&
29
30 test_commit "base" &&
31 git repack -d &&
32
33 git repack --geometric 2 >out &&
34
35 test_i18ngrep "Nothing new to pack" out
36 )
37 '
38
39 test_expect_success '--geometric with an intact progression' '
40 git init geometric &&
41 test_when_finished "rm -fr geometric" &&
42 (
43 cd geometric &&
44
45 # These packs already form a geometric progression.
46 test_commit_bulk --start=1 1 && # 3 objects
47 test_commit_bulk --start=2 2 && # 6 objects
48 test_commit_bulk --start=4 4 && # 12 objects
49
50 find $objdir/pack -name "*.pack" | sort >expect &&
51 git repack --geometric 2 -d &&
52 find $objdir/pack -name "*.pack" | sort >actual &&
53
54 test_cmp expect actual
55 )
56 '
57
58 test_expect_success '--geometric with loose objects' '
59 git init geometric &&
60 test_when_finished "rm -fr geometric" &&
61 (
62 cd geometric &&
63
64 # These packs already form a geometric progression.
65 test_commit_bulk --start=1 1 && # 3 objects
66 test_commit_bulk --start=2 2 && # 6 objects
67 # The loose objects are packed together, breaking the
68 # progression.
69 test_commit loose && # 3 objects
70
71 find $objdir/pack -name "*.pack" | sort >before &&
72 git repack --geometric 2 -d &&
73 find $objdir/pack -name "*.pack" | sort >after &&
74
75 comm -13 before after >new &&
76 comm -23 before after >removed &&
77
78 test_line_count = 1 new &&
79 test_must_be_empty removed &&
80
81 git repack --geometric 2 -d &&
82 find $objdir/pack -name "*.pack" | sort >after &&
83
84 # The progression (3, 3, 6) is combined into one new pack.
85 test_line_count = 1 after
86 )
87 '
88
89 test_expect_success '--geometric with small-pack rollup' '
90 git init geometric &&
91 test_when_finished "rm -fr geometric" &&
92 (
93 cd geometric &&
94
95 test_commit_bulk --start=1 1 && # 3 objects
96 test_commit_bulk --start=2 1 && # 3 objects
97 find $objdir/pack -name "*.pack" | sort >small &&
98 test_commit_bulk --start=3 4 && # 12 objects
99 test_commit_bulk --start=7 8 && # 24 objects
100 find $objdir/pack -name "*.pack" | sort >before &&
101
102 git repack --geometric 2 -d &&
103
104 # Three packs in total; two of the existing large ones, and one
105 # new one.
106 find $objdir/pack -name "*.pack" | sort >after &&
107 test_line_count = 3 after &&
108 comm -3 small before | tr -d "\t" >large &&
109 grep -qFf large after
110 )
111 '
112
113 test_expect_success '--geometric with small- and large-pack rollup' '
114 git init geometric &&
115 test_when_finished "rm -fr geometric" &&
116 (
117 cd geometric &&
118
119 # size(small1) + size(small2) > size(medium) / 2
120 test_commit_bulk --start=1 1 && # 3 objects
121 test_commit_bulk --start=2 1 && # 3 objects
122 test_commit_bulk --start=2 3 && # 7 objects
123 test_commit_bulk --start=6 9 && # 27 objects &&
124
125 find $objdir/pack -name "*.pack" | sort >before &&
126
127 git repack --geometric 2 -d &&
128
129 find $objdir/pack -name "*.pack" | sort >after &&
130 comm -12 before after >untouched &&
131
132 # Two packs in total; the largest pack from before running "git
133 # repack", and one new one.
134 test_line_count = 1 untouched &&
135 test_line_count = 2 after
136 )
137 '
138
139 test_expect_success '--geometric ignores kept packs' '
140 git init geometric &&
141 test_when_finished "rm -fr geometric" &&
142 (
143 cd geometric &&
144
145 test_commit kept && # 3 objects
146 test_commit pack && # 3 objects
147
148 KEPT=$(git pack-objects --revs $objdir/pack/pack <<-EOF
149 refs/tags/kept
150 EOF
151 ) &&
152 PACK=$(git pack-objects --revs $objdir/pack/pack <<-EOF
153 refs/tags/pack
154 ^refs/tags/kept
155 EOF
156 ) &&
157
158 # neither pack contains more than twice the number of objects in
159 # the other, so they should be combined. but, marking one as
160 # .kept on disk will "freeze" it, so the pack structure should
161 # remain unchanged.
162 touch $objdir/pack/pack-$KEPT.keep &&
163
164 find $objdir/pack -name "*.pack" | sort >before &&
165 git repack --geometric 2 -d &&
166 find $objdir/pack -name "*.pack" | sort >after &&
167
168 # both packs should still exist
169 test_path_is_file $objdir/pack/pack-$KEPT.pack &&
170 test_path_is_file $objdir/pack/pack-$PACK.pack &&
171
172 # and no new packs should be created
173 test_cmp before after &&
174
175 # Passing --pack-kept-objects causes packs with a .keep file to
176 # be repacked, too.
177 git repack --geometric 2 -d --pack-kept-objects &&
178
179 # After repacking, two packs remain: one new one (containing the
180 # objects in both the .keep and non-kept pack), and the .keep
181 # pack (since `--pack-kept-objects -d` does not actually delete
182 # the kept pack).
183 find $objdir/pack -name "*.pack" >after &&
184 test_line_count = 2 after
185 )
186 '
187
188 test_expect_success '--geometric ignores --keep-pack packs' '
189 git init geometric &&
190 test_when_finished "rm -fr geometric" &&
191 (
192 cd geometric &&
193
194 # Create two equal-sized packs
195 test_commit kept && # 3 objects
196 git repack -d &&
197 test_commit pack && # 3 objects
198 git repack -d &&
199
200 find $objdir/pack -type f -name "*.pack" | sort >packs.before &&
201 git repack --geometric 2 -dm \
202 --keep-pack="$(basename "$(head -n 1 packs.before)")" >out &&
203 find $objdir/pack -type f -name "*.pack" | sort >packs.after &&
204
205 # Packs should not have changed (only one non-kept pack, no
206 # loose objects), but $midx should now exist.
207 grep "Nothing new to pack" out &&
208 test_path_is_file $midx &&
209
210 test_cmp packs.before packs.after &&
211
212 git fsck
213 )
214 '
215
216 test_expect_success '--geometric chooses largest MIDX preferred pack' '
217 git init geometric &&
218 test_when_finished "rm -fr geometric" &&
219 (
220 cd geometric &&
221
222 # These packs already form a geometric progression.
223 test_commit_bulk --start=1 1 && # 3 objects
224 test_commit_bulk --start=2 2 && # 6 objects
225 ls $objdir/pack/pack-*.idx >before &&
226 test_commit_bulk --start=4 4 && # 12 objects
227 ls $objdir/pack/pack-*.idx >after &&
228
229 git repack --geometric 2 -dbm &&
230
231 comm -3 before after | xargs -n 1 basename >expect &&
232 test-tool read-midx --preferred-pack $objdir >actual &&
233
234 test_cmp expect actual
235 )
236 '
237
238 test_expect_success '--geometric with pack.packSizeLimit' '
239 git init pack-rewrite &&
240 test_when_finished "rm -fr pack-rewrite" &&
241 (
242 cd pack-rewrite &&
243
244 test-tool genrandom foo 1048576 >foo &&
245 test-tool genrandom bar 1048576 >bar &&
246
247 git add foo bar &&
248 test_tick &&
249 git commit -m base &&
250
251 git rev-parse HEAD:foo HEAD:bar >p1.objects &&
252 git rev-parse HEAD HEAD^{tree} >p2.objects &&
253
254 # These two packs each contain two objects, so the following
255 # `--geometric` repack will try to combine them.
256 p1="$(git pack-objects $packdir/pack <p1.objects)" &&
257 p2="$(git pack-objects $packdir/pack <p2.objects)" &&
258
259 # Remove any loose objects in packs, since we do not want extra
260 # copies around (which would mask over potential object
261 # corruption issues).
262 git prune-packed &&
263
264 # Both p1 and p2 will be rolled up, but pack-objects will write
265 # three packs:
266 #
267 # - one containing object "foo",
268 # - another containing object "bar",
269 # - a final pack containing the commit and tree objects
270 # (identical to p2 above)
271 git repack --geometric 2 -d --max-pack-size=1048576 &&
272
273 # Ensure `repack` can detect that the third pack it wrote
274 # (containing just the tree and commit objects) was identical to
275 # one that was below the geometric split, so that we can save it
276 # from deletion.
277 #
278 # If `repack` fails to do that, we will incorrectly delete p2,
279 # causing object corruption.
280 git fsck
281 )
282 '
283
284 test_done