t / t7063-status-untracked-cache.shon commit Seventh batch for 2.6 (e6837c8)
   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'
 417
 418test_expect_success 'test sparse status with untracked cache' '
 419        : >../trace &&
 420        avoid_racy &&
 421        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 422        git status --porcelain >../status.actual &&
 423        cat >../status.expect <<EOF &&
 424 M done/two
 425?? .gitignore
 426?? done/five
 427?? dtwo/
 428EOF
 429        test_cmp ../status.expect ../status.actual &&
 430        cat >../trace.expect <<EOF &&
 431node creation: 0
 432gitignore invalidation: 1
 433directory invalidation: 2
 434opendir: 2
 435EOF
 436        test_cmp ../trace.expect ../trace
 437'
 438
 439test_expect_success 'untracked cache correct after status' '
 440        test-dump-untracked-cache >../actual &&
 441        cat >../expect <<EOF &&
 442info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
 443core.excludesfile 0000000000000000000000000000000000000000
 444exclude_per_dir .gitignore
 445flags 00000006
 446/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
 447.gitignore
 448dtwo/
 449/done/ 1946f0437f90c5005533cbe1736a6451ca301714 recurse valid
 450five
 451/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 452/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 453two
 454EOF
 455        test_cmp ../expect ../actual
 456'
 457
 458test_expect_success 'test sparse status again with untracked cache' '
 459        avoid_racy &&
 460        : >../trace &&
 461        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 462        git status --porcelain >../status.actual &&
 463        cat >../status.expect <<EOF &&
 464 M done/two
 465?? .gitignore
 466?? done/five
 467?? dtwo/
 468EOF
 469        test_cmp ../status.expect ../status.actual &&
 470        cat >../trace.expect <<EOF &&
 471node creation: 0
 472gitignore invalidation: 0
 473directory invalidation: 0
 474opendir: 0
 475EOF
 476        test_cmp ../trace.expect ../trace
 477'
 478
 479test_expect_success 'set up for test of subdir and sparse checkouts' '
 480        mkdir done/sub &&
 481        mkdir done/sub/sub &&
 482        echo "sub" > done/sub/sub/file
 483'
 484
 485test_expect_success 'test sparse status with untracked cache and subdir' '
 486        avoid_racy &&
 487        : >../trace &&
 488        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 489        git status --porcelain >../status.actual &&
 490        cat >../status.expect <<EOF &&
 491 M done/two
 492?? .gitignore
 493?? done/five
 494?? done/sub/
 495?? dtwo/
 496EOF
 497        test_cmp ../status.expect ../status.actual &&
 498        cat >../trace.expect <<EOF &&
 499node creation: 2
 500gitignore invalidation: 0
 501directory invalidation: 1
 502opendir: 3
 503EOF
 504        test_cmp ../trace.expect ../trace
 505'
 506
 507test_expect_success 'verify untracked cache dump (sparse/subdirs)' '
 508        test-dump-untracked-cache >../actual &&
 509        cat >../expect <<EOF &&
 510info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
 511core.excludesfile 0000000000000000000000000000000000000000
 512exclude_per_dir .gitignore
 513flags 00000006
 514/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
 515.gitignore
 516dtwo/
 517/done/ 1946f0437f90c5005533cbe1736a6451ca301714 recurse valid
 518five
 519sub/
 520/done/sub/ 0000000000000000000000000000000000000000 recurse check_only valid
 521sub/
 522/done/sub/sub/ 0000000000000000000000000000000000000000 recurse check_only valid
 523file
 524/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
 525/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
 526two
 527EOF
 528        test_cmp ../expect ../actual
 529'
 530
 531test_expect_success 'test sparse status again with untracked cache and subdir' '
 532        avoid_racy &&
 533        : >../trace &&
 534        GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
 535        git status --porcelain >../status.actual &&
 536        test_cmp ../status.expect ../status.actual &&
 537        cat >../trace.expect <<EOF &&
 538node creation: 0
 539gitignore invalidation: 0
 540directory invalidation: 0
 541opendir: 0
 542EOF
 543        test_cmp ../trace.expect ../trace
 544'
 545
 546test_expect_success 'move entry in subdir from untracked to cached' '
 547        git add dtwo/two &&
 548        git status --porcelain >../status.actual &&
 549        cat >../status.expect <<EOF &&
 550 M done/two
 551A  dtwo/two
 552?? .gitignore
 553?? done/five
 554?? done/sub/
 555EOF
 556        test_cmp ../status.expect ../status.actual
 557'
 558
 559test_expect_success 'move entry in subdir from cached to untracked' '
 560        git rm --cached dtwo/two &&
 561        git status --porcelain >../status.actual &&
 562        cat >../status.expect <<EOF &&
 563 M done/two
 564?? .gitignore
 565?? done/five
 566?? done/sub/
 567?? dtwo/
 568EOF
 569        test_cmp ../status.expect ../status.actual
 570'
 571
 572test_done