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