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