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