t / t7063-status-untracked-cache.shon commit Merge branch 'dt/name-hash-dir-entry-fix' into maint (3a27eec)
   1#!/bin/sh
   2
   3test_description='test untracked cache'
   4
   5. ./test-lib.sh
   6
   7avoid_racy() {
   8        sleep 1
   9}
  10
  11# It's fine if git update-index returns an error code other than one,
  12# it'll be caught in the first test.
  13test_lazy_prereq UNTRACKED_CACHE '
  14        { git update-index --untracked-cache; ret=$?; } &&
  15        test $ret -ne 1
  16'
  17
  18if ! test_have_prereq UNTRACKED_CACHE; then
  19        skip_all='This system does not support untracked cache'
  20        test_done
  21fi
  22
  23test_expect_success 'setup' '
  24        git init worktree &&
  25        cd worktree &&
  26        mkdir done dtwo dthree &&
  27        touch one two three done/one dtwo/two dthree/three &&
  28        git add one two done/one &&
  29        : >.git/info/exclude &&
  30        git update-index --untracked-cache
  31'
  32
  33test_expect_success 'untracked cache is empty' '
  34        test-dump-untracked-cache >../actual &&
  35        cat >../expect <<EOF &&
  36info/exclude 0000000000000000000000000000000000000000
  37core.excludesfile 0000000000000000000000000000000000000000
  38exclude_per_dir .gitignore
  39flags 00000006
  40EOF
  41        test_cmp ../expect ../actual
  42'
  43
  44cat >../status.expect <<EOF &&
  45A  done/one
  46A  one
  47A  two
  48?? dthree/
  49?? dtwo/
  50?? three
  51EOF
  52
  53cat >../dump.expect <<EOF &&
  54info/exclude e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
  55core.excludesfile 0000000000000000000000000000000000000000
  56exclude_per_dir .gitignore
  57flags 00000006
  58/ 0000000000000000000000000000000000000000 recurse valid
  59dthree/
  60dtwo/
  61three
  62/done/ 0000000000000000000000000000000000000000 recurse valid
  63/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
  64three
  65/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
  66two
  67EOF
  68
  69test_expect_success 'status first time (empty cache)' '
  70        avoid_racy &&
  71        : >../trace &&
  72        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
  73        git status --porcelain >../actual &&
  74        test_cmp ../status.expect ../actual &&
  75        cat >../trace.expect <<EOF &&
  76node creation: 3
  77gitignore invalidation: 1
  78directory invalidation: 0
  79opendir: 4
  80EOF
  81        test_cmp ../trace.expect ../trace
  82'
  83
  84test_expect_success 'untracked cache after first status' '
  85        test-dump-untracked-cache >../actual &&
  86        test_cmp ../dump.expect ../actual
  87'
  88
  89test_expect_success 'status second time (fully populated cache)' '
  90        avoid_racy &&
  91        : >../trace &&
  92        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
  93        git status --porcelain >../actual &&
  94        test_cmp ../status.expect ../actual &&
  95        cat >../trace.expect <<EOF &&
  96node creation: 0
  97gitignore invalidation: 0
  98directory invalidation: 0
  99opendir: 0
 100EOF
 101        test_cmp ../trace.expect ../trace
 102'
 103
 104test_expect_success 'untracked cache after second status' '
 105        test-dump-untracked-cache >../actual &&
 106        test_cmp ../dump.expect ../actual
 107'
 108
 109test_expect_success 'modify in root directory, one dir invalidation' '
 110        avoid_racy &&
 111        : >four &&
 112        : >../trace &&
 113        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 114        git status --porcelain >../actual &&
 115        cat >../status.expect <<EOF &&
 116A  done/one
 117A  one
 118A  two
 119?? dthree/
 120?? dtwo/
 121?? four
 122?? three
 123EOF
 124        test_cmp ../status.expect ../actual &&
 125        cat >../trace.expect <<EOF &&
 126node creation: 0
 127gitignore invalidation: 0
 128directory invalidation: 1
 129opendir: 1
 130EOF
 131        test_cmp ../trace.expect ../trace
 132
 133'
 134
 135test_expect_success 'verify untracked cache dump' '
 136        test-dump-untracked-cache >../actual &&
 137        cat >../expect <<EOF &&
 138info/exclude e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
 139core.excludesfile 0000000000000000000000000000000000000000
 140exclude_per_dir .gitignore
 141flags 00000006
 142/ 0000000000000000000000000000000000000000 recurse valid
 143dthree/
 144dtwo/
 145four
 146three
 147/done/ 0000000000000000000000000000000000000000 recurse valid
 148/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 149three
 150/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 151two
 152EOF
 153        test_cmp ../expect ../actual
 154'
 155
 156test_expect_success 'new .gitignore invalidates recursively' '
 157        avoid_racy &&
 158        echo four >.gitignore &&
 159        : >../trace &&
 160        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 161        git status --porcelain >../actual &&
 162        cat >../status.expect <<EOF &&
 163A  done/one
 164A  one
 165A  two
 166?? .gitignore
 167?? dthree/
 168?? dtwo/
 169?? three
 170EOF
 171        test_cmp ../status.expect ../actual &&
 172        cat >../trace.expect <<EOF &&
 173node creation: 0
 174gitignore invalidation: 1
 175directory invalidation: 1
 176opendir: 4
 177EOF
 178        test_cmp ../trace.expect ../trace
 179
 180'
 181
 182test_expect_success 'verify untracked cache dump' '
 183        test-dump-untracked-cache >../actual &&
 184        cat >../expect <<EOF &&
 185info/exclude e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
 186core.excludesfile 0000000000000000000000000000000000000000
 187exclude_per_dir .gitignore
 188flags 00000006
 189/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
 190.gitignore
 191dthree/
 192dtwo/
 193three
 194/done/ 0000000000000000000000000000000000000000 recurse valid
 195/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 196three
 197/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 198two
 199EOF
 200        test_cmp ../expect ../actual
 201'
 202
 203test_expect_success 'new info/exclude invalidates everything' '
 204        avoid_racy &&
 205        echo three >>.git/info/exclude &&
 206        : >../trace &&
 207        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 208        git status --porcelain >../actual &&
 209        cat >../status.expect <<EOF &&
 210A  done/one
 211A  one
 212A  two
 213?? .gitignore
 214?? dtwo/
 215EOF
 216        test_cmp ../status.expect ../actual &&
 217        cat >../trace.expect <<EOF &&
 218node creation: 0
 219gitignore invalidation: 1
 220directory invalidation: 0
 221opendir: 4
 222EOF
 223        test_cmp ../trace.expect ../trace
 224'
 225
 226test_expect_success 'verify untracked cache dump' '
 227        test-dump-untracked-cache >../actual &&
 228        cat >../expect <<EOF &&
 229info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
 230core.excludesfile 0000000000000000000000000000000000000000
 231exclude_per_dir .gitignore
 232flags 00000006
 233/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
 234.gitignore
 235dtwo/
 236/done/ 0000000000000000000000000000000000000000 recurse valid
 237/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 238/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 239two
 240EOF
 241        test_cmp ../expect ../actual
 242'
 243
 244test_expect_success 'move two from tracked to untracked' '
 245        git rm --cached two &&
 246        test-dump-untracked-cache >../actual &&
 247        cat >../expect <<EOF &&
 248info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
 249core.excludesfile 0000000000000000000000000000000000000000
 250exclude_per_dir .gitignore
 251flags 00000006
 252/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse
 253/done/ 0000000000000000000000000000000000000000 recurse valid
 254/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 255/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 256two
 257EOF
 258        test_cmp ../expect ../actual
 259'
 260
 261test_expect_success 'status after the move' '
 262        : >../trace &&
 263        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 264        git status --porcelain >../actual &&
 265        cat >../status.expect <<EOF &&
 266A  done/one
 267A  one
 268?? .gitignore
 269?? dtwo/
 270?? two
 271EOF
 272        test_cmp ../status.expect ../actual &&
 273        cat >../trace.expect <<EOF &&
 274node creation: 0
 275gitignore invalidation: 0
 276directory invalidation: 0
 277opendir: 1
 278EOF
 279        test_cmp ../trace.expect ../trace
 280'
 281
 282test_expect_success 'verify untracked cache dump' '
 283        test-dump-untracked-cache >../actual &&
 284        cat >../expect <<EOF &&
 285info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
 286core.excludesfile 0000000000000000000000000000000000000000
 287exclude_per_dir .gitignore
 288flags 00000006
 289/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
 290.gitignore
 291dtwo/
 292two
 293/done/ 0000000000000000000000000000000000000000 recurse valid
 294/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 295/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 296two
 297EOF
 298        test_cmp ../expect ../actual
 299'
 300
 301test_expect_success 'move two from untracked to tracked' '
 302        git add two &&
 303        test-dump-untracked-cache >../actual &&
 304        cat >../expect <<EOF &&
 305info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
 306core.excludesfile 0000000000000000000000000000000000000000
 307exclude_per_dir .gitignore
 308flags 00000006
 309/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse
 310/done/ 0000000000000000000000000000000000000000 recurse valid
 311/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 312/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 313two
 314EOF
 315        test_cmp ../expect ../actual
 316'
 317
 318test_expect_success 'status after the move' '
 319        : >../trace &&
 320        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 321        git status --porcelain >../actual &&
 322        cat >../status.expect <<EOF &&
 323A  done/one
 324A  one
 325A  two
 326?? .gitignore
 327?? dtwo/
 328EOF
 329        test_cmp ../status.expect ../actual &&
 330        cat >../trace.expect <<EOF &&
 331node creation: 0
 332gitignore invalidation: 0
 333directory invalidation: 0
 334opendir: 1
 335EOF
 336        test_cmp ../trace.expect ../trace
 337'
 338
 339test_expect_success 'verify untracked cache dump' '
 340        test-dump-untracked-cache >../actual &&
 341        cat >../expect <<EOF &&
 342info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
 343core.excludesfile 0000000000000000000000000000000000000000
 344exclude_per_dir .gitignore
 345flags 00000006
 346/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
 347.gitignore
 348dtwo/
 349/done/ 0000000000000000000000000000000000000000 recurse valid
 350/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 351/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 352two
 353EOF
 354        test_cmp ../expect ../actual
 355'
 356
 357test_expect_success 'set up for sparse checkout testing' '
 358        echo two >done/.gitignore &&
 359        echo three >>done/.gitignore &&
 360        echo two >done/two &&
 361        git add -f done/two done/.gitignore &&
 362        git commit -m "first commit"
 363'
 364
 365test_expect_success 'status after commit' '
 366        : >../trace &&
 367        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 368        git status --porcelain >../actual &&
 369        cat >../status.expect <<EOF &&
 370?? .gitignore
 371?? dtwo/
 372EOF
 373        test_cmp ../status.expect ../actual &&
 374        cat >../trace.expect <<EOF &&
 375node creation: 0
 376gitignore invalidation: 0
 377directory invalidation: 0
 378opendir: 2
 379EOF
 380        test_cmp ../trace.expect ../trace
 381'
 382
 383test_expect_success 'untracked cache correct after commit' '
 384        test-dump-untracked-cache >../actual &&
 385        cat >../expect <<EOF &&
 386info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
 387core.excludesfile 0000000000000000000000000000000000000000
 388exclude_per_dir .gitignore
 389flags 00000006
 390/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
 391.gitignore
 392dtwo/
 393/done/ 0000000000000000000000000000000000000000 recurse valid
 394/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 395/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 396two
 397EOF
 398        test_cmp ../expect ../actual
 399'
 400
 401test_expect_success 'set up sparse checkout' '
 402        echo "done/[a-z]*" >.git/info/sparse-checkout &&
 403        test_config core.sparsecheckout true &&
 404        git checkout master &&
 405        git update-index --force-untracked-cache &&
 406        git status --porcelain >/dev/null && # prime the cache
 407        test_path_is_missing done/.gitignore &&
 408        test_path_is_file done/one
 409'
 410
 411test_expect_success 'create/modify files, some of which are gitignored' '
 412        echo two bis >done/two &&
 413        echo three >done/three && # three is gitignored
 414        echo four >done/four && # four is gitignored at a higher level
 415        echo five >done/five && # five is not gitignored
 416        echo test >base && #we need to ensure that the root dir is touched
 417        rm base
 418'
 419
 420test_expect_success 'test sparse status with untracked cache' '
 421        : >../trace &&
 422        avoid_racy &&
 423        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 424        git status --porcelain >../status.actual &&
 425        cat >../status.expect <<EOF &&
 426 M done/two
 427?? .gitignore
 428?? done/five
 429?? dtwo/
 430EOF
 431        test_cmp ../status.expect ../status.actual &&
 432        cat >../trace.expect <<EOF &&
 433node creation: 0
 434gitignore invalidation: 1
 435directory invalidation: 2
 436opendir: 2
 437EOF
 438        test_cmp ../trace.expect ../trace
 439'
 440
 441test_expect_success 'untracked cache correct after status' '
 442        test-dump-untracked-cache >../actual &&
 443        cat >../expect <<EOF &&
 444info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
 445core.excludesfile 0000000000000000000000000000000000000000
 446exclude_per_dir .gitignore
 447flags 00000006
 448/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
 449.gitignore
 450dtwo/
 451/done/ 1946f0437f90c5005533cbe1736a6451ca301714 recurse valid
 452five
 453/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 454/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 455two
 456EOF
 457        test_cmp ../expect ../actual
 458'
 459
 460test_expect_success 'test sparse status again with untracked cache' '
 461        avoid_racy &&
 462        : >../trace &&
 463        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 464        git status --porcelain >../status.actual &&
 465        cat >../status.expect <<EOF &&
 466 M done/two
 467?? .gitignore
 468?? done/five
 469?? dtwo/
 470EOF
 471        test_cmp ../status.expect ../status.actual &&
 472        cat >../trace.expect <<EOF &&
 473node creation: 0
 474gitignore invalidation: 0
 475directory invalidation: 0
 476opendir: 0
 477EOF
 478        test_cmp ../trace.expect ../trace
 479'
 480
 481test_expect_success 'set up for test of subdir and sparse checkouts' '
 482        mkdir done/sub &&
 483        mkdir done/sub/sub &&
 484        echo "sub" > done/sub/sub/file
 485'
 486
 487test_expect_success 'test sparse status with untracked cache and subdir' '
 488        avoid_racy &&
 489        : >../trace &&
 490        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 491        git status --porcelain >../status.actual &&
 492        cat >../status.expect <<EOF &&
 493 M done/two
 494?? .gitignore
 495?? done/five
 496?? done/sub/
 497?? dtwo/
 498EOF
 499        test_cmp ../status.expect ../status.actual &&
 500        cat >../trace.expect <<EOF &&
 501node creation: 2
 502gitignore invalidation: 0
 503directory invalidation: 1
 504opendir: 3
 505EOF
 506        test_cmp ../trace.expect ../trace
 507'
 508
 509test_expect_success 'verify untracked cache dump (sparse/subdirs)' '
 510        test-dump-untracked-cache >../actual &&
 511        cat >../expect <<EOF &&
 512info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
 513core.excludesfile 0000000000000000000000000000000000000000
 514exclude_per_dir .gitignore
 515flags 00000006
 516/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
 517.gitignore
 518dtwo/
 519/done/ 1946f0437f90c5005533cbe1736a6451ca301714 recurse valid
 520five
 521sub/
 522/done/sub/ 0000000000000000000000000000000000000000 recurse check_only valid
 523sub/
 524/done/sub/sub/ 0000000000000000000000000000000000000000 recurse check_only valid
 525file
 526/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 527/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 528two
 529EOF
 530        test_cmp ../expect ../actual
 531'
 532
 533test_expect_success 'test sparse status again with untracked cache and subdir' '
 534        avoid_racy &&
 535        : >../trace &&
 536        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 537        git status --porcelain >../status.actual &&
 538        test_cmp ../status.expect ../status.actual &&
 539        cat >../trace.expect <<EOF &&
 540node creation: 0
 541gitignore invalidation: 0
 542directory invalidation: 0
 543opendir: 0
 544EOF
 545        test_cmp ../trace.expect ../trace
 546'
 547
 548test_expect_success 'move entry in subdir from untracked to cached' '
 549        git add dtwo/two &&
 550        git status --porcelain >../status.actual &&
 551        cat >../status.expect <<EOF &&
 552 M done/two
 553A  dtwo/two
 554?? .gitignore
 555?? done/five
 556?? done/sub/
 557EOF
 558        test_cmp ../status.expect ../status.actual
 559'
 560
 561test_expect_success 'move entry in subdir from cached to untracked' '
 562        git rm --cached dtwo/two &&
 563        git status --porcelain >../status.actual &&
 564        cat >../status.expect <<EOF &&
 565 M done/two
 566?? .gitignore
 567?? done/five
 568?? done/sub/
 569?? dtwo/
 570EOF
 571        test_cmp ../status.expect ../status.actual
 572'
 573
 574test_done