Blob


1 #!/bin/sh
2 #
3 # Copyright (c) 2021 Stefan Sperling <stsp@openbsd.org>
4 #
5 # Permission to use, copy, modify, and distribute this software for any
6 # purpose with or without fee is hereby granted, provided that the above
7 # copyright notice and this permission notice appear in all copies.
8 #
9 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 . ./common.sh
19 # disable automatic packing for these tests
20 export GOT_TEST_PACK=""
22 test_cleanup_unreferenced_loose_objects() {
23 local testroot=`test_init cleanup_unreferenced_loose_objects`
25 nloose0=`gotadmin info -r $testroot/repo | grep '^loose objects:' | \
26 cut -d ':' -f 2 | tr -d ' '`
27 if [ "$nloose0" != "8" ]; then
28 echo "unexpected number of loose objects: $nloose0" >&2
29 test_done "$testroot" "1"
30 return 1
31 fi
33 # create a branch with some changes
34 got branch -r $testroot/repo newbranch >/dev/null
36 got checkout -b newbranch $testroot/repo $testroot/wt >/dev/null
37 ret=$?
38 if [ $ret -ne 0 ]; then
39 echo "got checkout command failed unexpectedly"
40 test_done "$testroot" "$ret"
41 return 1
42 fi
44 echo 'foo' > $testroot/wt/foo
45 (cd $testroot/wt && got add foo > /dev/null)
46 echo 'modified alpha' > $testroot/wt/alpha
47 (cd $testroot/wt && got commit -m 'newbranch commit' > /dev/null)
48 local commit1=`git_show_branch_head $testroot/repo newbranch`
49 local tree1=`got cat -r $testroot/repo $newbranch_commit | \
50 grep ^tree | cut -d ' ' -f2`
51 local alpha1=`got tree -r $testroot/repo -i -c $commit1 | \
52 grep "[0-9a-f] alpha$" | cut -d' ' -f 1`
53 local foo1=`got tree -r $testroot/repo -i -c $commit1 | \
54 grep "[0-9a-f] foo$" | cut -d' ' -f 1`
56 nloose1=`gotadmin info -r $testroot/repo | grep '^loose objects:' | \
57 cut -d ':' -f 2 | tr -d ' '`
58 if [ "$nloose1" != "12" ]; then
59 echo "unexpected number of loose objects: $nloose1" >&2
60 test_done "$testroot" "1"
61 return 1
62 fi
64 # delete the branch
65 got branch -r $testroot/repo -d newbranch >/dev/null
67 # remove worktree's base commit reference, which points at the branch
68 wt_uuid=`(cd $testroot/wt && got info | grep 'UUID:' | \
69 cut -d ':' -f 2 | tr -d ' ')`
70 got ref -r $testroot/repo -d "refs/got/worktree/base-$wt_uuid" \
71 > /dev/null
73 # cleanup -n should not remove any objects
74 ls -R $testroot/repo/.git/objects > $testroot/objects-before
75 gotadmin cleanup -a -n -q -r $testroot/repo > $testroot/stdout
76 echo -n > $testroot/stdout.expected
77 cmp -s $testroot/stdout.expected $testroot/stdout
78 ret=$?
79 if [ $ret -ne 0 ]; then
80 diff -u $testroot/stdout.expected $testroot/stdout
81 test_done "$testroot" "$ret"
82 return 1
83 fi
84 ls -R $testroot/repo/.git/objects > $testroot/objects-after
85 cmp -s $testroot/objects-before $testroot/objects-after
86 ret=$?
87 if [ $ret -ne 0 ]; then
88 diff -u $testroot/objects-before $testroot/objects-after
89 test_done "$testroot" "$ret"
90 return 1
91 fi
93 # cleanup should remove loose objects that belonged to the branch
94 gotadmin cleanup -a -q -r $testroot/repo > $testroot/stdout
95 ret=$?
96 if [ $ret -ne 0 ]; then
97 echo "gotadmin cleanup failed unexpectedly" >&2
98 test_done "$testroot" "$ret"
99 return 1
100 fi
101 echo -n > $testroot/stdout.expected
102 cmp -s $testroot/stdout.expected $testroot/stdout
103 ret=$?
104 if [ $ret -ne 0 ]; then
105 diff -u $testroot/stdout.expected $testroot/stdout
106 test_done "$testroot" "$ret"
107 return 1
108 fi
110 nloose2=`gotadmin info -r $testroot/repo | grep '^loose objects:' | \
111 cut -d ':' -f 2 | tr -d ' '`
112 if [ "$nloose2" != "$nloose0" ]; then
113 echo "unexpected number of loose objects: $nloose2" >&2
114 test_done "$testroot" "1"
115 return 1
116 fi
118 for id in $commit1 $tree1 $alpha1 $foo1; do
119 path=`get_loose_object_path $testroot/repo $id`
120 if [ -e "$path" ]; then
121 echo "loose object $path was not purged" >&2
122 ret=1
123 break
124 fi
125 done
127 test_done "$testroot" "$ret"
130 test_cleanup_redundant_loose_objects() {
131 local testroot=`test_init cleanup_redundant_loose_objects`
133 # tags should also be packed
134 got tag -r $testroot/repo -m 1.0 1.0 >/dev/null
136 nloose0=`gotadmin info -r $testroot/repo | grep '^loose objects:' | \
137 cut -d ':' -f 2 | tr -d ' '`
138 if [ "$nloose0" != "9" ]; then
139 echo "unexpected number of loose objects: $nloose0" >&2
140 test_done "$testroot" "1"
141 return 1
142 fi
144 # no pack files should exist yet
145 ls $testroot/repo/.git/objects/pack/ > $testroot/stdout
146 ret=$?
147 if [ $ret -ne 0 ]; then
148 test_done "$testroot" "$ret"
149 return 1
150 fi
151 echo -n > $testroot/stdout.expected
152 cmp -s $testroot/stdout.expected $testroot/stdout
153 ret=$?
154 if [ $ret -ne 0 ]; then
155 diff -u $testroot/stdout.expected $testroot/stdout
156 test_done "$testroot" "$ret"
157 return 1
158 fi
160 gotadmin pack -r $testroot/repo > /dev/null
162 npacked0=`gotadmin info -r $testroot/repo | grep '^packed objects:' | \
163 cut -d ':' -f 2 | tr -d ' '`
164 if [ "$npacked0" != "9" ]; then
165 echo "unexpected number of loose objects: $npacked0" >&2
166 test_done "$testroot" "1"
167 return 1
168 fi
170 # cleanup -n should not remove any objects
171 ls -R $testroot/repo/.git/objects > $testroot/objects-before
172 gotadmin cleanup -a -n -q -r $testroot/repo > $testroot/stdout
173 echo -n > $testroot/stdout.expected
174 cmp -s $testroot/stdout.expected $testroot/stdout
175 ret=$?
176 if [ $ret -ne 0 ]; then
177 diff -u $testroot/stdout.expected $testroot/stdout
178 test_done "$testroot" "$ret"
179 return 1
180 fi
181 ls -R $testroot/repo/.git/objects > $testroot/objects-after
182 cmp -s $testroot/objects-before $testroot/objects-after
183 ret=$?
184 if [ $ret -ne 0 ]; then
185 diff -u $testroot/objects-before $testroot/objects-after
186 test_done "$testroot" "$ret"
187 return 1
188 fi
190 nloose1=`gotadmin info -r $testroot/repo | grep '^loose objects:' | \
191 cut -d ':' -f 2 | tr -d ' '`
192 if [ "$nloose1" != "$nloose0" ]; then
193 echo "unexpected number of loose objects: $nloose1" >&2
194 test_done "$testroot" "1"
195 return 1
196 fi
198 # cleanup should remove all loose objects
199 gotadmin cleanup -a -q -r $testroot/repo > $testroot/stdout
200 ret=$?
201 if [ $ret -ne 0 ]; then
202 echo "gotadmin cleanup failed unexpectedly" >&2
203 test_done "$testroot" "$ret"
204 return 1
205 fi
206 echo -n > $testroot/stdout.expected
207 cmp -s $testroot/stdout.expected $testroot/stdout
208 ret=$?
209 if [ $ret -ne 0 ]; then
210 diff -u $testroot/stdout.expected $testroot/stdout
211 test_done "$testroot" "$ret"
212 return 1
213 fi
215 nloose2=`gotadmin info -r $testroot/repo | grep '^loose objects:' | \
216 cut -d ':' -f 2 | tr -d ' '`
217 if [ "$nloose2" != "0" ]; then
218 echo "unexpected number of loose objects: $nloose2" >&2
219 test_done "$testroot" "1"
220 return 1
221 fi
223 for d in $testroot/repo/.git/objects/[0-9a-f][0-9a-f]; do
224 id0=`basename $d`
225 ret=0
226 for e in `ls $d`; do
227 obj_id=${id0}${e}
228 echo "loose object $obj_id was not purged" >&2
229 ret=1
230 break
231 done
232 if [ $ret -eq 1 ]; then
233 break
234 fi
235 done
237 test_done "$testroot" "$ret"
240 test_cleanup_redundant_pack_files() {
241 local testroot=`test_init cleanup_redundant_pack_files`
243 # no pack files should exist yet
245 n=$(gotadmin info -r "$testroot/repo" | awk '/^pack files/{print $3}')
246 if [ "$n" -ne 0 ]; then
247 echo "expected no pack file to exists, $n found" >&2
248 test_done "$testroot" 1
249 return 1
250 fi
252 # create a redundant pack with an associated .keep file
253 hash=$(gotadmin pack -a -r "$testroot/repo" \
254 | awk '/^Indexed/{print $2}')
255 kpack="$testroot/repo/.git/objects/pack/pack-$hash"
256 touch "${kpack%.pack}.keep"
258 # create a few pack files with different objects
259 for i in `jot 5`; do
260 echo "alpha $i" > $testroot/repo/alpha
261 git_commit "$testroot/repo" -m "edit #$i"
262 gotadmin pack -r "$testroot/repo" >/dev/null
263 done
265 # create two packs with all the objects
266 gotadmin pack -a -r "$testroot/repo" >/dev/null
267 gotadmin pack -a -r "$testroot/repo" >/dev/null
269 gotadmin cleanup -r "$testroot/repo" | grep 'pack files? purged' \
270 | tail -1 > $testroot/stdout
272 echo "5 pack files purged" > $testroot/stdout.expected
273 if cmp -s "$testroot/stdout.expected" "$testroot/stdout"; then
274 diff -u "$testroot/stdout.expected" "$testroot/stdout"
275 test_done "$testroot" 1
276 return 1
277 fi
279 n=$(gotadmin info -r "$testroot/repo" | awk '/^pack files/{print $3}')
280 if [ "$n" -ne 2 ]; then
281 echo "expected 2 pack files left, $n found instead" >&2
282 test_done "$testroot" 1
283 return 1
284 fi
286 if [ ! -f "$kpack" ]; then
287 echo "$kpack disappeared unexpectedly" >&2
288 test_done "$testroot" 1
289 return 1
290 fi
292 if [ ! -f "${kpack%.pack}.keep" ]; then
293 echo "${kpack%.pack}.keep disappeared unexpectedly" >&2
294 test_done "$testroot" 1
295 return 1
296 fi
298 # create one more non-redundant pack
299 for i in `jot 5`; do
300 echo "alpha again $i" > $testroot/repo/alpha
301 git_commit "$testroot/repo" -m "edit $i"
302 done
303 gotadmin pack -r "$testroot/repo" >/dev/null
305 gotadmin cleanup -r "$testroot/repo" | grep 'pack files? purged' \
306 | tail -1 > $testroot/stdout
308 echo "0 pack files purged" > $testroot/stdout.expected
309 if cmp -s "$testroot/stdout.expected" "$testroot/stdout"; then
310 diff -u "$testroot/stdout.expected" "$testroot/stdout"
311 test_done "$testroot" 1
312 return 1
313 fi
315 n=$(gotadmin info -r "$testroot/repo" | awk '/^pack files/{print $3}')
316 if [ "$n" -ne 3 ]; then
317 echo "expected 3 pack files left, $n found instead" >&2
318 test_done "$testroot" 1
319 return 1
320 fi
322 # remove the .keep file
323 rm "${kpack%.pack}.keep"
325 # create some commits on a separate branch
326 (cd "$testroot/repo" && git checkout -q -b newbranch)
328 for i in `jot 5`; do
329 echo "alpha $i" > $testroot/repo/alpha
330 git_commit "$testroot/repo" -m "edit #$i"
331 gotadmin pack -r "$testroot/repo" >/dev/null
332 done
334 gotadmin pack -a -x master -r "$testroot/repo" >/dev/null
336 gotadmin cleanup -r "$testroot/repo" | grep 'pack files? purged' \
337 | tail -1 > $testroot/stdout
339 echo "6 pack files purged" > $testroot/stdout.expected
340 if cmp -s "$testroot/stdout.expected" "$testroot/stdout"; then
341 diff -u "$testroot/stdout.expected" "$testroot/stdout"
342 test_done "$testroot" 1
343 return 1
344 fi
346 n=$(gotadmin info -r "$testroot/repo" | awk '/^pack files/{print $3}')
347 if [ "$n" -ne 3 ]; then
348 echo "expected 3 pack files left, $n found instead" >&2
349 test_done "$testroot" 1
350 return 1
351 fi
353 test_done "$testroot" 0
356 test_cleanup_precious_objects() {
357 local testroot=`test_init cleanup_precious_objects`
359 # enable Git's preciousObjects extension
360 (cd $testroot/repo && git config extensions.preciousObjects true)
362 # cleanup should now refuse to purge objects
363 gotadmin cleanup -a -q -r $testroot/repo > $testroot/stdout \
364 2> $testroot/stderr
365 ret=$?
366 if [ $ret -eq 0 ]; then
367 echo "gotadmin cleanup succeeded unexpectedly" >&2
368 test_done "$testroot" "1"
369 return 1
370 fi
372 echo -n "gotadmin: the preciousObjects Git extension is enabled; " \
373 > $testroot/stderr.expected
374 echo "this implies that objects must not be deleted" \
375 >> $testroot/stderr.expected
376 cmp -s $testroot/stderr.expected $testroot/stderr
377 ret=$?
378 if [ $ret -ne 0 ]; then
379 diff -u $testroot/stderr.expected $testroot/stderr
380 fi
381 test_done "$testroot" "$ret"
384 test_cleanup_missing_pack_file() {
385 local testroot=`test_init cleanup_missing_pack_file`
387 # no pack files should exist yet
388 ls $testroot/repo/.git/objects/pack/ > $testroot/stdout
389 ret=$?
390 if [ $ret -ne 0 ]; then
391 test_done "$testroot" "$ret"
392 return 1
393 fi
394 echo -n > $testroot/stdout.expected
395 cmp -s $testroot/stdout.expected $testroot/stdout
396 ret=$?
397 if [ $ret -ne 0 ]; then
398 diff -u $testroot/stdout.expected $testroot/stdout
399 test_done "$testroot" "$ret"
400 return 1
401 fi
403 gotadmin pack -r $testroot/repo > $testroot/stdout
404 packname=`grep ^Wrote $testroot/stdout | cut -d ' ' -f2`
405 packhash=`echo $packname | sed -e 's:^objects/pack/pack-::' \
406 -e 's/.pack$//'`
408 # Some freshly cloned Git repositories suffer from lonely pack index
409 # files. Remove the pack file we just wrote to simulate this issue.
410 rm -f $testroot/repo/.git/objects/pack/pack-$packname
412 # cleanup should now refuse to purge objects
413 gotadmin cleanup -a -q -r $testroot/repo > $testroot/stdout \
414 2> $testroot/stderr
415 ret=$?
416 if [ $ret -eq 0 ]; then
417 echo "gotadmin cleanup succeeded unexpectedly" >&2
418 test_done "$testroot" "1"
419 return 1
420 fi
422 echo -n "gotadmin: objects/pack/pack-${packhash}.idx: " \
423 > $testroot/stderr.expected
424 echo -n "pack index has no corresponding pack file; pack file must " \
425 >> $testroot/stderr.expected
426 echo "be restored or 'gotadmin cleanup -p' must be run" \
427 >> $testroot/stderr.expected
428 cmp -s $testroot/stderr.expected $testroot/stderr
429 ret=$?
430 if [ $ret -ne 0 ]; then
431 diff -u $testroot/stderr.expected $testroot/stderr
432 test_done "$testroot" "$ret"
433 return 1
434 fi
436 gotadmin cleanup -a -r $testroot/repo -p -n > $testroot/stdout
437 ret=$?
438 if [ $ret -ne 0 ]; then
439 echo "gotadmin cleanup failed unexpectedly" >&2
440 test_done "$testroot" "$ret"
441 return 1
442 fi
443 packidx_path=$testroot/repo/.git/objects/pack/pack-${packhash}.idx
444 echo "$packidx_path could be removed" > $testroot/stdout.expected
445 cmp -s $testroot/stdout.expected $testroot/stdout
446 ret=$?
447 if [ $ret -ne 0 ]; then
448 diff -u $testroot/stdout.expected $testroot/stdout
449 test_done "$testroot" "$ret"
450 return 1
451 fi
453 gotadmin cleanup -a -r $testroot/repo -p > $testroot/stdout
454 ret=$?
455 if [ $ret -ne 0 ]; then
456 echo "gotadmin cleanup failed unexpectedly" >&2
457 test_done "$testroot" "$ret"
458 return 1
459 fi
460 echo "$packidx_path removed" > $testroot/stdout.expected
461 cmp -s $testroot/stdout.expected $testroot/stdout
462 ret=$?
463 if [ $ret -ne 0 ]; then
464 diff -u $testroot/stdout.expected $testroot/stdout
465 test_done "$testroot" "$ret"
466 return 1
467 fi
469 # cleanup should now attempt to purge objects
470 gotadmin cleanup -a -q -r $testroot/repo > $testroot/stdout \
471 2> $testroot/stderr
472 ret=$?
473 if [ $ret -ne 0 ]; then
474 echo "gotadmin cleanup failed unexpectedly" >&2
475 test_done "$testroot" "1"
476 return 1
477 fi
478 test_done "$testroot" "$ret"
481 test_parseargs "$@"
482 run_test test_cleanup_unreferenced_loose_objects
483 run_test test_cleanup_redundant_loose_objects
484 run_test test_cleanup_redundant_pack_files
485 run_test test_cleanup_precious_objects
486 run_test test_cleanup_missing_pack_file