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