]> git.ipfire.org Git - thirdparty/git.git/blame - t/t7900-maintenance.sh
maintenance: add troubleshooting guide to docs
[thirdparty/git.git] / t / t7900-maintenance.sh
CommitLineData
2057d750
DS
1#!/bin/sh
2
3test_description='git maintenance builtin'
4
5. ./test-lib.sh
6
663b2b1b 7GIT_TEST_COMMIT_GRAPH=0
52fe41ff 8GIT_TEST_MULTI_PACK_INDEX=0
663b2b1b 9
2057d750
DS
10test_expect_success 'help text' '
11 test_expect_code 129 git maintenance -h 2>err &&
0c18b700 12 test_i18ngrep "usage: git maintenance <subcommand>" err &&
2057d750
DS
13 test_expect_code 128 git maintenance barf 2>err &&
14 test_i18ngrep "invalid subcommand: barf" err &&
15 test_expect_code 129 git maintenance 2>err &&
16 test_i18ngrep "usage: git maintenance" err
17'
18
3ddaad0e
DS
19test_expect_success 'run [--auto|--quiet]' '
20 GIT_TRACE2_EVENT="$(pwd)/run-no-auto.txt" \
21 git maintenance run 2>/dev/null &&
22 GIT_TRACE2_EVENT="$(pwd)/run-auto.txt" \
23 git maintenance run --auto 2>/dev/null &&
24 GIT_TRACE2_EVENT="$(pwd)/run-no-quiet.txt" \
25 git maintenance run --no-quiet 2>/dev/null &&
26 test_subcommand git gc --quiet <run-no-auto.txt &&
916d0626 27 test_subcommand ! git gc --auto --quiet <run-auto.txt &&
3ddaad0e 28 test_subcommand git gc --no-quiet <run-no-quiet.txt
2057d750
DS
29'
30
1942d483
DS
31test_expect_success 'maintenance.auto config option' '
32 GIT_TRACE2_EVENT="$(pwd)/default" git commit --quiet --allow-empty -m 1 &&
33 test_subcommand git maintenance run --auto --quiet <default &&
34 GIT_TRACE2_EVENT="$(pwd)/true" \
35 git -c maintenance.auto=true \
36 commit --quiet --allow-empty -m 2 &&
37 test_subcommand git maintenance run --auto --quiet <true &&
38 GIT_TRACE2_EVENT="$(pwd)/false" \
39 git -c maintenance.auto=false \
40 commit --quiet --allow-empty -m 3 &&
41 test_subcommand ! git maintenance run --auto --quiet <false
42'
43
65d655b5
DS
44test_expect_success 'maintenance.<task>.enabled' '
45 git config maintenance.gc.enabled false &&
46 git config maintenance.commit-graph.enabled true &&
47 GIT_TRACE2_EVENT="$(pwd)/run-config.txt" git maintenance run 2>err &&
48 test_subcommand ! git gc --quiet <run-config.txt &&
49 test_subcommand git commit-graph write --split --reachable --no-progress <run-config.txt
50'
51
090511bc
DS
52test_expect_success 'run --task=<task>' '
53 GIT_TRACE2_EVENT="$(pwd)/run-commit-graph.txt" \
54 git maintenance run --task=commit-graph 2>/dev/null &&
55 GIT_TRACE2_EVENT="$(pwd)/run-gc.txt" \
56 git maintenance run --task=gc 2>/dev/null &&
57 GIT_TRACE2_EVENT="$(pwd)/run-commit-graph.txt" \
58 git maintenance run --task=commit-graph 2>/dev/null &&
59 GIT_TRACE2_EVENT="$(pwd)/run-both.txt" \
60 git maintenance run --task=commit-graph --task=gc 2>/dev/null &&
61 test_subcommand ! git gc --quiet <run-commit-graph.txt &&
62 test_subcommand git gc --quiet <run-gc.txt &&
63 test_subcommand git gc --quiet <run-both.txt &&
64 test_subcommand git commit-graph write --split --reachable --no-progress <run-commit-graph.txt &&
65 test_subcommand ! git commit-graph write --split --reachable --no-progress <run-gc.txt &&
66 test_subcommand git commit-graph write --split --reachable --no-progress <run-both.txt
67'
68
69test_expect_success 'run --task=bogus' '
70 test_must_fail git maintenance run --task=bogus 2>err &&
71 test_i18ngrep "is not a valid task" err
72'
73
74test_expect_success 'run --task duplicate' '
75 test_must_fail git maintenance run --task=gc --task=gc 2>err &&
76 test_i18ngrep "cannot be selected multiple times" err
77'
78
28cb5e66
DS
79test_expect_success 'run --task=prefetch with no remotes' '
80 git maintenance run --task=prefetch 2>err &&
81 test_must_be_empty err
82'
83
84test_expect_success 'prefetch multiple remotes' '
85 git clone . clone1 &&
86 git clone . clone2 &&
87 git remote add remote1 "file://$(pwd)/clone1" &&
88 git remote add remote2 "file://$(pwd)/clone2" &&
89 git -C clone1 switch -c one &&
90 git -C clone2 switch -c two &&
91 test_commit -C clone1 one &&
92 test_commit -C clone2 two &&
93 GIT_TRACE2_EVENT="$(pwd)/run-prefetch.txt" git maintenance run --task=prefetch 2>/dev/null &&
94 fetchargs="--prune --no-tags --no-write-fetch-head --recurse-submodules=no --refmap= --quiet" &&
95 test_subcommand git fetch remote1 $fetchargs +refs/heads/\\*:refs/prefetch/remote1/\\* <run-prefetch.txt &&
96 test_subcommand git fetch remote2 $fetchargs +refs/heads/\\*:refs/prefetch/remote2/\\* <run-prefetch.txt &&
97 test_path_is_missing .git/refs/remotes &&
98 git log prefetch/remote1/one &&
99 git log prefetch/remote2/two &&
100 git fetch --all &&
101 test_cmp_rev refs/remotes/remote1/one refs/prefetch/remote1/one &&
102 test_cmp_rev refs/remotes/remote2/two refs/prefetch/remote2/two
103'
104
252cfb7c
DS
105test_expect_success 'loose-objects task' '
106 # Repack everything so we know the state of the object dir
107 git repack -adk &&
108
109 # Hack to stop maintenance from running during "git commit"
110 echo in use >.git/objects/maintenance.lock &&
111
112 # Assuming that "git commit" creates at least one loose object
113 test_commit create-loose-object &&
114 rm .git/objects/maintenance.lock &&
115
116 ls .git/objects >obj-dir-before &&
117 test_file_not_empty obj-dir-before &&
118 ls .git/objects/pack/*.pack >packs-before &&
119 test_line_count = 1 packs-before &&
120
121 # The first run creates a pack-file
122 # but does not delete loose objects.
123 git maintenance run --task=loose-objects &&
124 ls .git/objects >obj-dir-between &&
125 test_cmp obj-dir-before obj-dir-between &&
126 ls .git/objects/pack/*.pack >packs-between &&
127 test_line_count = 2 packs-between &&
128 ls .git/objects/pack/loose-*.pack >loose-packs &&
129 test_line_count = 1 loose-packs &&
130
131 # The second run deletes loose objects
132 # but does not create a pack-file.
133 git maintenance run --task=loose-objects &&
134 ls .git/objects >obj-dir-after &&
135 cat >expect <<-\EOF &&
136 info
137 pack
138 EOF
139 test_cmp expect obj-dir-after &&
140 ls .git/objects/pack/*.pack >packs-after &&
141 test_cmp packs-between packs-after
142'
143
3e220e60
DS
144test_expect_success 'maintenance.loose-objects.auto' '
145 git repack -adk &&
146 GIT_TRACE2_EVENT="$(pwd)/trace-lo1.txt" \
147 git -c maintenance.loose-objects.auto=1 maintenance \
148 run --auto --task=loose-objects 2>/dev/null &&
149 test_subcommand ! git prune-packed --quiet <trace-lo1.txt &&
150 printf data-A | git hash-object -t blob --stdin -w &&
151 GIT_TRACE2_EVENT="$(pwd)/trace-loA" \
152 git -c maintenance.loose-objects.auto=2 \
153 maintenance run --auto --task=loose-objects 2>/dev/null &&
154 test_subcommand ! git prune-packed --quiet <trace-loA &&
155 printf data-B | git hash-object -t blob --stdin -w &&
156 GIT_TRACE2_EVENT="$(pwd)/trace-loB" \
157 git -c maintenance.loose-objects.auto=2 \
158 maintenance run --auto --task=loose-objects 2>/dev/null &&
159 test_subcommand git prune-packed --quiet <trace-loB &&
160 GIT_TRACE2_EVENT="$(pwd)/trace-loC" \
161 git -c maintenance.loose-objects.auto=2 \
162 maintenance run --auto --task=loose-objects 2>/dev/null &&
163 test_subcommand git prune-packed --quiet <trace-loC
164'
165
52fe41ff
DS
166test_expect_success 'incremental-repack task' '
167 packDir=.git/objects/pack &&
168 for i in $(test_seq 1 5)
169 do
170 test_commit $i || return 1
171 done &&
172
173 # Create three disjoint pack-files with size BIG, small, small.
174 echo HEAD~2 | git pack-objects --revs $packDir/test-1 &&
175 test_tick &&
176 git pack-objects --revs $packDir/test-2 <<-\EOF &&
177 HEAD~1
178 ^HEAD~2
179 EOF
180 test_tick &&
181 git pack-objects --revs $packDir/test-3 <<-\EOF &&
182 HEAD
183 ^HEAD~1
184 EOF
185 rm -f $packDir/pack-* &&
186 rm -f $packDir/loose-* &&
187 ls $packDir/*.pack >packs-before &&
188 test_line_count = 3 packs-before &&
189
190 # the job repacks the two into a new pack, but does not
191 # delete the old ones.
192 git maintenance run --task=incremental-repack &&
193 ls $packDir/*.pack >packs-between &&
194 test_line_count = 4 packs-between &&
195
196 # the job deletes the two old packs, and does not write
a13e3d0e
DS
197 # a new one because the batch size is not high enough to
198 # pack the largest pack-file.
52fe41ff
DS
199 git maintenance run --task=incremental-repack &&
200 ls .git/objects/pack/*.pack >packs-after &&
a13e3d0e
DS
201 test_line_count = 2 packs-after
202'
203
204test_expect_success EXPENSIVE 'incremental-repack 2g limit' '
205 for i in $(test_seq 1 5)
206 do
207 test-tool genrandom foo$i $((512 * 1024 * 1024 + 1)) >>big ||
208 return 1
209 done &&
210 git add big &&
211 git commit -m "Add big file (1)" &&
212
213 # ensure any possible loose objects are in a pack-file
214 git maintenance run --task=loose-objects &&
215
216 rm big &&
217 for i in $(test_seq 6 10)
218 do
219 test-tool genrandom foo$i $((512 * 1024 * 1024 + 1)) >>big ||
220 return 1
221 done &&
222 git add big &&
223 git commit -m "Add big file (2)" &&
224
225 # ensure any possible loose objects are in a pack-file
226 git maintenance run --task=loose-objects &&
227
228 # Now run the incremental-repack task and check the batch-size
229 GIT_TRACE2_EVENT="$(pwd)/run-2g.txt" git maintenance run \
230 --task=incremental-repack 2>/dev/null &&
231 test_subcommand git multi-pack-index repack \
232 --no-progress --batch-size=2147483647 <run-2g.txt
52fe41ff
DS
233'
234
e841a79a
DS
235test_expect_success 'maintenance.incremental-repack.auto' '
236 git repack -adk &&
237 git config core.multiPackIndex true &&
238 git multi-pack-index write &&
239 GIT_TRACE2_EVENT="$(pwd)/midx-init.txt" git \
240 -c maintenance.incremental-repack.auto=1 \
241 maintenance run --auto --task=incremental-repack 2>/dev/null &&
242 test_subcommand ! git multi-pack-index write --no-progress <midx-init.txt &&
243 test_commit A &&
244 git pack-objects --revs .git/objects/pack/pack <<-\EOF &&
245 HEAD
246 ^HEAD~1
247 EOF
248 GIT_TRACE2_EVENT=$(pwd)/trace-A git \
249 -c maintenance.incremental-repack.auto=2 \
250 maintenance run --auto --task=incremental-repack 2>/dev/null &&
251 test_subcommand ! git multi-pack-index write --no-progress <trace-A &&
252 test_commit B &&
253 git pack-objects --revs .git/objects/pack/pack <<-\EOF &&
254 HEAD
255 ^HEAD~1
256 EOF
257 GIT_TRACE2_EVENT=$(pwd)/trace-B git \
258 -c maintenance.incremental-repack.auto=2 \
259 maintenance run --auto --task=incremental-repack 2>/dev/null &&
260 test_subcommand git multi-pack-index write --no-progress <trace-B
261'
262
b08ff1fe
DS
263test_expect_success '--auto and --schedule incompatible' '
264 test_must_fail git maintenance run --auto --schedule=daily 2>err &&
265 test_i18ngrep "at most one" err
266'
267
268test_expect_success 'invalid --schedule value' '
269 test_must_fail git maintenance run --schedule=annually 2>err &&
270 test_i18ngrep "unrecognized --schedule" err
271'
272
273test_expect_success '--schedule inheritance weekly -> daily -> hourly' '
274 git config maintenance.loose-objects.enabled true &&
275 git config maintenance.loose-objects.schedule hourly &&
276 git config maintenance.commit-graph.enabled true &&
277 git config maintenance.commit-graph.schedule daily &&
278 git config maintenance.incremental-repack.enabled true &&
279 git config maintenance.incremental-repack.schedule weekly &&
280
281 GIT_TRACE2_EVENT="$(pwd)/hourly.txt" \
282 git maintenance run --schedule=hourly 2>/dev/null &&
283 test_subcommand git prune-packed --quiet <hourly.txt &&
284 test_subcommand ! git commit-graph write --split --reachable \
285 --no-progress <hourly.txt &&
286 test_subcommand ! git multi-pack-index write --no-progress <hourly.txt &&
287
288 GIT_TRACE2_EVENT="$(pwd)/daily.txt" \
289 git maintenance run --schedule=daily 2>/dev/null &&
290 test_subcommand git prune-packed --quiet <daily.txt &&
291 test_subcommand git commit-graph write --split --reachable \
292 --no-progress <daily.txt &&
293 test_subcommand ! git multi-pack-index write --no-progress <daily.txt &&
294
295 GIT_TRACE2_EVENT="$(pwd)/weekly.txt" \
296 git maintenance run --schedule=weekly 2>/dev/null &&
297 test_subcommand git prune-packed --quiet <weekly.txt &&
298 test_subcommand git commit-graph write --split --reachable \
299 --no-progress <weekly.txt &&
300 test_subcommand git multi-pack-index write --no-progress <weekly.txt
301'
302
a4cb1a23
DS
303test_expect_success 'maintenance.strategy inheritance' '
304 for task in commit-graph loose-objects incremental-repack
305 do
306 git config --unset maintenance.$task.schedule || return 1
307 done &&
308
309 test_when_finished git config --unset maintenance.strategy &&
310 git config maintenance.strategy incremental &&
311
312 GIT_TRACE2_EVENT="$(pwd)/incremental-hourly.txt" \
313 git maintenance run --schedule=hourly --quiet &&
314 GIT_TRACE2_EVENT="$(pwd)/incremental-daily.txt" \
315 git maintenance run --schedule=daily --quiet &&
316
317 test_subcommand git commit-graph write --split --reachable \
318 --no-progress <incremental-hourly.txt &&
319 test_subcommand ! git prune-packed --quiet <incremental-hourly.txt &&
320 test_subcommand ! git multi-pack-index write --no-progress \
321 <incremental-hourly.txt &&
322
323 test_subcommand git commit-graph write --split --reachable \
324 --no-progress <incremental-daily.txt &&
325 test_subcommand git prune-packed --quiet <incremental-daily.txt &&
326 test_subcommand git multi-pack-index write --no-progress \
327 <incremental-daily.txt &&
328
329 # Modify defaults
330 git config maintenance.commit-graph.schedule daily &&
331 git config maintenance.loose-objects.schedule hourly &&
332 git config maintenance.incremental-repack.enabled false &&
333
334 GIT_TRACE2_EVENT="$(pwd)/modified-hourly.txt" \
335 git maintenance run --schedule=hourly --quiet &&
336 GIT_TRACE2_EVENT="$(pwd)/modified-daily.txt" \
337 git maintenance run --schedule=daily --quiet &&
338
339 test_subcommand ! git commit-graph write --split --reachable \
340 --no-progress <modified-hourly.txt &&
341 test_subcommand git prune-packed --quiet <modified-hourly.txt &&
342 test_subcommand ! git multi-pack-index write --no-progress \
343 <modified-hourly.txt &&
344
345 test_subcommand git commit-graph write --split --reachable \
346 --no-progress <modified-daily.txt &&
347 test_subcommand git prune-packed --quiet <modified-daily.txt &&
348 test_subcommand ! git multi-pack-index write --no-progress \
349 <modified-daily.txt
350'
351
0c18b700
DS
352test_expect_success 'register and unregister' '
353 test_when_finished git config --global --unset-all maintenance.repo &&
354 git config --global --add maintenance.repo /existing1 &&
355 git config --global --add maintenance.repo /existing2 &&
356 git config --global --get-all maintenance.repo >before &&
61f7a383 357
0c18b700 358 git maintenance register &&
61f7a383
DS
359 test_cmp_config false maintenance.auto &&
360 git config --global --get-all maintenance.repo >between &&
361 cp before expect &&
362 pwd >>expect &&
363 test_cmp expect between &&
364
0c18b700
DS
365 git maintenance unregister &&
366 git config --global --get-all maintenance.repo >actual &&
367 test_cmp before actual
368'
369
2fec604f
DS
370test_expect_success 'start from empty cron table' '
371 GIT_TEST_CRONTAB="test-tool crontab cron.txt" git maintenance start &&
372
373 # start registers the repo
374 git config --get --global maintenance.repo "$(pwd)" &&
375
376 grep "for-each-repo --config=maintenance.repo maintenance run --schedule=daily" cron.txt &&
377 grep "for-each-repo --config=maintenance.repo maintenance run --schedule=hourly" cron.txt &&
378 grep "for-each-repo --config=maintenance.repo maintenance run --schedule=weekly" cron.txt
379'
380
381test_expect_success 'stop from existing schedule' '
382 GIT_TEST_CRONTAB="test-tool crontab cron.txt" git maintenance stop &&
383
384 # stop does not unregister the repo
385 git config --get --global maintenance.repo "$(pwd)" &&
386
387 # Operation is idempotent
388 GIT_TEST_CRONTAB="test-tool crontab cron.txt" git maintenance stop &&
389 test_must_be_empty cron.txt
390'
391
392test_expect_success 'start preserves existing schedule' '
393 echo "Important information!" >cron.txt &&
394 GIT_TEST_CRONTAB="test-tool crontab cron.txt" git maintenance start &&
395 grep "Important information!" cron.txt
396'
397
61f7a383
DS
398test_expect_success 'register preserves existing strategy' '
399 git config maintenance.strategy none &&
400 git maintenance register &&
401 test_config maintenance.strategy none &&
402 git config --unset maintenance.strategy &&
403 git maintenance register &&
404 test_config maintenance.strategy incremental
405'
406
2057d750 407test_done