t / t7300-clean.shon commit Merge branch 'rs/path-name-safety-cleanup' (3bf7d37)
   1#!/bin/sh
   2#
   3# Copyright (c) 2007 Michael Spang
   4#
   5
   6test_description='git clean basic tests'
   7
   8. ./test-lib.sh
   9
  10git config clean.requireForce no
  11
  12test_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
  25test_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
  44test_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
  61test_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
  78test_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
  95test_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
 113test_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
 125test_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
 137test_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
 147test_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
 158test_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
 176test_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
 195test_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
 209test_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
 226test_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
 243test_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
 261test_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
 278test_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
 295test_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
 312test_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
 329test_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
 346test_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
 363test_expect_success 'clean.requireForce defaults to true' '
 364
 365        git config --unset clean.requireForce &&
 366        test_must_fail git clean
 367
 368'
 369
 370test_expect_success 'clean.requireForce' '
 371
 372        git config clean.requireForce true &&
 373        test_must_fail git clean
 374
 375'
 376
 377test_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
 394test_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
 408test_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
 419test_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
 429test_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
 454test_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
 473test_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
 498test_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
 512test_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
 522test_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
 534test_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
 542test_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
 550test_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
 565test_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
 580test_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
 594test_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
 617test_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
 633test_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
 640test_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
 648test_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
 656test_done