1#!/bin/sh
2
3test_description='test untracked cache'
4
5. ./test-lib.sh
6
7avoid_racy() {
8 sleep 1
9}
10
11# It's fine if git update-index returns an error code other than one,
12# it'll be caught in the first test.
13test_lazy_prereq UNTRACKED_CACHE '
14 { git update-index --untracked-cache; ret=$?; } &&
15 test $ret -ne 1
16'
17
18if ! test_have_prereq UNTRACKED_CACHE; then
19 skip_all='This system does not support untracked cache'
20 test_done
21fi
22
23test_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
31'
32
33test_expect_success 'untracked cache is empty' '
34 test-dump-untracked-cache >../actual &&
35 cat >../expect <<EOF &&
36info/exclude 0000000000000000000000000000000000000000
37core.excludesfile 0000000000000000000000000000000000000000
38exclude_per_dir .gitignore
39flags 00000006
40EOF
41 test_cmp ../expect ../actual
42'
43
44cat >../status.expect <<EOF &&
45A done/one
46A one
47A two
48?? dthree/
49?? dtwo/
50?? three
51EOF
52
53cat >../dump.expect <<EOF &&
54info/exclude e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
55core.excludesfile 0000000000000000000000000000000000000000
56exclude_per_dir .gitignore
57flags 00000006
58/ 0000000000000000000000000000000000000000 recurse valid
59dthree/
60dtwo/
61three
62/done/ 0000000000000000000000000000000000000000 recurse valid
63/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
64three
65/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
66two
67EOF
68
69test_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 &&
76node creation: 3
77gitignore invalidation: 1
78directory invalidation: 0
79opendir: 4
80EOF
81 test_cmp ../trace.expect ../trace
82'
83
84test_expect_success 'untracked cache after first status' '
85 test-dump-untracked-cache >../actual &&
86 test_cmp ../dump.expect ../actual
87'
88
89test_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 &&
96node creation: 0
97gitignore invalidation: 0
98directory invalidation: 0
99opendir: 0
100EOF
101 test_cmp ../trace.expect ../trace
102'
103
104test_expect_success 'untracked cache after second status' '
105 test-dump-untracked-cache >../actual &&
106 test_cmp ../dump.expect ../actual
107'
108
109test_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 &&
116A done/one
117A one
118A two
119?? dthree/
120?? dtwo/
121?? four
122?? three
123EOF
124 test_cmp ../status.expect ../actual &&
125 cat >../trace.expect <<EOF &&
126node creation: 0
127gitignore invalidation: 0
128directory invalidation: 1
129opendir: 1
130EOF
131 test_cmp ../trace.expect ../trace
132
133'
134
135test_expect_success 'verify untracked cache dump' '
136 test-dump-untracked-cache >../actual &&
137 cat >../expect <<EOF &&
138info/exclude e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
139core.excludesfile 0000000000000000000000000000000000000000
140exclude_per_dir .gitignore
141flags 00000006
142/ 0000000000000000000000000000000000000000 recurse valid
143dthree/
144dtwo/
145four
146three
147/done/ 0000000000000000000000000000000000000000 recurse valid
148/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
149three
150/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
151two
152EOF
153 test_cmp ../expect ../actual
154'
155
156test_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 &&
163A done/one
164A one
165A two
166?? .gitignore
167?? dthree/
168?? dtwo/
169?? three
170EOF
171 test_cmp ../status.expect ../actual &&
172 cat >../trace.expect <<EOF &&
173node creation: 0
174gitignore invalidation: 1
175directory invalidation: 1
176opendir: 4
177EOF
178 test_cmp ../trace.expect ../trace
179
180'
181
182test_expect_success 'verify untracked cache dump' '
183 test-dump-untracked-cache >../actual &&
184 cat >../expect <<EOF &&
185info/exclude e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
186core.excludesfile 0000000000000000000000000000000000000000
187exclude_per_dir .gitignore
188flags 00000006
189/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
190.gitignore
191dthree/
192dtwo/
193three
194/done/ 0000000000000000000000000000000000000000 recurse valid
195/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
196three
197/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
198two
199EOF
200 test_cmp ../expect ../actual
201'
202
203test_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 &&
210A done/one
211A one
212A two
213?? .gitignore
214?? dtwo/
215EOF
216 test_cmp ../status.expect ../actual &&
217 cat >../trace.expect <<EOF &&
218node creation: 0
219gitignore invalidation: 1
220directory invalidation: 0
221opendir: 4
222EOF
223 test_cmp ../trace.expect ../trace
224'
225
226test_expect_success 'verify untracked cache dump' '
227 test-dump-untracked-cache >../actual &&
228 cat >../expect <<EOF &&
229info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
230core.excludesfile 0000000000000000000000000000000000000000
231exclude_per_dir .gitignore
232flags 00000006
233/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
234.gitignore
235dtwo/
236/done/ 0000000000000000000000000000000000000000 recurse valid
237/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
238/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
239two
240EOF
241 test_cmp ../expect ../actual
242'
243
244test_expect_success 'move two from tracked to untracked' '
245 git rm --cached two &&
246 test-dump-untracked-cache >../actual &&
247 cat >../expect <<EOF &&
248info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
249core.excludesfile 0000000000000000000000000000000000000000
250exclude_per_dir .gitignore
251flags 00000006
252/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse
253/done/ 0000000000000000000000000000000000000000 recurse valid
254/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
255/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
256two
257EOF
258 test_cmp ../expect ../actual
259'
260
261test_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 &&
266A done/one
267A one
268?? .gitignore
269?? dtwo/
270?? two
271EOF
272 test_cmp ../status.expect ../actual &&
273 cat >../trace.expect <<EOF &&
274node creation: 0
275gitignore invalidation: 0
276directory invalidation: 0
277opendir: 1
278EOF
279 test_cmp ../trace.expect ../trace
280'
281
282test_expect_success 'verify untracked cache dump' '
283 test-dump-untracked-cache >../actual &&
284 cat >../expect <<EOF &&
285info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
286core.excludesfile 0000000000000000000000000000000000000000
287exclude_per_dir .gitignore
288flags 00000006
289/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
290.gitignore
291dtwo/
292two
293/done/ 0000000000000000000000000000000000000000 recurse valid
294/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
295/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
296two
297EOF
298 test_cmp ../expect ../actual
299'
300
301test_expect_success 'move two from untracked to tracked' '
302 git add two &&
303 test-dump-untracked-cache >../actual &&
304 cat >../expect <<EOF &&
305info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
306core.excludesfile 0000000000000000000000000000000000000000
307exclude_per_dir .gitignore
308flags 00000006
309/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse
310/done/ 0000000000000000000000000000000000000000 recurse valid
311/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
312/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
313two
314EOF
315 test_cmp ../expect ../actual
316'
317
318test_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 &&
323A done/one
324A one
325A two
326?? .gitignore
327?? dtwo/
328EOF
329 test_cmp ../status.expect ../actual &&
330 cat >../trace.expect <<EOF &&
331node creation: 0
332gitignore invalidation: 0
333directory invalidation: 0
334opendir: 1
335EOF
336 test_cmp ../trace.expect ../trace
337'
338
339test_expect_success 'verify untracked cache dump' '
340 test-dump-untracked-cache >../actual &&
341 cat >../expect <<EOF &&
342info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
343core.excludesfile 0000000000000000000000000000000000000000
344exclude_per_dir .gitignore
345flags 00000006
346/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
347.gitignore
348dtwo/
349/done/ 0000000000000000000000000000000000000000 recurse valid
350/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
351/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
352two
353EOF
354 test_cmp ../expect ../actual
355'
356
357test_done