Merge branch 'jk/pack-idx-corruption-safety'
[git] / t / t7300-clean.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2007 Michael Spang
4 #
5
6 test_description='git clean basic tests'
7
8 . ./test-lib.sh
9
10 git config clean.requireForce no
11
12 test_expect_success 'setup' '
13
14         mkdir -p src &&
15         touch src/part1.c Makefile &&
16         echo build >.gitignore &&
17         echo \*.o >>.gitignore &&
18         git add . &&
19         git commit -m setup &&
20         touch src/part2.c README &&
21         git add .
22
23 '
24
25 test_expect_success 'git clean with skip-worktree .gitignore' '
26         git update-index --skip-worktree .gitignore &&
27         rm .gitignore &&
28         mkdir -p build docs &&
29         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
30         git clean &&
31         test -f Makefile &&
32         test -f README &&
33         test -f src/part1.c &&
34         test -f src/part2.c &&
35         test ! -f a.out &&
36         test ! -f src/part3.c &&
37         test -f docs/manual.txt &&
38         test -f obj.o &&
39         test -f build/lib.so &&
40         git update-index --no-skip-worktree .gitignore &&
41         git checkout .gitignore
42 '
43
44 test_expect_success 'git clean' '
45
46         mkdir -p build docs &&
47         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
48         git clean &&
49         test -f Makefile &&
50         test -f README &&
51         test -f src/part1.c &&
52         test -f src/part2.c &&
53         test ! -f a.out &&
54         test ! -f src/part3.c &&
55         test -f docs/manual.txt &&
56         test -f obj.o &&
57         test -f build/lib.so
58
59 '
60
61 test_expect_success 'git clean src/' '
62
63         mkdir -p build docs &&
64         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
65         git clean src/ &&
66         test -f Makefile &&
67         test -f README &&
68         test -f src/part1.c &&
69         test -f src/part2.c &&
70         test -f a.out &&
71         test ! -f src/part3.c &&
72         test -f docs/manual.txt &&
73         test -f obj.o &&
74         test -f build/lib.so
75
76 '
77
78 test_expect_success 'git clean src/ src/' '
79
80         mkdir -p build docs &&
81         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
82         git clean src/ src/ &&
83         test -f Makefile &&
84         test -f README &&
85         test -f src/part1.c &&
86         test -f src/part2.c &&
87         test -f a.out &&
88         test ! -f src/part3.c &&
89         test -f docs/manual.txt &&
90         test -f obj.o &&
91         test -f build/lib.so
92
93 '
94
95 test_expect_success 'git clean with prefix' '
96
97         mkdir -p build docs src/test &&
98         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so src/test/1.c &&
99         (cd src/ && git clean) &&
100         test -f Makefile &&
101         test -f README &&
102         test -f src/part1.c &&
103         test -f src/part2.c &&
104         test -f a.out &&
105         test ! -f src/part3.c &&
106         test -f src/test/1.c &&
107         test -f docs/manual.txt &&
108         test -f obj.o &&
109         test -f build/lib.so
110
111 '
112
113 test_expect_success C_LOCALE_OUTPUT 'git clean with relative prefix' '
114
115         mkdir -p build docs &&
116         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
117         would_clean=$(
118                 cd docs &&
119                 git clean -n ../src |
120                 sed -n -e "s|^Would remove ||p"
121         ) &&
122         verbose test "$would_clean" = ../src/part3.c
123 '
124
125 test_expect_success C_LOCALE_OUTPUT 'git clean with absolute path' '
126
127         mkdir -p build docs &&
128         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
129         would_clean=$(
130                 cd docs &&
131                 git clean -n "$(pwd)/../src" |
132                 sed -n -e "s|^Would remove ||p"
133         ) &&
134         verbose test "$would_clean" = ../src/part3.c
135 '
136
137 test_expect_success 'git clean with out of work tree relative path' '
138
139         mkdir -p build docs &&
140         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
141         (
142                 cd docs &&
143                 test_must_fail git clean -n ../..
144         )
145 '
146
147 test_expect_success 'git clean with out of work tree absolute path' '
148
149         mkdir -p build docs &&
150         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
151         dd=$(cd .. && pwd) &&
152         (
153                 cd docs &&
154                 test_must_fail git clean -n $dd
155         )
156 '
157
158 test_expect_success 'git clean -d with prefix and path' '
159
160         mkdir -p build docs src/feature &&
161         touch a.out src/part3.c src/feature/file.c docs/manual.txt obj.o build/lib.so &&
162         (cd src/ && git clean -d feature/) &&
163         test -f Makefile &&
164         test -f README &&
165         test -f src/part1.c &&
166         test -f src/part2.c &&
167         test -f a.out &&
168         test -f src/part3.c &&
169         test ! -f src/feature/file.c &&
170         test -f docs/manual.txt &&
171         test -f obj.o &&
172         test -f build/lib.so
173
174 '
175
176 test_expect_success SYMLINKS 'git clean symbolic link' '
177
178         mkdir -p build docs &&
179         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
180         ln -s docs/manual.txt src/part4.c &&
181         git clean &&
182         test -f Makefile &&
183         test -f README &&
184         test -f src/part1.c &&
185         test -f src/part2.c &&
186         test ! -f a.out &&
187         test ! -f src/part3.c &&
188         test ! -f src/part4.c &&
189         test -f docs/manual.txt &&
190         test -f obj.o &&
191         test -f build/lib.so
192
193 '
194
195 test_expect_success 'git clean with wildcard' '
196
197         touch a.clean b.clean other.c &&
198         git clean "*.clean" &&
199         test -f Makefile &&
200         test -f README &&
201         test -f src/part1.c &&
202         test -f src/part2.c &&
203         test ! -f a.clean &&
204         test ! -f b.clean &&
205         test -f other.c
206
207 '
208
209 test_expect_success 'git clean -n' '
210
211         mkdir -p build docs &&
212         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
213         git clean -n &&
214         test -f Makefile &&
215         test -f README &&
216         test -f src/part1.c &&
217         test -f src/part2.c &&
218         test -f a.out &&
219         test -f src/part3.c &&
220         test -f docs/manual.txt &&
221         test -f obj.o &&
222         test -f build/lib.so
223
224 '
225
226 test_expect_success 'git clean -d' '
227
228         mkdir -p build docs &&
229         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
230         git clean -d &&
231         test -f Makefile &&
232         test -f README &&
233         test -f src/part1.c &&
234         test -f src/part2.c &&
235         test ! -f a.out &&
236         test ! -f src/part3.c &&
237         test ! -d docs &&
238         test -f obj.o &&
239         test -f build/lib.so
240
241 '
242
243 test_expect_success 'git clean -d src/ examples/' '
244
245         mkdir -p build docs examples &&
246         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so examples/1.c &&
247         git clean -d src/ examples/ &&
248         test -f Makefile &&
249         test -f README &&
250         test -f src/part1.c &&
251         test -f src/part2.c &&
252         test -f a.out &&
253         test ! -f src/part3.c &&
254         test ! -f examples/1.c &&
255         test -f docs/manual.txt &&
256         test -f obj.o &&
257         test -f build/lib.so
258
259 '
260
261 test_expect_success 'git clean -x' '
262
263         mkdir -p build docs &&
264         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
265         git clean -x &&
266         test -f Makefile &&
267         test -f README &&
268         test -f src/part1.c &&
269         test -f src/part2.c &&
270         test ! -f a.out &&
271         test ! -f src/part3.c &&
272         test -f docs/manual.txt &&
273         test ! -f obj.o &&
274         test -f build/lib.so
275
276 '
277
278 test_expect_success 'git clean -d -x' '
279
280         mkdir -p build docs &&
281         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
282         git clean -d -x &&
283         test -f Makefile &&
284         test -f README &&
285         test -f src/part1.c &&
286         test -f src/part2.c &&
287         test ! -f a.out &&
288         test ! -f src/part3.c &&
289         test ! -d docs &&
290         test ! -f obj.o &&
291         test ! -d build
292
293 '
294
295 test_expect_success 'git clean -d -x with ignored tracked directory' '
296
297         mkdir -p build docs &&
298         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
299         git clean -d -x -e src &&
300         test -f Makefile &&
301         test -f README &&
302         test -f src/part1.c &&
303         test -f src/part2.c &&
304         test ! -f a.out &&
305         test -f src/part3.c &&
306         test ! -d docs &&
307         test ! -f obj.o &&
308         test ! -d build
309
310 '
311
312 test_expect_success 'git clean -X' '
313
314         mkdir -p build docs &&
315         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
316         git clean -X &&
317         test -f Makefile &&
318         test -f README &&
319         test -f src/part1.c &&
320         test -f src/part2.c &&
321         test -f a.out &&
322         test -f src/part3.c &&
323         test -f docs/manual.txt &&
324         test ! -f obj.o &&
325         test -f build/lib.so
326
327 '
328
329 test_expect_success 'git clean -d -X' '
330
331         mkdir -p build docs &&
332         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
333         git clean -d -X &&
334         test -f Makefile &&
335         test -f README &&
336         test -f src/part1.c &&
337         test -f src/part2.c &&
338         test -f a.out &&
339         test -f src/part3.c &&
340         test -f docs/manual.txt &&
341         test ! -f obj.o &&
342         test ! -d build
343
344 '
345
346 test_expect_success 'git clean -d -X with ignored tracked directory' '
347
348         mkdir -p build docs &&
349         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
350         git clean -d -X -e src &&
351         test -f Makefile &&
352         test -f README &&
353         test -f src/part1.c &&
354         test -f src/part2.c &&
355         test -f a.out &&
356         test ! -f src/part3.c &&
357         test -f docs/manual.txt &&
358         test ! -f obj.o &&
359         test ! -d build
360
361 '
362
363 test_expect_success 'clean.requireForce defaults to true' '
364
365         git config --unset clean.requireForce &&
366         test_must_fail git clean
367
368 '
369
370 test_expect_success 'clean.requireForce' '
371
372         git config clean.requireForce true &&
373         test_must_fail git clean
374
375 '
376
377 test_expect_success 'clean.requireForce and -n' '
378
379         mkdir -p build docs &&
380         touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
381         git clean -n &&
382         test -f Makefile &&
383         test -f README &&
384         test -f src/part1.c &&
385         test -f src/part2.c &&
386         test -f a.out &&
387         test -f src/part3.c &&
388         test -f docs/manual.txt &&
389         test -f obj.o &&
390         test -f build/lib.so
391
392 '
393
394 test_expect_success 'clean.requireForce and -f' '
395
396         git clean -f &&
397         test -f README &&
398         test -f src/part1.c &&
399         test -f src/part2.c &&
400         test ! -f a.out &&
401         test ! -f src/part3.c &&
402         test -f docs/manual.txt &&
403         test -f obj.o &&
404         test -f build/lib.so
405
406 '
407
408 test_expect_success C_LOCALE_OUTPUT 'core.excludesfile' '
409
410         echo excludes >excludes &&
411         echo included >included &&
412         git config core.excludesfile excludes &&
413         output=$(git clean -n excludes included 2>&1) &&
414         expr "$output" : ".*included" >/dev/null &&
415         ! expr "$output" : ".*excludes" >/dev/null
416
417 '
418
419 test_expect_success SANITY 'removal failure' '
420
421         mkdir foo &&
422         touch foo/bar &&
423         test_when_finished "chmod 755 foo" &&
424         (exec <foo/bar &&
425          chmod 0 foo &&
426          test_must_fail git clean -f -d)
427 '
428
429 test_expect_success 'nested git work tree' '
430         rm -fr foo bar baz &&
431         mkdir -p foo bar baz/boo &&
432         (
433                 cd foo &&
434                 git init &&
435                 test_commit nested hello.world
436         ) &&
437         (
438                 cd bar &&
439                 >goodbye.people
440         ) &&
441         (
442                 cd baz/boo &&
443                 git init &&
444                 test_commit deeply.nested deeper.world
445         ) &&
446         git clean -f -d &&
447         test -f foo/.git/index &&
448         test -f foo/hello.world &&
449         test -f baz/boo/.git/index &&
450         test -f baz/boo/deeper.world &&
451         ! test -d bar
452 '
453
454 test_expect_success 'should clean things that almost look like git but are not' '
455         rm -fr almost_git almost_bare_git almost_submodule &&
456         mkdir -p almost_git/.git/objects &&
457         mkdir -p almost_git/.git/refs &&
458         cat >almost_git/.git/HEAD <<-\EOF &&
459         garbage
460         EOF
461         cp -r almost_git/.git/ almost_bare_git &&
462         mkdir almost_submodule/ &&
463         cat >almost_submodule/.git <<-\EOF &&
464         garbage
465         EOF
466         test_when_finished "rm -rf almost_*" &&
467         git clean -f -d &&
468         test_path_is_missing almost_git &&
469         test_path_is_missing almost_bare_git &&
470         test_path_is_missing almost_submodule
471 '
472
473 test_expect_success 'should not clean submodules' '
474         rm -fr repo to_clean sub1 sub2 &&
475         mkdir repo to_clean &&
476         (
477                 cd repo &&
478                 git init &&
479                 test_commit msg hello.world
480         ) &&
481         git submodule add ./repo/.git sub1 &&
482         git commit -m "sub1" &&
483         git branch before_sub2 &&
484         git submodule add ./repo/.git sub2 &&
485         git commit -m "sub2" &&
486         git checkout before_sub2 &&
487         >to_clean/should_clean.this &&
488         git clean -f -d &&
489         test_path_is_file repo/.git/index &&
490         test_path_is_file repo/hello.world &&
491         test_path_is_file sub1/.git &&
492         test_path_is_file sub1/hello.world &&
493         test_path_is_file sub2/.git &&
494         test_path_is_file sub2/hello.world &&
495         test_path_is_missing to_clean
496 '
497
498 test_expect_success POSIXPERM,SANITY 'should avoid cleaning possible submodules' '
499         rm -fr to_clean possible_sub1 &&
500         mkdir to_clean possible_sub1 &&
501         test_when_finished "rm -rf possible_sub*" &&
502         echo "gitdir: foo" >possible_sub1/.git &&
503         >possible_sub1/hello.world &&
504         chmod 0 possible_sub1/.git &&
505         >to_clean/should_clean.this &&
506         git clean -f -d &&
507         test_path_is_file possible_sub1/.git &&
508         test_path_is_file possible_sub1/hello.world &&
509         test_path_is_missing to_clean
510 '
511
512 test_expect_success 'nested (empty) git should be kept' '
513         rm -fr empty_repo to_clean &&
514         git init empty_repo &&
515         mkdir to_clean &&
516         >to_clean/should_clean.this &&
517         git clean -f -d &&
518         test_path_is_file empty_repo/.git/HEAD &&
519         test_path_is_missing to_clean
520 '
521
522 test_expect_success 'nested bare repositories should be cleaned' '
523         rm -fr bare1 bare2 subdir &&
524         git init --bare bare1 &&
525         git clone --local --bare . bare2 &&
526         mkdir subdir &&
527         cp -r bare2 subdir/bare3 &&
528         git clean -f -d &&
529         test_path_is_missing bare1 &&
530         test_path_is_missing bare2 &&
531         test_path_is_missing subdir
532 '
533
534 test_expect_failure 'nested (empty) bare repositories should be cleaned even when in .git' '
535         rm -fr strange_bare &&
536         mkdir strange_bare &&
537         git init --bare strange_bare/.git &&
538         git clean -f -d &&
539         test_path_is_missing strange_bare
540 '
541
542 test_expect_failure 'nested (non-empty) bare repositories should be cleaned even when in .git' '
543         rm -fr strange_bare &&
544         mkdir strange_bare &&
545         git clone --local --bare . strange_bare/.git &&
546         git clean -f -d &&
547         test_path_is_missing strange_bare
548 '
549
550 test_expect_success 'giving path in nested git work tree will remove it' '
551         rm -fr repo &&
552         mkdir repo &&
553         (
554                 cd repo &&
555                 git init &&
556                 mkdir -p bar/baz &&
557                 test_commit msg bar/baz/hello.world
558         ) &&
559         git clean -f -d repo/bar/baz &&
560         test_path_is_file repo/.git/HEAD &&
561         test_path_is_dir repo/bar/ &&
562         test_path_is_missing repo/bar/baz
563 '
564
565 test_expect_success 'giving path to nested .git will not remove it' '
566         rm -fr repo &&
567         mkdir repo untracked &&
568         (
569                 cd repo &&
570                 git init &&
571                 test_commit msg hello.world
572         ) &&
573         git clean -f -d repo/.git &&
574         test_path_is_file repo/.git/HEAD &&
575         test_path_is_dir repo/.git/refs &&
576         test_path_is_dir repo/.git/objects &&
577         test_path_is_dir untracked/
578 '
579
580 test_expect_success 'giving path to nested .git/ will remove contents' '
581         rm -fr repo untracked &&
582         mkdir repo untracked &&
583         (
584                 cd repo &&
585                 git init &&
586                 test_commit msg hello.world
587         ) &&
588         git clean -f -d repo/.git/ &&
589         test_path_is_dir repo/.git &&
590         test_dir_is_empty repo/.git &&
591         test_path_is_dir untracked/
592 '
593
594 test_expect_success 'force removal of nested git work tree' '
595         rm -fr foo bar baz &&
596         mkdir -p foo bar baz/boo &&
597         (
598                 cd foo &&
599                 git init &&
600                 test_commit nested hello.world
601         ) &&
602         (
603                 cd bar &&
604                 >goodbye.people
605         ) &&
606         (
607                 cd baz/boo &&
608                 git init &&
609                 test_commit deeply.nested deeper.world
610         ) &&
611         git clean -f -f -d &&
612         ! test -d foo &&
613         ! test -d bar &&
614         ! test -d baz
615 '
616
617 test_expect_success 'git clean -e' '
618         rm -fr repo &&
619         mkdir repo &&
620         (
621                 cd repo &&
622                 git init &&
623                 touch known 1 2 3 &&
624                 git add known &&
625                 git clean -f -e 1 -e 2 &&
626                 test -e 1 &&
627                 test -e 2 &&
628                 ! (test -e 3) &&
629                 test -e known
630         )
631 '
632
633 test_expect_success SANITY 'git clean -d with an unreadable empty directory' '
634         mkdir foo &&
635         chmod a= foo &&
636         git clean -dfx foo &&
637         ! test -d foo
638 '
639
640 test_expect_success 'git clean -d respects pathspecs (dir is prefix of pathspec)' '
641         mkdir -p foo &&
642         mkdir -p foobar &&
643         git clean -df foobar &&
644         test_path_is_dir foo &&
645         test_path_is_missing foobar
646 '
647
648 test_expect_success 'git clean -d respects pathspecs (pathspec is prefix of dir)' '
649         mkdir -p foo &&
650         mkdir -p foobar &&
651         git clean -df foo &&
652         test_path_is_missing foo &&
653         test_path_is_dir foobar
654 '
655
656 test_expect_success 'git clean -d skips untracked dirs containing ignored files' '
657         echo /foo/bar >.gitignore &&
658         echo ignoreme >>.gitignore &&
659         rm -rf foo &&
660         mkdir -p foo/a/aa/aaa foo/b/bb/bbb &&
661         touch foo/bar foo/baz foo/a/aa/ignoreme foo/b/ignoreme foo/b/bb/1 foo/b/bb/2 &&
662         git clean -df &&
663         test_path_is_dir foo &&
664         test_path_is_file foo/bar &&
665         test_path_is_missing foo/baz &&
666         test_path_is_file foo/a/aa/ignoreme &&
667         test_path_is_missing foo/a/aa/aaa &&
668         test_path_is_file foo/b/ignoreme &&
669         test_path_is_missing foo/b/bb
670 '
671
672 test_done