t / t7063-status-untracked-cache.shon commit Merge branch 'rs/perf-repeat-thrice-by-default' (74735c9)
   1#!/bin/sh
   2
   3test_description='test untracked cache'
   4
   5. ./test-lib.sh
   6
   7# On some filesystems (e.g. FreeBSD's ext2 and ufs) directory mtime
   8# is updated lazily after contents in the directory changes, which
   9# forces the untracked cache code to take the slow path.  A test
  10# that wants to make sure that the fast path works correctly should
  11# call this helper to make mtime of the containing directory in sync
  12# with the reality before checking the fast path behaviour.
  13#
  14# See <20160803174522.5571-1-pclouds@gmail.com> if you want to know
  15# more.
  16
  17sync_mtime () {
  18        find . -type d -ls >/dev/null
  19}
  20
  21avoid_racy() {
  22        sleep 1
  23}
  24
  25status_is_clean() {
  26        >../status.expect &&
  27        git status --porcelain >../status.actual &&
  28        test_cmp ../status.expect ../status.actual
  29}
  30
  31test_lazy_prereq UNTRACKED_CACHE '
  32        { git update-index --test-untracked-cache; ret=$?; } &&
  33        test $ret -ne 1
  34'
  35
  36if ! test_have_prereq UNTRACKED_CACHE; then
  37        skip_all='This system does not support untracked cache'
  38        test_done
  39fi
  40
  41test_expect_success 'core.untrackedCache is unset' '
  42        test_must_fail git config --get core.untrackedCache
  43'
  44
  45test_expect_success 'setup' '
  46        git init worktree &&
  47        cd worktree &&
  48        mkdir done dtwo dthree &&
  49        touch one two three done/one dtwo/two dthree/three &&
  50        git add one two done/one &&
  51        : >.git/info/exclude &&
  52        git update-index --untracked-cache
  53'
  54
  55test_expect_success 'untracked cache is empty' '
  56        test-dump-untracked-cache >../actual &&
  57        cat >../expect-empty <<EOF &&
  58info/exclude 0000000000000000000000000000000000000000
  59core.excludesfile 0000000000000000000000000000000000000000
  60exclude_per_dir .gitignore
  61flags 00000006
  62EOF
  63        test_cmp ../expect-empty ../actual
  64'
  65
  66cat >../status.expect <<EOF &&
  67A  done/one
  68A  one
  69A  two
  70?? dthree/
  71?? dtwo/
  72?? three
  73EOF
  74
  75cat >../dump.expect <<EOF &&
  76info/exclude $EMPTY_BLOB
  77core.excludesfile 0000000000000000000000000000000000000000
  78exclude_per_dir .gitignore
  79flags 00000006
  80/ 0000000000000000000000000000000000000000 recurse valid
  81dthree/
  82dtwo/
  83three
  84/done/ 0000000000000000000000000000000000000000 recurse valid
  85/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
  86three
  87/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
  88two
  89EOF
  90
  91test_expect_success 'status first time (empty cache)' '
  92        avoid_racy &&
  93        : >../trace &&
  94        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
  95        git status --porcelain >../actual &&
  96        test_cmp ../status.expect ../actual &&
  97        cat >../trace.expect <<EOF &&
  98node creation: 3
  99gitignore invalidation: 1
 100directory invalidation: 0
 101opendir: 4
 102EOF
 103        test_cmp ../trace.expect ../trace
 104'
 105
 106test_expect_success 'untracked cache after first status' '
 107        test-dump-untracked-cache >../actual &&
 108        test_cmp ../dump.expect ../actual
 109'
 110
 111test_expect_success 'status second time (fully populated cache)' '
 112        avoid_racy &&
 113        : >../trace &&
 114        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 115        git status --porcelain >../actual &&
 116        test_cmp ../status.expect ../actual &&
 117        cat >../trace.expect <<EOF &&
 118node creation: 0
 119gitignore invalidation: 0
 120directory invalidation: 0
 121opendir: 0
 122EOF
 123        test_cmp ../trace.expect ../trace
 124'
 125
 126test_expect_success 'untracked cache after second status' '
 127        test-dump-untracked-cache >../actual &&
 128        test_cmp ../dump.expect ../actual
 129'
 130
 131test_expect_success 'modify in root directory, one dir invalidation' '
 132        avoid_racy &&
 133        : >four &&
 134        : >../trace &&
 135        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 136        git status --porcelain >../actual &&
 137        cat >../status.expect <<EOF &&
 138A  done/one
 139A  one
 140A  two
 141?? dthree/
 142?? dtwo/
 143?? four
 144?? three
 145EOF
 146        test_cmp ../status.expect ../actual &&
 147        cat >../trace.expect <<EOF &&
 148node creation: 0
 149gitignore invalidation: 0
 150directory invalidation: 1
 151opendir: 1
 152EOF
 153        test_cmp ../trace.expect ../trace
 154
 155'
 156
 157test_expect_success 'verify untracked cache dump' '
 158        test-dump-untracked-cache >../actual &&
 159        cat >../expect <<EOF &&
 160info/exclude $EMPTY_BLOB
 161core.excludesfile 0000000000000000000000000000000000000000
 162exclude_per_dir .gitignore
 163flags 00000006
 164/ 0000000000000000000000000000000000000000 recurse valid
 165dthree/
 166dtwo/
 167four
 168three
 169/done/ 0000000000000000000000000000000000000000 recurse valid
 170/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 171three
 172/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 173two
 174EOF
 175        test_cmp ../expect ../actual
 176'
 177
 178test_expect_success 'new .gitignore invalidates recursively' '
 179        avoid_racy &&
 180        echo four >.gitignore &&
 181        : >../trace &&
 182        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 183        git status --porcelain >../actual &&
 184        cat >../status.expect <<EOF &&
 185A  done/one
 186A  one
 187A  two
 188?? .gitignore
 189?? dthree/
 190?? dtwo/
 191?? three
 192EOF
 193        test_cmp ../status.expect ../actual &&
 194        cat >../trace.expect <<EOF &&
 195node creation: 0
 196gitignore invalidation: 1
 197directory invalidation: 1
 198opendir: 4
 199EOF
 200        test_cmp ../trace.expect ../trace
 201
 202'
 203
 204test_expect_success 'verify untracked cache dump' '
 205        test-dump-untracked-cache >../actual &&
 206        cat >../expect <<EOF &&
 207info/exclude $EMPTY_BLOB
 208core.excludesfile 0000000000000000000000000000000000000000
 209exclude_per_dir .gitignore
 210flags 00000006
 211/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
 212.gitignore
 213dthree/
 214dtwo/
 215three
 216/done/ 0000000000000000000000000000000000000000 recurse valid
 217/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 218three
 219/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 220two
 221EOF
 222        test_cmp ../expect ../actual
 223'
 224
 225test_expect_success 'new info/exclude invalidates everything' '
 226        avoid_racy &&
 227        echo three >>.git/info/exclude &&
 228        : >../trace &&
 229        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 230        git status --porcelain >../actual &&
 231        cat >../status.expect <<EOF &&
 232A  done/one
 233A  one
 234A  two
 235?? .gitignore
 236?? dtwo/
 237EOF
 238        test_cmp ../status.expect ../actual &&
 239        cat >../trace.expect <<EOF &&
 240node creation: 0
 241gitignore invalidation: 1
 242directory invalidation: 0
 243opendir: 4
 244EOF
 245        test_cmp ../trace.expect ../trace
 246'
 247
 248test_expect_success 'verify untracked cache dump' '
 249        test-dump-untracked-cache >../actual &&
 250        cat >../expect <<EOF &&
 251info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
 252core.excludesfile 0000000000000000000000000000000000000000
 253exclude_per_dir .gitignore
 254flags 00000006
 255/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
 256.gitignore
 257dtwo/
 258/done/ 0000000000000000000000000000000000000000 recurse valid
 259/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 260/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 261two
 262EOF
 263        test_cmp ../expect ../actual
 264'
 265
 266test_expect_success 'move two from tracked to untracked' '
 267        git rm --cached two &&
 268        test-dump-untracked-cache >../actual &&
 269        cat >../expect <<EOF &&
 270info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
 271core.excludesfile 0000000000000000000000000000000000000000
 272exclude_per_dir .gitignore
 273flags 00000006
 274/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse
 275/done/ 0000000000000000000000000000000000000000 recurse valid
 276/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 277/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 278two
 279EOF
 280        test_cmp ../expect ../actual
 281'
 282
 283test_expect_success 'status after the move' '
 284        : >../trace &&
 285        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 286        git status --porcelain >../actual &&
 287        cat >../status.expect <<EOF &&
 288A  done/one
 289A  one
 290?? .gitignore
 291?? dtwo/
 292?? two
 293EOF
 294        test_cmp ../status.expect ../actual &&
 295        cat >../trace.expect <<EOF &&
 296node creation: 0
 297gitignore invalidation: 0
 298directory invalidation: 0
 299opendir: 1
 300EOF
 301        test_cmp ../trace.expect ../trace
 302'
 303
 304test_expect_success 'verify untracked cache dump' '
 305        test-dump-untracked-cache >../actual &&
 306        cat >../expect <<EOF &&
 307info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
 308core.excludesfile 0000000000000000000000000000000000000000
 309exclude_per_dir .gitignore
 310flags 00000006
 311/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
 312.gitignore
 313dtwo/
 314two
 315/done/ 0000000000000000000000000000000000000000 recurse valid
 316/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 317/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 318two
 319EOF
 320        test_cmp ../expect ../actual
 321'
 322
 323test_expect_success 'move two from untracked to tracked' '
 324        git add two &&
 325        test-dump-untracked-cache >../actual &&
 326        cat >../expect <<EOF &&
 327info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
 328core.excludesfile 0000000000000000000000000000000000000000
 329exclude_per_dir .gitignore
 330flags 00000006
 331/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse
 332/done/ 0000000000000000000000000000000000000000 recurse valid
 333/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 334/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 335two
 336EOF
 337        test_cmp ../expect ../actual
 338'
 339
 340test_expect_success 'status after the move' '
 341        : >../trace &&
 342        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 343        git status --porcelain >../actual &&
 344        cat >../status.expect <<EOF &&
 345A  done/one
 346A  one
 347A  two
 348?? .gitignore
 349?? dtwo/
 350EOF
 351        test_cmp ../status.expect ../actual &&
 352        cat >../trace.expect <<EOF &&
 353node creation: 0
 354gitignore invalidation: 0
 355directory invalidation: 0
 356opendir: 1
 357EOF
 358        test_cmp ../trace.expect ../trace
 359'
 360
 361test_expect_success 'verify untracked cache dump' '
 362        test-dump-untracked-cache >../actual &&
 363        cat >../expect <<EOF &&
 364info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
 365core.excludesfile 0000000000000000000000000000000000000000
 366exclude_per_dir .gitignore
 367flags 00000006
 368/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
 369.gitignore
 370dtwo/
 371/done/ 0000000000000000000000000000000000000000 recurse valid
 372/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 373/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 374two
 375EOF
 376        test_cmp ../expect ../actual
 377'
 378
 379test_expect_success 'set up for sparse checkout testing' '
 380        echo two >done/.gitignore &&
 381        echo three >>done/.gitignore &&
 382        echo two >done/two &&
 383        git add -f done/two done/.gitignore &&
 384        git commit -m "first commit"
 385'
 386
 387test_expect_success 'status after commit' '
 388        : >../trace &&
 389        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 390        git status --porcelain >../actual &&
 391        cat >../status.expect <<EOF &&
 392?? .gitignore
 393?? dtwo/
 394EOF
 395        test_cmp ../status.expect ../actual &&
 396        cat >../trace.expect <<EOF &&
 397node creation: 0
 398gitignore invalidation: 0
 399directory invalidation: 0
 400opendir: 2
 401EOF
 402        test_cmp ../trace.expect ../trace
 403'
 404
 405test_expect_success 'untracked cache correct after commit' '
 406        test-dump-untracked-cache >../actual &&
 407        cat >../expect <<EOF &&
 408info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
 409core.excludesfile 0000000000000000000000000000000000000000
 410exclude_per_dir .gitignore
 411flags 00000006
 412/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
 413.gitignore
 414dtwo/
 415/done/ 0000000000000000000000000000000000000000 recurse valid
 416/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 417/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 418two
 419EOF
 420        test_cmp ../expect ../actual
 421'
 422
 423test_expect_success 'set up sparse checkout' '
 424        echo "done/[a-z]*" >.git/info/sparse-checkout &&
 425        test_config core.sparsecheckout true &&
 426        git checkout master &&
 427        git update-index --force-untracked-cache &&
 428        git status --porcelain >/dev/null && # prime the cache
 429        test_path_is_missing done/.gitignore &&
 430        test_path_is_file done/one
 431'
 432
 433test_expect_success 'create/modify files, some of which are gitignored' '
 434        echo two bis >done/two &&
 435        echo three >done/three && # three is gitignored
 436        echo four >done/four && # four is gitignored at a higher level
 437        echo five >done/five && # five is not gitignored
 438        echo test >base && #we need to ensure that the root dir is touched
 439        rm base &&
 440        sync_mtime
 441'
 442
 443test_expect_success 'test sparse status with untracked cache' '
 444        : >../trace &&
 445        avoid_racy &&
 446        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 447        git status --porcelain >../status.actual &&
 448        cat >../status.expect <<EOF &&
 449 M done/two
 450?? .gitignore
 451?? done/five
 452?? dtwo/
 453EOF
 454        test_cmp ../status.expect ../status.actual &&
 455        cat >../trace.expect <<EOF &&
 456node creation: 0
 457gitignore invalidation: 1
 458directory invalidation: 2
 459opendir: 2
 460EOF
 461        test_cmp ../trace.expect ../trace
 462'
 463
 464test_expect_success 'untracked cache correct after status' '
 465        test-dump-untracked-cache >../actual &&
 466        cat >../expect <<EOF &&
 467info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
 468core.excludesfile 0000000000000000000000000000000000000000
 469exclude_per_dir .gitignore
 470flags 00000006
 471/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
 472.gitignore
 473dtwo/
 474/done/ 1946f0437f90c5005533cbe1736a6451ca301714 recurse valid
 475five
 476/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 477/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 478two
 479EOF
 480        test_cmp ../expect ../actual
 481'
 482
 483test_expect_success 'test sparse status again with untracked cache' '
 484        avoid_racy &&
 485        : >../trace &&
 486        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 487        git status --porcelain >../status.actual &&
 488        cat >../status.expect <<EOF &&
 489 M done/two
 490?? .gitignore
 491?? done/five
 492?? dtwo/
 493EOF
 494        test_cmp ../status.expect ../status.actual &&
 495        cat >../trace.expect <<EOF &&
 496node creation: 0
 497gitignore invalidation: 0
 498directory invalidation: 0
 499opendir: 0
 500EOF
 501        test_cmp ../trace.expect ../trace
 502'
 503
 504test_expect_success 'set up for test of subdir and sparse checkouts' '
 505        mkdir done/sub &&
 506        mkdir done/sub/sub &&
 507        echo "sub" > done/sub/sub/file
 508'
 509
 510test_expect_success 'test sparse status with untracked cache and subdir' '
 511        avoid_racy &&
 512        : >../trace &&
 513        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 514        git status --porcelain >../status.actual &&
 515        cat >../status.expect <<EOF &&
 516 M done/two
 517?? .gitignore
 518?? done/five
 519?? done/sub/
 520?? dtwo/
 521EOF
 522        test_cmp ../status.expect ../status.actual &&
 523        cat >../trace.expect <<EOF &&
 524node creation: 2
 525gitignore invalidation: 0
 526directory invalidation: 1
 527opendir: 3
 528EOF
 529        test_cmp ../trace.expect ../trace
 530'
 531
 532test_expect_success 'verify untracked cache dump (sparse/subdirs)' '
 533        test-dump-untracked-cache >../actual &&
 534        cat >../expect-from-test-dump <<EOF &&
 535info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
 536core.excludesfile 0000000000000000000000000000000000000000
 537exclude_per_dir .gitignore
 538flags 00000006
 539/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
 540.gitignore
 541dtwo/
 542/done/ 1946f0437f90c5005533cbe1736a6451ca301714 recurse valid
 543five
 544sub/
 545/done/sub/ 0000000000000000000000000000000000000000 recurse check_only valid
 546sub/
 547/done/sub/sub/ 0000000000000000000000000000000000000000 recurse check_only valid
 548file
 549/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 550/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 551two
 552EOF
 553        test_cmp ../expect-from-test-dump ../actual
 554'
 555
 556test_expect_success 'test sparse status again with untracked cache and subdir' '
 557        avoid_racy &&
 558        : >../trace &&
 559        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 560        git status --porcelain >../status.actual &&
 561        test_cmp ../status.expect ../status.actual &&
 562        cat >../trace.expect <<EOF &&
 563node creation: 0
 564gitignore invalidation: 0
 565directory invalidation: 0
 566opendir: 0
 567EOF
 568        test_cmp ../trace.expect ../trace
 569'
 570
 571test_expect_success 'move entry in subdir from untracked to cached' '
 572        git add dtwo/two &&
 573        git status --porcelain >../status.actual &&
 574        cat >../status.expect <<EOF &&
 575 M done/two
 576A  dtwo/two
 577?? .gitignore
 578?? done/five
 579?? done/sub/
 580EOF
 581        test_cmp ../status.expect ../status.actual
 582'
 583
 584test_expect_success 'move entry in subdir from cached to untracked' '
 585        git rm --cached dtwo/two &&
 586        git status --porcelain >../status.actual &&
 587        cat >../status.expect <<EOF &&
 588 M done/two
 589?? .gitignore
 590?? done/five
 591?? done/sub/
 592?? dtwo/
 593EOF
 594        test_cmp ../status.expect ../status.actual
 595'
 596
 597test_expect_success '--no-untracked-cache removes the cache' '
 598        git update-index --no-untracked-cache &&
 599        test-dump-untracked-cache >../actual &&
 600        echo "no untracked cache" >../expect-no-uc &&
 601        test_cmp ../expect-no-uc ../actual
 602'
 603
 604test_expect_success 'git status does not change anything' '
 605        git status &&
 606        test-dump-untracked-cache >../actual &&
 607        test_cmp ../expect-no-uc ../actual
 608'
 609
 610test_expect_success 'setting core.untrackedCache to true and using git status creates the cache' '
 611        git config core.untrackedCache true &&
 612        test-dump-untracked-cache >../actual &&
 613        test_cmp ../expect-no-uc ../actual &&
 614        git status &&
 615        test-dump-untracked-cache >../actual &&
 616        test_cmp ../expect-from-test-dump ../actual
 617'
 618
 619test_expect_success 'using --no-untracked-cache does not fail when core.untrackedCache is true' '
 620        git update-index --no-untracked-cache &&
 621        test-dump-untracked-cache >../actual &&
 622        test_cmp ../expect-no-uc ../actual &&
 623        git update-index --untracked-cache &&
 624        test-dump-untracked-cache >../actual &&
 625        test_cmp ../expect-empty ../actual
 626'
 627
 628test_expect_success 'setting core.untrackedCache to false and using git status removes the cache' '
 629        git config core.untrackedCache false &&
 630        test-dump-untracked-cache >../actual &&
 631        test_cmp ../expect-empty ../actual &&
 632        git status &&
 633        test-dump-untracked-cache >../actual &&
 634        test_cmp ../expect-no-uc ../actual
 635'
 636
 637test_expect_success 'using --untracked-cache does not fail when core.untrackedCache is false' '
 638        git update-index --untracked-cache &&
 639        test-dump-untracked-cache >../actual &&
 640        test_cmp ../expect-empty ../actual
 641'
 642
 643test_expect_success 'setting core.untrackedCache to keep' '
 644        git config core.untrackedCache keep &&
 645        git update-index --untracked-cache &&
 646        test-dump-untracked-cache >../actual &&
 647        test_cmp ../expect-empty ../actual &&
 648        git status &&
 649        test-dump-untracked-cache >../actual &&
 650        test_cmp ../expect-from-test-dump ../actual &&
 651        git update-index --no-untracked-cache &&
 652        test-dump-untracked-cache >../actual &&
 653        test_cmp ../expect-no-uc ../actual &&
 654        git update-index --force-untracked-cache &&
 655        test-dump-untracked-cache >../actual &&
 656        test_cmp ../expect-empty ../actual &&
 657        git status &&
 658        test-dump-untracked-cache >../actual &&
 659        test_cmp ../expect-from-test-dump ../actual
 660'
 661
 662test_expect_success 'test ident field is working' '
 663        mkdir ../other_worktree &&
 664        cp -R done dthree dtwo four three ../other_worktree &&
 665        GIT_WORK_TREE=../other_worktree git status 2>../err &&
 666        echo "warning: Untracked cache is disabled on this system or location." >../expect &&
 667        test_i18ncmp ../expect ../err
 668'
 669
 670test_expect_success 'untracked cache survives a checkout' '
 671        git commit --allow-empty -m empty &&
 672        test-dump-untracked-cache >../before &&
 673        test_when_finished  "git checkout master" &&
 674        git checkout -b other_branch &&
 675        test-dump-untracked-cache >../after &&
 676        test_cmp ../before ../after &&
 677        test_commit test &&
 678        test-dump-untracked-cache >../before &&
 679        git checkout master &&
 680        test-dump-untracked-cache >../after &&
 681        test_cmp ../before ../after
 682'
 683
 684test_expect_success 'untracked cache survives a commit' '
 685        test-dump-untracked-cache >../before &&
 686        git add done/two &&
 687        git commit -m commit &&
 688        test-dump-untracked-cache >../after &&
 689        test_cmp ../before ../after
 690'
 691
 692test_expect_success 'teardown worktree' '
 693        cd ..
 694'
 695
 696test_expect_success SYMLINKS 'setup worktree for symlink test' '
 697        git init worktree-symlink &&
 698        cd worktree-symlink &&
 699        git config core.untrackedCache true &&
 700        mkdir one two &&
 701        touch one/file two/file &&
 702        git add one/file two/file &&
 703        git commit -m"first commit" &&
 704        git rm -rf one &&
 705        ln -s two one &&
 706        git add one &&
 707        git commit -m"second commit"
 708'
 709
 710test_expect_success SYMLINKS '"status" after symlink replacement should be clean with UC=true' '
 711        git checkout HEAD~ &&
 712        status_is_clean &&
 713        status_is_clean &&
 714        git checkout master &&
 715        avoid_racy &&
 716        status_is_clean &&
 717        status_is_clean
 718'
 719
 720test_expect_success SYMLINKS '"status" after symlink replacement should be clean with UC=false' '
 721        git config core.untrackedCache false &&
 722        git checkout HEAD~ &&
 723        status_is_clean &&
 724        status_is_clean &&
 725        git checkout master &&
 726        avoid_racy &&
 727        status_is_clean &&
 728        status_is_clean
 729'
 730
 731test_expect_success 'setup worktree for non-symlink test' '
 732        git init worktree-non-symlink &&
 733        cd worktree-non-symlink &&
 734        git config core.untrackedCache true &&
 735        mkdir one two &&
 736        touch one/file two/file &&
 737        git add one/file two/file &&
 738        git commit -m"first commit" &&
 739        git rm -rf one &&
 740        cp two/file one &&
 741        git add one &&
 742        git commit -m"second commit"
 743'
 744
 745test_expect_success '"status" after file replacement should be clean with UC=true' '
 746        git checkout HEAD~ &&
 747        status_is_clean &&
 748        status_is_clean &&
 749        git checkout master &&
 750        avoid_racy &&
 751        status_is_clean &&
 752        test-dump-untracked-cache >../actual &&
 753        grep -F "recurse valid" ../actual >../actual.grep &&
 754        cat >../expect.grep <<EOF &&
 755/ 0000000000000000000000000000000000000000 recurse valid
 756/two/ 0000000000000000000000000000000000000000 recurse valid
 757EOF
 758        status_is_clean &&
 759        test_cmp ../expect.grep ../actual.grep
 760'
 761
 762test_expect_success '"status" after file replacement should be clean with UC=false' '
 763        git config core.untrackedCache false &&
 764        git checkout HEAD~ &&
 765        status_is_clean &&
 766        status_is_clean &&
 767        git checkout master &&
 768        avoid_racy &&
 769        status_is_clean &&
 770        status_is_clean
 771'
 772
 773test_done