Merge branch 'vd/scalar-generalize-diagnose'
[alt-git.git] / t / t7703-repack-geometric.sh
blobda87f8b2d8822cd5f844cfb00bcdaf5c52117f79
1 #!/bin/sh
3 test_description='git repack --geometric works correctly'
5 . ./test-lib.sh
7 GIT_TEST_MULTI_PACK_INDEX=0
9 objdir=.git/objects
10 packdir=$objdir/pack
11 midx=$objdir/pack/multi-pack-index
13 test_expect_success '--geometric with no packs' '
14 git init geometric &&
15 test_when_finished "rm -fr geometric" &&
17 cd geometric &&
19 git repack --write-midx --geometric 2 >out &&
20 test_i18ngrep "Nothing new to pack" out
24 test_expect_success '--geometric with one pack' '
25 git init geometric &&
26 test_when_finished "rm -fr geometric" &&
28 cd geometric &&
30 test_commit "base" &&
31 git repack -d &&
33 git repack --geometric 2 >out &&
35 test_i18ngrep "Nothing new to pack" out
39 test_expect_success '--geometric with an intact progression' '
40 git init geometric &&
41 test_when_finished "rm -fr geometric" &&
43 cd geometric &&
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
50 find $objdir/pack -name "*.pack" | sort >expect &&
51 git repack --geometric 2 -d &&
52 find $objdir/pack -name "*.pack" | sort >actual &&
54 test_cmp expect actual
58 test_expect_success '--geometric with loose objects' '
59 git init geometric &&
60 test_when_finished "rm -fr geometric" &&
62 cd geometric &&
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
71 find $objdir/pack -name "*.pack" | sort >before &&
72 git repack --geometric 2 -d &&
73 find $objdir/pack -name "*.pack" | sort >after &&
75 comm -13 before after >new &&
76 comm -23 before after >removed &&
78 test_line_count = 1 new &&
79 test_must_be_empty removed &&
81 git repack --geometric 2 -d &&
82 find $objdir/pack -name "*.pack" | sort >after &&
84 # The progression (3, 3, 6) is combined into one new pack.
85 test_line_count = 1 after
89 test_expect_success '--geometric with small-pack rollup' '
90 git init geometric &&
91 test_when_finished "rm -fr geometric" &&
93 cd geometric &&
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 &&
102 git repack --geometric 2 -d &&
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
113 test_expect_success '--geometric with small- and large-pack rollup' '
114 git init geometric &&
115 test_when_finished "rm -fr geometric" &&
117 cd geometric &&
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 &&
125 find $objdir/pack -name "*.pack" | sort >before &&
127 git repack --geometric 2 -d &&
129 find $objdir/pack -name "*.pack" | sort >after &&
130 comm -12 before after >untouched &&
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
139 test_expect_success '--geometric ignores kept packs' '
140 git init geometric &&
141 test_when_finished "rm -fr geometric" &&
143 cd geometric &&
145 test_commit kept && # 3 objects
146 test_commit pack && # 3 objects
148 KEPT=$(git pack-objects --revs $objdir/pack/pack <<-EOF
149 refs/tags/kept
151 ) &&
152 PACK=$(git pack-objects --revs $objdir/pack/pack <<-EOF
153 refs/tags/pack
154 ^refs/tags/kept
156 ) &&
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 &&
164 find $objdir/pack -name "*.pack" | sort >before &&
165 git repack --geometric 2 -d &&
166 find $objdir/pack -name "*.pack" | sort >after &&
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 &&
172 # and no new packs should be created
173 test_cmp before after &&
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 &&
179 find $objdir/pack -name "*.pack" >after &&
180 test_line_count = 1 after
184 test_expect_success '--geometric ignores --keep-pack packs' '
185 git init geometric &&
186 test_when_finished "rm -fr geometric" &&
188 cd geometric &&
190 # Create two equal-sized packs
191 test_commit kept && # 3 objects
192 git repack -d &&
193 test_commit pack && # 3 objects
194 git repack -d &&
196 find $objdir/pack -type f -name "*.pack" | sort >packs.before &&
197 git repack --geometric 2 -dm \
198 --keep-pack="$(basename "$(head -n 1 packs.before)")" >out &&
199 find $objdir/pack -type f -name "*.pack" | sort >packs.after &&
201 # Packs should not have changed (only one non-kept pack, no
202 # loose objects), but $midx should now exist.
203 grep "Nothing new to pack" out &&
204 test_path_is_file $midx &&
206 test_cmp packs.before packs.after &&
208 git fsck
212 test_expect_success '--geometric chooses largest MIDX preferred pack' '
213 git init geometric &&
214 test_when_finished "rm -fr geometric" &&
216 cd geometric &&
218 # These packs already form a geometric progression.
219 test_commit_bulk --start=1 1 && # 3 objects
220 test_commit_bulk --start=2 2 && # 6 objects
221 ls $objdir/pack/pack-*.idx >before &&
222 test_commit_bulk --start=4 4 && # 12 objects
223 ls $objdir/pack/pack-*.idx >after &&
225 git repack --geometric 2 -dbm &&
227 comm -3 before after | xargs -n 1 basename >expect &&
228 test-tool read-midx --preferred-pack $objdir >actual &&
230 test_cmp expect actual
234 test_expect_success '--geometric with pack.packSizeLimit' '
235 git init pack-rewrite &&
236 test_when_finished "rm -fr pack-rewrite" &&
238 cd pack-rewrite &&
240 test-tool genrandom foo 1048576 >foo &&
241 test-tool genrandom bar 1048576 >bar &&
243 git add foo bar &&
244 test_tick &&
245 git commit -m base &&
247 git rev-parse HEAD:foo HEAD:bar >p1.objects &&
248 git rev-parse HEAD HEAD^{tree} >p2.objects &&
250 # These two packs each contain two objects, so the following
251 # `--geometric` repack will try to combine them.
252 p1="$(git pack-objects $packdir/pack <p1.objects)" &&
253 p2="$(git pack-objects $packdir/pack <p2.objects)" &&
255 # Remove any loose objects in packs, since we do not want extra
256 # copies around (which would mask over potential object
257 # corruption issues).
258 git prune-packed &&
260 # Both p1 and p2 will be rolled up, but pack-objects will write
261 # three packs:
263 # - one containing object "foo",
264 # - another containing object "bar",
265 # - a final pack containing the commit and tree objects
266 # (identical to p2 above)
267 git repack --geometric 2 -d --max-pack-size=1048576 &&
269 # Ensure `repack` can detect that the third pack it wrote
270 # (containing just the tree and commit objects) was identical to
271 # one that was below the geometric split, so that we can save it
272 # from deletion.
274 # If `repack` fails to do that, we will incorrectly delete p2,
275 # causing object corruption.
276 git fsck
280 test_done