3 # Copyright (c) 2007 Michael Spang
6 test_description='git clean basic tests'
10 git config clean.requireForce no
12 test_expect_success 'setup' '
15 touch src/part1.c Makefile &&
16 echo build >.gitignore &&
17 echo \*.o >>.gitignore &&
19 git commit -m setup &&
20 touch src/part2.c README &&
25 test_expect_success 'git clean with skip-worktree .gitignore' '
26 git update-index --skip-worktree .gitignore &&
28 mkdir -p build docs &&
29 touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
33 test -f src/part1.c &&
34 test -f src/part2.c &&
36 test ! -f src/part3.c &&
37 test -f docs/manual.txt &&
39 test -f build/lib.so &&
40 git update-index --no-skip-worktree .gitignore &&
41 git checkout .gitignore
44 test_expect_success 'git clean' '
46 mkdir -p build docs &&
47 touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
51 test -f src/part1.c &&
52 test -f src/part2.c &&
54 test ! -f src/part3.c &&
55 test -f docs/manual.txt &&
61 test_expect_success 'git clean src/' '
63 mkdir -p build docs &&
64 touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
68 test -f src/part1.c &&
69 test -f src/part2.c &&
71 test ! -f src/part3.c &&
72 test -f docs/manual.txt &&
78 test_expect_success 'git clean src/ src/' '
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/ &&
85 test -f src/part1.c &&
86 test -f src/part2.c &&
88 test ! -f src/part3.c &&
89 test -f docs/manual.txt &&
95 test_expect_success 'git clean with prefix' '
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) &&
102 test -f src/part1.c &&
103 test -f src/part2.c &&
105 test ! -f src/part3.c &&
106 test -f src/test/1.c &&
107 test -f docs/manual.txt &&
113 test_expect_success C_LOCALE_OUTPUT 'git clean with relative prefix' '
115 mkdir -p build docs &&
116 touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
119 git clean -n ../src |
120 sed -n -e "s|^Would remove ||p"
122 verbose test "$would_clean" = ../src/part3.c
125 test_expect_success C_LOCALE_OUTPUT 'git clean with absolute path' '
127 mkdir -p build docs &&
128 touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
131 git clean -n "$(pwd)/../src" |
132 sed -n -e "s|^Would remove ||p"
134 verbose test "$would_clean" = ../src/part3.c
137 test_expect_success 'git clean with out of work tree relative path' '
139 mkdir -p build docs &&
140 touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
143 test_must_fail git clean -n ../..
147 test_expect_success 'git clean with out of work tree absolute path' '
149 mkdir -p build docs &&
150 touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
151 dd=$(cd .. && pwd) &&
154 test_must_fail git clean -n $dd
158 test_expect_success 'git clean -d with prefix and path' '
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/) &&
165 test -f src/part1.c &&
166 test -f src/part2.c &&
168 test -f src/part3.c &&
169 test ! -f src/feature/file.c &&
170 test -f docs/manual.txt &&
176 test_expect_success SYMLINKS 'git clean symbolic link' '
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 &&
184 test -f src/part1.c &&
185 test -f src/part2.c &&
187 test ! -f src/part3.c &&
188 test ! -f src/part4.c &&
189 test -f docs/manual.txt &&
195 test_expect_success 'git clean with wildcard' '
197 touch a.clean b.clean other.c &&
198 git clean "*.clean" &&
201 test -f src/part1.c &&
202 test -f src/part2.c &&
209 test_expect_success 'git clean -n' '
211 mkdir -p build docs &&
212 touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
216 test -f src/part1.c &&
217 test -f src/part2.c &&
219 test -f src/part3.c &&
220 test -f docs/manual.txt &&
226 test_expect_success 'git clean -d' '
228 mkdir -p build docs &&
229 touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
233 test -f src/part1.c &&
234 test -f src/part2.c &&
236 test ! -f src/part3.c &&
243 test_expect_success 'git clean -d src/ examples/' '
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/ &&
250 test -f src/part1.c &&
251 test -f src/part2.c &&
253 test ! -f src/part3.c &&
254 test ! -f examples/1.c &&
255 test -f docs/manual.txt &&
261 test_expect_success 'git clean -x' '
263 mkdir -p build docs &&
264 touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
268 test -f src/part1.c &&
269 test -f src/part2.c &&
271 test ! -f src/part3.c &&
272 test -f docs/manual.txt &&
278 test_expect_success 'git clean -d -x' '
280 mkdir -p build docs &&
281 touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
285 test -f src/part1.c &&
286 test -f src/part2.c &&
288 test ! -f src/part3.c &&
295 test_expect_success 'git clean -d -x with ignored tracked directory' '
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 &&
302 test -f src/part1.c &&
303 test -f src/part2.c &&
305 test -f src/part3.c &&
312 test_expect_success 'git clean -X' '
314 mkdir -p build docs &&
315 touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
319 test -f src/part1.c &&
320 test -f src/part2.c &&
322 test -f src/part3.c &&
323 test -f docs/manual.txt &&
329 test_expect_success 'git clean -d -X' '
331 mkdir -p build docs &&
332 touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
336 test -f src/part1.c &&
337 test -f src/part2.c &&
339 test -f src/part3.c &&
340 test -f docs/manual.txt &&
346 test_expect_success 'git clean -d -X with ignored tracked directory' '
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 &&
353 test -f src/part1.c &&
354 test -f src/part2.c &&
356 test ! -f src/part3.c &&
357 test -f docs/manual.txt &&
363 test_expect_success 'clean.requireForce defaults to true' '
365 git config --unset clean.requireForce &&
366 test_must_fail git clean
370 test_expect_success 'clean.requireForce' '
372 git config clean.requireForce true &&
373 test_must_fail git clean
377 test_expect_success 'clean.requireForce and -n' '
379 mkdir -p build docs &&
380 touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
384 test -f src/part1.c &&
385 test -f src/part2.c &&
387 test -f src/part3.c &&
388 test -f docs/manual.txt &&
394 test_expect_success 'clean.requireForce and -f' '
398 test -f src/part1.c &&
399 test -f src/part2.c &&
401 test ! -f src/part3.c &&
402 test -f docs/manual.txt &&
408 test_expect_success C_LOCALE_OUTPUT 'core.excludesfile' '
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
419 test_expect_success SANITY 'removal failure' '
423 test_when_finished "chmod 755 foo" &&
426 test_must_fail git clean -f -d)
429 test_expect_success 'nested git work tree' '
430 rm -fr foo bar baz &&
431 mkdir -p foo bar baz/boo &&
435 test_commit nested hello.world
444 test_commit deeply.nested deeper.world
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 &&
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 &&
461 cp -r almost_git/.git/ almost_bare_git &&
462 mkdir almost_submodule/ &&
463 cat >almost_submodule/.git <<-\EOF &&
466 test_when_finished "rm -rf almost_*" &&
468 test_path_is_missing almost_git &&
469 test_path_is_missing almost_bare_git &&
470 test_path_is_missing almost_submodule
473 test_expect_success 'should not clean submodules' '
474 rm -fr repo to_clean sub1 sub2 &&
475 mkdir repo to_clean &&
479 test_commit msg hello.world
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 &&
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
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 &&
507 test_path_is_file possible_sub1/.git &&
508 test_path_is_file possible_sub1/hello.world &&
509 test_path_is_missing to_clean
512 test_expect_success 'nested (empty) git should be kept' '
513 rm -fr empty_repo to_clean &&
514 git init empty_repo &&
516 >to_clean/should_clean.this &&
518 test_path_is_file empty_repo/.git/HEAD &&
519 test_path_is_missing to_clean
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 &&
527 cp -r bare2 subdir/bare3 &&
529 test_path_is_missing bare1 &&
530 test_path_is_missing bare2 &&
531 test_path_is_missing subdir
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 &&
539 test_path_is_missing strange_bare
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 &&
547 test_path_is_missing strange_bare
550 test_expect_success 'giving path in nested git work tree will remove it' '
557 test_commit msg bar/baz/hello.world
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
565 test_expect_success 'giving path to nested .git will not remove it' '
567 mkdir repo untracked &&
571 test_commit msg hello.world
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/
580 test_expect_success 'giving path to nested .git/ will remove contents' '
581 rm -fr repo untracked &&
582 mkdir repo untracked &&
586 test_commit msg hello.world
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/
594 test_expect_success 'force removal of nested git work tree' '
595 rm -fr foo bar baz &&
596 mkdir -p foo bar baz/boo &&
600 test_commit nested hello.world
609 test_commit deeply.nested deeper.world
611 git clean -f -f -d &&
617 test_expect_success 'git clean -e' '
625 git clean -f -e 1 -e 2 &&
633 test_expect_success SANITY 'git clean -d with an unreadable empty directory' '
636 git clean -dfx foo &&
640 test_expect_success 'git clean -d respects pathspecs (dir is prefix of pathspec)' '
643 git clean -df foobar &&
644 test_path_is_dir foo &&
645 test_path_is_missing foobar
648 test_expect_success 'git clean -d respects pathspecs (pathspec is prefix of dir)' '
652 test_path_is_missing foo &&
653 test_path_is_dir foobar
656 test_expect_success 'git clean -d skips untracked dirs containing ignored files' '
657 echo /foo/bar >.gitignore &&
658 echo ignoreme >>.gitignore &&
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 &&
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