Merge branch 'cb/t3404-shellquote'
[git/debian.git] / t / t7063-status-untracked-cache.sh
blob0e8d0d42f2f5b1edbc18d46da77c956cd99dadec
1 #!/bin/sh
3 test_description='test untracked cache'
5 . ./test-lib.sh
7 avoid_racy() {
8 sleep 1
11 # It's fine if git update-index returns an error code other than one,
12 # it'll be caught in the first test.
13 test_lazy_prereq UNTRACKED_CACHE '
14 { git update-index --untracked-cache; ret=$?; } &&
15 test $ret -ne 1
18 if ! test_have_prereq UNTRACKED_CACHE; then
19 skip_all='This system does not support untracked cache'
20 test_done
23 test_expect_success 'setup' '
24 git init worktree &&
25 cd worktree &&
26 mkdir done dtwo dthree &&
27 touch one two three done/one dtwo/two dthree/three &&
28 git add one two done/one &&
29 : >.git/info/exclude &&
30 git update-index --untracked-cache
33 test_expect_success 'untracked cache is empty' '
34 test-dump-untracked-cache >../actual &&
35 cat >../expect <<EOF &&
36 info/exclude 0000000000000000000000000000000000000000
37 core.excludesfile 0000000000000000000000000000000000000000
38 exclude_per_dir .gitignore
39 flags 00000006
40 EOF
41 test_cmp ../expect ../actual
44 cat >../status.expect <<EOF &&
45 A done/one
46 A one
47 A two
48 ?? dthree/
49 ?? dtwo/
50 ?? three
51 EOF
53 cat >../dump.expect <<EOF &&
54 info/exclude e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
55 core.excludesfile 0000000000000000000000000000000000000000
56 exclude_per_dir .gitignore
57 flags 00000006
58 / 0000000000000000000000000000000000000000 recurse valid
59 dthree/
60 dtwo/
61 three
62 /done/ 0000000000000000000000000000000000000000 recurse valid
63 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
64 three
65 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
66 two
67 EOF
69 test_expect_success 'status first time (empty cache)' '
70 avoid_racy &&
71 : >../trace &&
72 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
73 git status --porcelain >../actual &&
74 test_cmp ../status.expect ../actual &&
75 cat >../trace.expect <<EOF &&
76 node creation: 3
77 gitignore invalidation: 1
78 directory invalidation: 0
79 opendir: 4
80 EOF
81 test_cmp ../trace.expect ../trace
84 test_expect_success 'untracked cache after first status' '
85 test-dump-untracked-cache >../actual &&
86 test_cmp ../dump.expect ../actual
89 test_expect_success 'status second time (fully populated cache)' '
90 avoid_racy &&
91 : >../trace &&
92 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
93 git status --porcelain >../actual &&
94 test_cmp ../status.expect ../actual &&
95 cat >../trace.expect <<EOF &&
96 node creation: 0
97 gitignore invalidation: 0
98 directory invalidation: 0
99 opendir: 0
101 test_cmp ../trace.expect ../trace
104 test_expect_success 'untracked cache after second status' '
105 test-dump-untracked-cache >../actual &&
106 test_cmp ../dump.expect ../actual
109 test_expect_success 'modify in root directory, one dir invalidation' '
110 avoid_racy &&
111 : >four &&
112 : >../trace &&
113 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
114 git status --porcelain >../actual &&
115 cat >../status.expect <<EOF &&
116 A done/one
117 A one
118 A two
119 ?? dthree/
120 ?? dtwo/
121 ?? four
122 ?? three
124 test_cmp ../status.expect ../actual &&
125 cat >../trace.expect <<EOF &&
126 node creation: 0
127 gitignore invalidation: 0
128 directory invalidation: 1
129 opendir: 1
131 test_cmp ../trace.expect ../trace
135 test_expect_success 'verify untracked cache dump' '
136 test-dump-untracked-cache >../actual &&
137 cat >../expect <<EOF &&
138 info/exclude e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
139 core.excludesfile 0000000000000000000000000000000000000000
140 exclude_per_dir .gitignore
141 flags 00000006
142 / 0000000000000000000000000000000000000000 recurse valid
143 dthree/
144 dtwo/
145 four
146 three
147 /done/ 0000000000000000000000000000000000000000 recurse valid
148 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
149 three
150 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
153 test_cmp ../expect ../actual
156 test_expect_success 'new .gitignore invalidates recursively' '
157 avoid_racy &&
158 echo four >.gitignore &&
159 : >../trace &&
160 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
161 git status --porcelain >../actual &&
162 cat >../status.expect <<EOF &&
163 A done/one
164 A one
165 A two
166 ?? .gitignore
167 ?? dthree/
168 ?? dtwo/
169 ?? three
171 test_cmp ../status.expect ../actual &&
172 cat >../trace.expect <<EOF &&
173 node creation: 0
174 gitignore invalidation: 1
175 directory invalidation: 1
176 opendir: 4
178 test_cmp ../trace.expect ../trace
182 test_expect_success 'verify untracked cache dump' '
183 test-dump-untracked-cache >../actual &&
184 cat >../expect <<EOF &&
185 info/exclude e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
186 core.excludesfile 0000000000000000000000000000000000000000
187 exclude_per_dir .gitignore
188 flags 00000006
189 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
190 .gitignore
191 dthree/
192 dtwo/
193 three
194 /done/ 0000000000000000000000000000000000000000 recurse valid
195 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
196 three
197 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
200 test_cmp ../expect ../actual
203 test_expect_success 'new info/exclude invalidates everything' '
204 avoid_racy &&
205 echo three >>.git/info/exclude &&
206 : >../trace &&
207 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
208 git status --porcelain >../actual &&
209 cat >../status.expect <<EOF &&
210 A done/one
211 A one
212 A two
213 ?? .gitignore
214 ?? dtwo/
216 test_cmp ../status.expect ../actual &&
217 cat >../trace.expect <<EOF &&
218 node creation: 0
219 gitignore invalidation: 1
220 directory invalidation: 0
221 opendir: 4
223 test_cmp ../trace.expect ../trace
226 test_expect_success 'verify untracked cache dump' '
227 test-dump-untracked-cache >../actual &&
228 cat >../expect <<EOF &&
229 info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
230 core.excludesfile 0000000000000000000000000000000000000000
231 exclude_per_dir .gitignore
232 flags 00000006
233 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
234 .gitignore
235 dtwo/
236 /done/ 0000000000000000000000000000000000000000 recurse valid
237 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
238 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
241 test_cmp ../expect ../actual
244 test_expect_success 'move two from tracked to untracked' '
245 git rm --cached two &&
246 test-dump-untracked-cache >../actual &&
247 cat >../expect <<EOF &&
248 info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
249 core.excludesfile 0000000000000000000000000000000000000000
250 exclude_per_dir .gitignore
251 flags 00000006
252 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse
253 /done/ 0000000000000000000000000000000000000000 recurse valid
254 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
255 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
258 test_cmp ../expect ../actual
261 test_expect_success 'status after the move' '
262 : >../trace &&
263 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
264 git status --porcelain >../actual &&
265 cat >../status.expect <<EOF &&
266 A done/one
267 A one
268 ?? .gitignore
269 ?? dtwo/
270 ?? two
272 test_cmp ../status.expect ../actual &&
273 cat >../trace.expect <<EOF &&
274 node creation: 0
275 gitignore invalidation: 0
276 directory invalidation: 0
277 opendir: 1
279 test_cmp ../trace.expect ../trace
282 test_expect_success 'verify untracked cache dump' '
283 test-dump-untracked-cache >../actual &&
284 cat >../expect <<EOF &&
285 info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
286 core.excludesfile 0000000000000000000000000000000000000000
287 exclude_per_dir .gitignore
288 flags 00000006
289 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
290 .gitignore
291 dtwo/
293 /done/ 0000000000000000000000000000000000000000 recurse valid
294 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
295 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
298 test_cmp ../expect ../actual
301 test_expect_success 'move two from untracked to tracked' '
302 git add two &&
303 test-dump-untracked-cache >../actual &&
304 cat >../expect <<EOF &&
305 info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
306 core.excludesfile 0000000000000000000000000000000000000000
307 exclude_per_dir .gitignore
308 flags 00000006
309 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse
310 /done/ 0000000000000000000000000000000000000000 recurse valid
311 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
312 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
315 test_cmp ../expect ../actual
318 test_expect_success 'status after the move' '
319 : >../trace &&
320 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
321 git status --porcelain >../actual &&
322 cat >../status.expect <<EOF &&
323 A done/one
324 A one
325 A two
326 ?? .gitignore
327 ?? dtwo/
329 test_cmp ../status.expect ../actual &&
330 cat >../trace.expect <<EOF &&
331 node creation: 0
332 gitignore invalidation: 0
333 directory invalidation: 0
334 opendir: 1
336 test_cmp ../trace.expect ../trace
339 test_expect_success 'verify untracked cache dump' '
340 test-dump-untracked-cache >../actual &&
341 cat >../expect <<EOF &&
342 info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
343 core.excludesfile 0000000000000000000000000000000000000000
344 exclude_per_dir .gitignore
345 flags 00000006
346 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
347 .gitignore
348 dtwo/
349 /done/ 0000000000000000000000000000000000000000 recurse valid
350 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
351 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
354 test_cmp ../expect ../actual
357 test_expect_success 'set up for sparse checkout testing' '
358 echo two >done/.gitignore &&
359 echo three >>done/.gitignore &&
360 echo two >done/two &&
361 git add -f done/two done/.gitignore &&
362 git commit -m "first commit"
365 test_expect_success 'status after commit' '
366 : >../trace &&
367 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
368 git status --porcelain >../actual &&
369 cat >../status.expect <<EOF &&
370 ?? .gitignore
371 ?? dtwo/
373 test_cmp ../status.expect ../actual &&
374 cat >../trace.expect <<EOF &&
375 node creation: 0
376 gitignore invalidation: 0
377 directory invalidation: 0
378 opendir: 2
380 test_cmp ../trace.expect ../trace
383 test_expect_success 'untracked cache correct after commit' '
384 test-dump-untracked-cache >../actual &&
385 cat >../expect <<EOF &&
386 info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
387 core.excludesfile 0000000000000000000000000000000000000000
388 exclude_per_dir .gitignore
389 flags 00000006
390 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
391 .gitignore
392 dtwo/
393 /done/ 0000000000000000000000000000000000000000 recurse valid
394 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
395 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
398 test_cmp ../expect ../actual
401 test_expect_success 'set up sparse checkout' '
402 echo "done/[a-z]*" >.git/info/sparse-checkout &&
403 test_config core.sparsecheckout true &&
404 git checkout master &&
405 git update-index --force-untracked-cache &&
406 git status --porcelain >/dev/null && # prime the cache
407 test_path_is_missing done/.gitignore &&
408 test_path_is_file done/one
411 test_expect_success 'create/modify files, some of which are gitignored' '
412 echo two bis >done/two &&
413 echo three >done/three && # three is gitignored
414 echo four >done/four && # four is gitignored at a higher level
415 echo five >done/five && # five is not gitignored
416 echo test >base && #we need to ensure that the root dir is touched
417 rm base
420 test_expect_success 'test sparse status with untracked cache' '
421 : >../trace &&
422 avoid_racy &&
423 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
424 git status --porcelain >../status.actual &&
425 cat >../status.expect <<EOF &&
426 M done/two
427 ?? .gitignore
428 ?? done/five
429 ?? dtwo/
431 test_cmp ../status.expect ../status.actual &&
432 cat >../trace.expect <<EOF &&
433 node creation: 0
434 gitignore invalidation: 1
435 directory invalidation: 2
436 opendir: 2
438 test_cmp ../trace.expect ../trace
441 test_expect_success 'untracked cache correct after status' '
442 test-dump-untracked-cache >../actual &&
443 cat >../expect <<EOF &&
444 info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
445 core.excludesfile 0000000000000000000000000000000000000000
446 exclude_per_dir .gitignore
447 flags 00000006
448 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
449 .gitignore
450 dtwo/
451 /done/ 1946f0437f90c5005533cbe1736a6451ca301714 recurse valid
452 five
453 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
454 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
457 test_cmp ../expect ../actual
460 test_expect_success 'test sparse status again with untracked cache' '
461 avoid_racy &&
462 : >../trace &&
463 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
464 git status --porcelain >../status.actual &&
465 cat >../status.expect <<EOF &&
466 M done/two
467 ?? .gitignore
468 ?? done/five
469 ?? dtwo/
471 test_cmp ../status.expect ../status.actual &&
472 cat >../trace.expect <<EOF &&
473 node creation: 0
474 gitignore invalidation: 0
475 directory invalidation: 0
476 opendir: 0
478 test_cmp ../trace.expect ../trace
481 test_expect_success 'set up for test of subdir and sparse checkouts' '
482 mkdir done/sub &&
483 mkdir done/sub/sub &&
484 echo "sub" > done/sub/sub/file
487 test_expect_success 'test sparse status with untracked cache and subdir' '
488 avoid_racy &&
489 : >../trace &&
490 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
491 git status --porcelain >../status.actual &&
492 cat >../status.expect <<EOF &&
493 M done/two
494 ?? .gitignore
495 ?? done/five
496 ?? done/sub/
497 ?? dtwo/
499 test_cmp ../status.expect ../status.actual &&
500 cat >../trace.expect <<EOF &&
501 node creation: 2
502 gitignore invalidation: 0
503 directory invalidation: 1
504 opendir: 3
506 test_cmp ../trace.expect ../trace
509 test_expect_success 'verify untracked cache dump (sparse/subdirs)' '
510 test-dump-untracked-cache >../actual &&
511 cat >../expect <<EOF &&
512 info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
513 core.excludesfile 0000000000000000000000000000000000000000
514 exclude_per_dir .gitignore
515 flags 00000006
516 / e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
517 .gitignore
518 dtwo/
519 /done/ 1946f0437f90c5005533cbe1736a6451ca301714 recurse valid
520 five
521 sub/
522 /done/sub/ 0000000000000000000000000000000000000000 recurse check_only valid
523 sub/
524 /done/sub/sub/ 0000000000000000000000000000000000000000 recurse check_only valid
525 file
526 /dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
527 /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
530 test_cmp ../expect ../actual
533 test_expect_success 'test sparse status again with untracked cache and subdir' '
534 avoid_racy &&
535 : >../trace &&
536 GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
537 git status --porcelain >../status.actual &&
538 test_cmp ../status.expect ../status.actual &&
539 cat >../trace.expect <<EOF &&
540 node creation: 0
541 gitignore invalidation: 0
542 directory invalidation: 0
543 opendir: 0
545 test_cmp ../trace.expect ../trace
548 test_expect_success 'move entry in subdir from untracked to cached' '
549 git add dtwo/two &&
550 git status --porcelain >../status.actual &&
551 cat >../status.expect <<EOF &&
552 M done/two
553 A dtwo/two
554 ?? .gitignore
555 ?? done/five
556 ?? done/sub/
558 test_cmp ../status.expect ../status.actual
561 test_expect_success 'move entry in subdir from cached to untracked' '
562 git rm --cached dtwo/two &&
563 git status --porcelain >../status.actual &&
564 cat >../status.expect <<EOF &&
565 M done/two
566 ?? .gitignore
567 ?? done/five
568 ?? done/sub/
569 ?? dtwo/
571 test_cmp ../status.expect ../status.actual
574 test_done