3 test_description='test untracked cache'
11 test_lazy_prereq UNTRACKED_CACHE '
12 { git update-index --test-untracked-cache; ret=$?; } &&
16 if ! test_have_prereq UNTRACKED_CACHE; then
17 skip_all='This system does not support untracked cache'
21 test_expect_success 'core.untrackedCache is unset' '
22 test_must_fail git config --get core.untrackedCache
25 test_expect_success 'setup' '
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
35 test_expect_success 'untracked cache is empty' '
36 test-dump-untracked-cache >../actual &&
37 cat >../expect-empty <<EOF &&
38 info/exclude 0000000000000000000000000000000000000000
39 core.excludesfile 0000000000000000000000000000000000000000
40 exclude_per_dir .gitignore
43 test_cmp ../expect-empty ../actual
46 cat >../status.expect <<EOF &&
55 cat >../dump.expect <<EOF &&
56 info/exclude $EMPTY_BLOB
57 core.excludesfile 0000000000000000000000000000000000000000
58 exclude_per_dir .gitignore
60 / 0000000000000000000000000000000000000000 recurse valid
64 /done/ 0000000000000000000000000000000000000000 recurse valid
65 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
67 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
71 test_expect_success 'status first time (empty cache)' '
74 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
75 git status --porcelain >../actual &&
76 test_cmp ../status.expect ../actual &&
77 cat >../trace.expect <<EOF &&
79 gitignore invalidation: 1
80 directory invalidation: 0
83 test_cmp ../trace.expect ../trace
86 test_expect_success 'untracked cache after first status' '
87 test-dump-untracked-cache >../actual &&
88 test_cmp ../dump.expect ../actual
91 test_expect_success 'status second time (fully populated cache)' '
94 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
95 git status --porcelain >../actual &&
96 test_cmp ../status.expect ../actual &&
97 cat >../trace.expect <<EOF &&
99 gitignore invalidation: 0
100 directory invalidation: 0
103 test_cmp ../trace.expect ../trace
106 test_expect_success 'untracked cache after second status' '
107 test-dump-untracked-cache >../actual &&
108 test_cmp ../dump.expect ../actual
111 test_expect_success 'modify in root directory, one dir invalidation' '
115 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
116 git status --porcelain >../actual &&
117 cat >../status.expect <<EOF &&
126 test_cmp ../status.expect ../actual &&
127 cat >../trace.expect <<EOF &&
129 gitignore invalidation: 0
130 directory invalidation: 1
133 test_cmp ../trace.expect ../trace
137 test_expect_success 'verify untracked cache dump' '
138 test-dump-untracked-cache >../actual &&
139 cat >../expect <<EOF &&
140 info/exclude $EMPTY_BLOB
141 core.excludesfile 0000000000000000000000000000000000000000
142 exclude_per_dir .gitignore
144 / 0000000000000000000000000000000000000000 recurse valid
149 /done/ 0000000000000000000000000000000000000000 recurse valid
150 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
152 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
155 test_cmp ../expect ../actual
158 test_expect_success 'new .gitignore invalidates recursively' '
160 echo four >.gitignore &&
162 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
163 git status --porcelain >../actual &&
164 cat >../status.expect <<EOF &&
173 test_cmp ../status.expect ../actual &&
174 cat >../trace.expect <<EOF &&
176 gitignore invalidation: 1
177 directory invalidation: 1
180 test_cmp ../trace.expect ../trace
184 test_expect_success 'verify untracked cache dump' '
185 test-dump-untracked-cache >../actual &&
186 cat >../expect <<EOF &&
187 info/exclude $EMPTY_BLOB
188 core.excludesfile 0000000000000000000000000000000000000000
189 exclude_per_dir .gitignore
191 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
196 /done/ 0000000000000000000000000000000000000000 recurse valid
197 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
199 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
202 test_cmp ../expect ../actual
205 test_expect_success 'new info/exclude invalidates everything' '
207 echo three >>.git/info/exclude &&
209 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
210 git status --porcelain >../actual &&
211 cat >../status.expect <<EOF &&
218 test_cmp ../status.expect ../actual &&
219 cat >../trace.expect <<EOF &&
221 gitignore invalidation: 1
222 directory invalidation: 0
225 test_cmp ../trace.expect ../trace
228 test_expect_success 'verify untracked cache dump' '
229 test-dump-untracked-cache >../actual &&
230 cat >../expect <<EOF &&
231 info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
232 core.excludesfile 0000000000000000000000000000000000000000
233 exclude_per_dir .gitignore
235 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
238 /done/ 0000000000000000000000000000000000000000 recurse valid
239 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
240 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
243 test_cmp ../expect ../actual
246 test_expect_success 'move two from tracked to untracked' '
247 git rm --cached two &&
248 test-dump-untracked-cache >../actual &&
249 cat >../expect <<EOF &&
250 info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
251 core.excludesfile 0000000000000000000000000000000000000000
252 exclude_per_dir .gitignore
254 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse
255 /done/ 0000000000000000000000000000000000000000 recurse valid
256 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
257 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
260 test_cmp ../expect ../actual
263 test_expect_success 'status after the move' '
265 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
266 git status --porcelain >../actual &&
267 cat >../status.expect <<EOF &&
274 test_cmp ../status.expect ../actual &&
275 cat >../trace.expect <<EOF &&
277 gitignore invalidation: 0
278 directory invalidation: 0
281 test_cmp ../trace.expect ../trace
284 test_expect_success 'verify untracked cache dump' '
285 test-dump-untracked-cache >../actual &&
286 cat >../expect <<EOF &&
287 info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
288 core.excludesfile 0000000000000000000000000000000000000000
289 exclude_per_dir .gitignore
291 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
295 /done/ 0000000000000000000000000000000000000000 recurse valid
296 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
297 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
300 test_cmp ../expect ../actual
303 test_expect_success 'move two from untracked to tracked' '
305 test-dump-untracked-cache >../actual &&
306 cat >../expect <<EOF &&
307 info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
308 core.excludesfile 0000000000000000000000000000000000000000
309 exclude_per_dir .gitignore
311 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse
312 /done/ 0000000000000000000000000000000000000000 recurse valid
313 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
314 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
317 test_cmp ../expect ../actual
320 test_expect_success 'status after the move' '
322 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
323 git status --porcelain >../actual &&
324 cat >../status.expect <<EOF &&
331 test_cmp ../status.expect ../actual &&
332 cat >../trace.expect <<EOF &&
334 gitignore invalidation: 0
335 directory invalidation: 0
338 test_cmp ../trace.expect ../trace
341 test_expect_success 'verify untracked cache dump' '
342 test-dump-untracked-cache >../actual &&
343 cat >../expect <<EOF &&
344 info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
345 core.excludesfile 0000000000000000000000000000000000000000
346 exclude_per_dir .gitignore
348 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
351 /done/ 0000000000000000000000000000000000000000 recurse valid
352 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
353 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
356 test_cmp ../expect ../actual
359 test_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"
367 test_expect_success 'status after commit' '
369 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
370 git status --porcelain >../actual &&
371 cat >../status.expect <<EOF &&
375 test_cmp ../status.expect ../actual &&
376 cat >../trace.expect <<EOF &&
378 gitignore invalidation: 0
379 directory invalidation: 0
382 test_cmp ../trace.expect ../trace
385 test_expect_success 'untracked cache correct after commit' '
386 test-dump-untracked-cache >../actual &&
387 cat >../expect <<EOF &&
388 info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
389 core.excludesfile 0000000000000000000000000000000000000000
390 exclude_per_dir .gitignore
392 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
395 /done/ 0000000000000000000000000000000000000000 recurse valid
396 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
397 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
400 test_cmp ../expect ../actual
403 test_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
413 test_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
422 test_expect_success 'test sparse status with untracked cache' '
425 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
426 git status --porcelain >../status.actual &&
427 cat >../status.expect <<EOF &&
433 test_cmp ../status.expect ../status.actual &&
434 cat >../trace.expect <<EOF &&
436 gitignore invalidation: 1
437 directory invalidation: 2
440 test_cmp ../trace.expect ../trace
443 test_expect_success 'untracked cache correct after status' '
444 test-dump-untracked-cache >../actual &&
445 cat >../expect <<EOF &&
446 info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
447 core.excludesfile 0000000000000000000000000000000000000000
448 exclude_per_dir .gitignore
450 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
453 /done/ 1946f0437f90c5005533cbe1736a6451ca301714 recurse valid
455 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
456 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
459 test_cmp ../expect ../actual
462 test_expect_success 'test sparse status again with untracked cache' '
465 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
466 git status --porcelain >../status.actual &&
467 cat >../status.expect <<EOF &&
473 test_cmp ../status.expect ../status.actual &&
474 cat >../trace.expect <<EOF &&
476 gitignore invalidation: 0
477 directory invalidation: 0
480 test_cmp ../trace.expect ../trace
483 test_expect_success 'set up for test of subdir and sparse checkouts' '
485 mkdir done/sub/sub &&
486 echo "sub" > done/sub/sub/file
489 test_expect_success 'test sparse status with untracked cache and subdir' '
492 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
493 git status --porcelain >../status.actual &&
494 cat >../status.expect <<EOF &&
501 test_cmp ../status.expect ../status.actual &&
502 cat >../trace.expect <<EOF &&
504 gitignore invalidation: 0
505 directory invalidation: 1
508 test_cmp ../trace.expect ../trace
511 test_expect_success 'verify untracked cache dump (sparse/subdirs)' '
512 test-dump-untracked-cache >../actual &&
513 cat >../expect-from-test-dump <<EOF &&
514 info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
515 core.excludesfile 0000000000000000000000000000000000000000
516 exclude_per_dir .gitignore
518 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
521 /done/ 1946f0437f90c5005533cbe1736a6451ca301714 recurse valid
524 /done/sub/ 0000000000000000000000000000000000000000 recurse check_only valid
526 /done/sub/sub/ 0000000000000000000000000000000000000000 recurse check_only valid
528 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
529 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
532 test_cmp ../expect-from-test-dump ../actual
535 test_expect_success 'test sparse status again with untracked cache and subdir' '
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 &&
543 gitignore invalidation: 0
544 directory invalidation: 0
547 test_cmp ../trace.expect ../trace
550 test_expect_success 'move entry in subdir from untracked to cached' '
552 git status --porcelain >../status.actual &&
553 cat >../status.expect <<EOF &&
560 test_cmp ../status.expect ../status.actual
563 test_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 &&
573 test_cmp ../status.expect ../status.actual
576 test_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
583 test_expect_success 'git status does not change anything' '
585 test-dump-untracked-cache >../actual &&
586 test_cmp ../expect-no-uc ../actual
589 test_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 &&
594 test-dump-untracked-cache >../actual &&
595 test_cmp ../expect-from-test-dump ../actual
598 test_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
607 test_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 &&
612 test-dump-untracked-cache >../actual &&
613 test_cmp ../expect-no-uc ../actual
616 test_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
622 test_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 &&
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 &&
637 test-dump-untracked-cache >../actual &&
638 test_cmp ../expect-from-test-dump ../actual
641 test_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_cmp ../expect ../err