Merge branch 'nd/cache-tree-ita'
[git.git] / t / t7063-status-untracked-cache.sh
blobc23a21cb74d56426a9948c0a37db512b093eaa57
1 #!/bin/sh
3 test_description='test untracked cache'
5 . ./test-lib.sh
7 avoid_racy() {
8 sleep 1
11 test_lazy_prereq UNTRACKED_CACHE '
12 { git update-index --test-untracked-cache; ret=$?; } &&
13 test $ret -ne 1
16 if ! test_have_prereq UNTRACKED_CACHE; then
17 skip_all='This system does not support untracked cache'
18 test_done
21 test_expect_success 'core.untrackedCache is unset' '
22 test_must_fail git config --get core.untrackedCache
25 test_expect_success 'setup' '
26 git init worktree &&
27 cd worktree &&
28 mkdir done dtwo dthree &&
29 touch one two three done/one dtwo/two dthree/three &&
30 git add one two done/one &&
31 : >.git/info/exclude &&
32 git update-index --untracked-cache
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
41 flags 00000006
42 EOF
43 test_cmp ../expect-empty ../actual
46 cat >../status.expect <<EOF &&
47 A done/one
48 A one
49 A two
50 ?? dthree/
51 ?? dtwo/
52 ?? three
53 EOF
55 cat >../dump.expect <<EOF &&
56 info/exclude $EMPTY_BLOB
57 core.excludesfile 0000000000000000000000000000000000000000
58 exclude_per_dir .gitignore
59 flags 00000006
60 / 0000000000000000000000000000000000000000 recurse valid
61 dthree/
62 dtwo/
63 three
64 /done/ 0000000000000000000000000000000000000000 recurse valid
65 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
66 three
67 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
68 two
69 EOF
71 test_expect_success 'status first time (empty cache)' '
72 avoid_racy &&
73 : >../trace &&
74 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
75 git status --porcelain >../actual &&
76 test_cmp ../status.expect ../actual &&
77 cat >../trace.expect <<EOF &&
78 node creation: 3
79 gitignore invalidation: 1
80 directory invalidation: 0
81 opendir: 4
82 EOF
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)' '
92 avoid_racy &&
93 : >../trace &&
94 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
95 git status --porcelain >../actual &&
96 test_cmp ../status.expect ../actual &&
97 cat >../trace.expect <<EOF &&
98 node creation: 0
99 gitignore invalidation: 0
100 directory invalidation: 0
101 opendir: 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' '
112 avoid_racy &&
113 : >four &&
114 : >../trace &&
115 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
116 git status --porcelain >../actual &&
117 cat >../status.expect <<EOF &&
118 A done/one
119 A one
120 A two
121 ?? dthree/
122 ?? dtwo/
123 ?? four
124 ?? three
126 test_cmp ../status.expect ../actual &&
127 cat >../trace.expect <<EOF &&
128 node creation: 0
129 gitignore invalidation: 0
130 directory invalidation: 1
131 opendir: 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
143 flags 00000006
144 / 0000000000000000000000000000000000000000 recurse valid
145 dthree/
146 dtwo/
147 four
148 three
149 /done/ 0000000000000000000000000000000000000000 recurse valid
150 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
151 three
152 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
155 test_cmp ../expect ../actual
158 test_expect_success 'new .gitignore invalidates recursively' '
159 avoid_racy &&
160 echo four >.gitignore &&
161 : >../trace &&
162 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
163 git status --porcelain >../actual &&
164 cat >../status.expect <<EOF &&
165 A done/one
166 A one
167 A two
168 ?? .gitignore
169 ?? dthree/
170 ?? dtwo/
171 ?? three
173 test_cmp ../status.expect ../actual &&
174 cat >../trace.expect <<EOF &&
175 node creation: 0
176 gitignore invalidation: 1
177 directory invalidation: 1
178 opendir: 4
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
190 flags 00000006
191 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
192 .gitignore
193 dthree/
194 dtwo/
195 three
196 /done/ 0000000000000000000000000000000000000000 recurse valid
197 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
198 three
199 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
202 test_cmp ../expect ../actual
205 test_expect_success 'new info/exclude invalidates everything' '
206 avoid_racy &&
207 echo three >>.git/info/exclude &&
208 : >../trace &&
209 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
210 git status --porcelain >../actual &&
211 cat >../status.expect <<EOF &&
212 A done/one
213 A one
214 A two
215 ?? .gitignore
216 ?? dtwo/
218 test_cmp ../status.expect ../actual &&
219 cat >../trace.expect <<EOF &&
220 node creation: 0
221 gitignore invalidation: 1
222 directory invalidation: 0
223 opendir: 4
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
234 flags 00000006
235 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
236 .gitignore
237 dtwo/
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
253 flags 00000006
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' '
264 : >../trace &&
265 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
266 git status --porcelain >../actual &&
267 cat >../status.expect <<EOF &&
268 A done/one
269 A one
270 ?? .gitignore
271 ?? dtwo/
272 ?? two
274 test_cmp ../status.expect ../actual &&
275 cat >../trace.expect <<EOF &&
276 node creation: 0
277 gitignore invalidation: 0
278 directory invalidation: 0
279 opendir: 1
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
290 flags 00000006
291 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
292 .gitignore
293 dtwo/
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' '
304 git add two &&
305 test-dump-untracked-cache >../actual &&
306 cat >../expect <<EOF &&
307 info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
308 core.excludesfile 0000000000000000000000000000000000000000
309 exclude_per_dir .gitignore
310 flags 00000006
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' '
321 : >../trace &&
322 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
323 git status --porcelain >../actual &&
324 cat >../status.expect <<EOF &&
325 A done/one
326 A one
327 A two
328 ?? .gitignore
329 ?? dtwo/
331 test_cmp ../status.expect ../actual &&
332 cat >../trace.expect <<EOF &&
333 node creation: 0
334 gitignore invalidation: 0
335 directory invalidation: 0
336 opendir: 1
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
347 flags 00000006
348 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
349 .gitignore
350 dtwo/
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' '
368 : >../trace &&
369 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
370 git status --porcelain >../actual &&
371 cat >../status.expect <<EOF &&
372 ?? .gitignore
373 ?? dtwo/
375 test_cmp ../status.expect ../actual &&
376 cat >../trace.expect <<EOF &&
377 node creation: 0
378 gitignore invalidation: 0
379 directory invalidation: 0
380 opendir: 2
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
391 flags 00000006
392 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
393 .gitignore
394 dtwo/
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
419 rm base
422 test_expect_success 'test sparse status with untracked cache' '
423 : >../trace &&
424 avoid_racy &&
425 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
426 git status --porcelain >../status.actual &&
427 cat >../status.expect <<EOF &&
428 M done/two
429 ?? .gitignore
430 ?? done/five
431 ?? dtwo/
433 test_cmp ../status.expect ../status.actual &&
434 cat >../trace.expect <<EOF &&
435 node creation: 0
436 gitignore invalidation: 1
437 directory invalidation: 2
438 opendir: 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
449 flags 00000006
450 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
451 .gitignore
452 dtwo/
453 /done/ 1946f0437f90c5005533cbe1736a6451ca301714 recurse valid
454 five
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' '
463 avoid_racy &&
464 : >../trace &&
465 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
466 git status --porcelain >../status.actual &&
467 cat >../status.expect <<EOF &&
468 M done/two
469 ?? .gitignore
470 ?? done/five
471 ?? dtwo/
473 test_cmp ../status.expect ../status.actual &&
474 cat >../trace.expect <<EOF &&
475 node creation: 0
476 gitignore invalidation: 0
477 directory invalidation: 0
478 opendir: 0
480 test_cmp ../trace.expect ../trace
483 test_expect_success 'set up for test of subdir and sparse checkouts' '
484 mkdir done/sub &&
485 mkdir done/sub/sub &&
486 echo "sub" > done/sub/sub/file
489 test_expect_success 'test sparse status with untracked cache and subdir' '
490 avoid_racy &&
491 : >../trace &&
492 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
493 git status --porcelain >../status.actual &&
494 cat >../status.expect <<EOF &&
495 M done/two
496 ?? .gitignore
497 ?? done/five
498 ?? done/sub/
499 ?? dtwo/
501 test_cmp ../status.expect ../status.actual &&
502 cat >../trace.expect <<EOF &&
503 node creation: 2
504 gitignore invalidation: 0
505 directory invalidation: 1
506 opendir: 3
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
517 flags 00000006
518 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
519 .gitignore
520 dtwo/
521 /done/ 1946f0437f90c5005533cbe1736a6451ca301714 recurse valid
522 five
523 sub/
524 /done/sub/ 0000000000000000000000000000000000000000 recurse check_only valid
525 sub/
526 /done/sub/sub/ 0000000000000000000000000000000000000000 recurse check_only valid
527 file
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' '
536 avoid_racy &&
537 : >../trace &&
538 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
539 git status --porcelain >../status.actual &&
540 test_cmp ../status.expect ../status.actual &&
541 cat >../trace.expect <<EOF &&
542 node creation: 0
543 gitignore invalidation: 0
544 directory invalidation: 0
545 opendir: 0
547 test_cmp ../trace.expect ../trace
550 test_expect_success 'move entry in subdir from untracked to cached' '
551 git add dtwo/two &&
552 git status --porcelain >../status.actual &&
553 cat >../status.expect <<EOF &&
554 M done/two
555 A dtwo/two
556 ?? .gitignore
557 ?? done/five
558 ?? done/sub/
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 &&
567 M done/two
568 ?? .gitignore
569 ?? done/five
570 ?? done/sub/
571 ?? dtwo/
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' '
584 git status &&
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 &&
593 git status &&
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 &&
611 git status &&
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 &&
627 git status &&
628 test-dump-untracked-cache >../actual &&
629 test_cmp ../expect-from-test-dump ../actual &&
630 git update-index --no-untracked-cache &&
631 test-dump-untracked-cache >../actual &&
632 test_cmp ../expect-no-uc ../actual &&
633 git update-index --force-untracked-cache &&
634 test-dump-untracked-cache >../actual &&
635 test_cmp ../expect-empty ../actual &&
636 git status &&
637 test-dump-untracked-cache >../actual &&
638 test_cmp ../expect-from-test-dump ../actual
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_i18ncmp ../expect ../err
649 test_done