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