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