t7063: tests for untracked cache

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Mar 8, 2015 at 17:12 UTC a3ddcefd97b0e033eca045f07e0a262e1e7bb483
4 files changed +416
.gitignore
+1
@@ -184,6 +184,7 @@
184 /test-delta
185 /test-dump-cache-tree
186 /test-dump-split-index
187 +/test-dump-untracked-cache
188 /test-scrap-cache-tree
189 /test-genrandom
190 /test-hashmap
Makefile
+1
@@ -570,6 +570,7 @@ TEST_PROGRAMS_NEED_X += test-date
570 TEST_PROGRAMS_NEED_X += test-delta
571 TEST_PROGRAMS_NEED_X += test-dump-cache-tree
572 TEST_PROGRAMS_NEED_X += test-dump-split-index
573 +TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
574 TEST_PROGRAMS_NEED_X += test-genrandom
575 TEST_PROGRAMS_NEED_X += test-hashmap
576 TEST_PROGRAMS_NEED_X += test-index-version
t/t7063-status-untracked-cache.sh new
+353
@@ -0,0 +1,353 @@
1 +#!/bin/sh
2 +
3 +test_description='test untracked cache'
4 +
5 +. ./test-lib.sh
6 +
7 +avoid_racy() {
8 + sleep 1
9 +}
10 +
11 +git 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.
14 +if test $? -eq 1; then
15 + skip_all='This system does not support untracked cache'
16 + test_done
17 +fi
18 +
19 +test_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 +
29 +test_expect_success 'untracked cache is empty' '
30 + test-dump-untracked-cache >../actual &&
31 + cat >../expect <<EOF &&
32 +info/exclude 0000000000000000000000000000000000000000
33 +core.excludesfile 0000000000000000000000000000000000000000
34 +exclude_per_dir .gitignore
35 +flags 00000006
36 +EOF
37 + test_cmp ../expect ../actual
38 +'
39 +
40 +cat >../status.expect <<EOF &&
41 +A done/one
42 +A one
43 +A two
44 +?? dthree/
45 +?? dtwo/
46 +?? three
47 +EOF
48 +
49 +cat >../dump.expect <<EOF &&
50 +info/exclude e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
51 +core.excludesfile 0000000000000000000000000000000000000000
52 +exclude_per_dir .gitignore
53 +flags 00000006
54 +/ 0000000000000000000000000000000000000000 recurse valid
55 +dthree/
56 +dtwo/
57 +three
58 +/done/ 0000000000000000000000000000000000000000 recurse valid
59 +/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
60 +three
61 +/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
62 +two
63 +EOF
64 +
65 +test_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 &&
72 +node creation: 3
73 +gitignore invalidation: 1
74 +directory invalidation: 0
75 +opendir: 4
76 +EOF
77 + test_cmp ../trace.expect ../trace
78 +'
79 +
80 +test_expect_success 'untracked cache after first status' '
81 + test-dump-untracked-cache >../actual &&
82 + test_cmp ../dump.expect ../actual
83 +'
84 +
85 +test_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 &&
92 +node creation: 0
93 +gitignore invalidation: 0
94 +directory invalidation: 0
95 +opendir: 0
96 +EOF
97 + test_cmp ../trace.expect ../trace
98 +'
99 +
100 +test_expect_success 'untracked cache after second status' '
101 + test-dump-untracked-cache >../actual &&
102 + test_cmp ../dump.expect ../actual
103 +'
104 +
105 +test_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 &&
112 +A done/one
113 +A one
114 +A two
115 +?? dthree/
116 +?? dtwo/
117 +?? four
118 +?? three
119 +EOF
120 + test_cmp ../status.expect ../actual &&
121 + cat >../trace.expect <<EOF &&
122 +node creation: 0
123 +gitignore invalidation: 0
124 +directory invalidation: 1
125 +opendir: 1
126 +EOF
127 + test_cmp ../trace.expect ../trace
128 +
129 +'
130 +
131 +test_expect_success 'verify untracked cache dump' '
132 + test-dump-untracked-cache >../actual &&
133 + cat >../expect <<EOF &&
134 +info/exclude e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
135 +core.excludesfile 0000000000000000000000000000000000000000
136 +exclude_per_dir .gitignore
137 +flags 00000006
138 +/ 0000000000000000000000000000000000000000 recurse valid
139 +dthree/
140 +dtwo/
141 +four
142 +three
143 +/done/ 0000000000000000000000000000000000000000 recurse valid
144 +/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
145 +three
146 +/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
147 +two
148 +EOF
149 + test_cmp ../expect ../actual
150 +'
151 +
152 +test_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 &&
159 +A done/one
160 +A one
161 +A two
162 +?? .gitignore
163 +?? dthree/
164 +?? dtwo/
165 +?? three
166 +EOF
167 + test_cmp ../status.expect ../actual &&
168 + cat >../trace.expect <<EOF &&
169 +node creation: 0
170 +gitignore invalidation: 1
171 +directory invalidation: 1
172 +opendir: 4
173 +EOF
174 + test_cmp ../trace.expect ../trace
175 +
176 +'
177 +
178 +test_expect_success 'verify untracked cache dump' '
179 + test-dump-untracked-cache >../actual &&
180 + cat >../expect <<EOF &&
181 +info/exclude e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
182 +core.excludesfile 0000000000000000000000000000000000000000
183 +exclude_per_dir .gitignore
184 +flags 00000006
185 +/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
186 +.gitignore
187 +dthree/
188 +dtwo/
189 +three
190 +/done/ 0000000000000000000000000000000000000000 recurse valid
191 +/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
192 +three
193 +/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
194 +two
195 +EOF
196 + test_cmp ../expect ../actual
197 +'
198 +
199 +test_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 &&
206 +A done/one
207 +A one
208 +A two
209 +?? .gitignore
210 +?? dtwo/
211 +EOF
212 + test_cmp ../status.expect ../actual &&
213 + cat >../trace.expect <<EOF &&
214 +node creation: 0
215 +gitignore invalidation: 1
216 +directory invalidation: 0
217 +opendir: 4
218 +EOF
219 + test_cmp ../trace.expect ../trace
220 +'
221 +
222 +test_expect_success 'verify untracked cache dump' '
223 + test-dump-untracked-cache >../actual &&
224 + cat >../expect <<EOF &&
225 +info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
226 +core.excludesfile 0000000000000000000000000000000000000000
227 +exclude_per_dir .gitignore
228 +flags 00000006
229 +/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
230 +.gitignore
231 +dtwo/
232 +/done/ 0000000000000000000000000000000000000000 recurse valid
233 +/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
234 +/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
235 +two
236 +EOF
237 + test_cmp ../expect ../actual
238 +'
239 +
240 +test_expect_success 'move two from tracked to untracked' '
241 + git rm --cached two &&
242 + test-dump-untracked-cache >../actual &&
243 + cat >../expect <<EOF &&
244 +info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
245 +core.excludesfile 0000000000000000000000000000000000000000
246 +exclude_per_dir .gitignore
247 +flags 00000006
248 +/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse
249 +/done/ 0000000000000000000000000000000000000000 recurse valid
250 +/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
251 +/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
252 +two
253 +EOF
254 + test_cmp ../expect ../actual
255 +'
256 +
257 +test_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 &&
262 +A done/one
263 +A one
264 +?? .gitignore
265 +?? dtwo/
266 +?? two
267 +EOF
268 + test_cmp ../status.expect ../actual &&
269 + cat >../trace.expect <<EOF &&
270 +node creation: 0
271 +gitignore invalidation: 0
272 +directory invalidation: 0
273 +opendir: 1
274 +EOF
275 + test_cmp ../trace.expect ../trace
276 +'
277 +
278 +test_expect_success 'verify untracked cache dump' '
279 + test-dump-untracked-cache >../actual &&
280 + cat >../expect <<EOF &&
281 +info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
282 +core.excludesfile 0000000000000000000000000000000000000000
283 +exclude_per_dir .gitignore
284 +flags 00000006
285 +/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
286 +.gitignore
287 +dtwo/
288 +two
289 +/done/ 0000000000000000000000000000000000000000 recurse valid
290 +/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
291 +/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
292 +two
293 +EOF
294 + test_cmp ../expect ../actual
295 +'
296 +
297 +test_expect_success 'move two from untracked to tracked' '
298 + git add two &&
299 + test-dump-untracked-cache >../actual &&
300 + cat >../expect <<EOF &&
301 +info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
302 +core.excludesfile 0000000000000000000000000000000000000000
303 +exclude_per_dir .gitignore
304 +flags 00000006
305 +/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse
306 +/done/ 0000000000000000000000000000000000000000 recurse valid
307 +/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
308 +/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
309 +two
310 +EOF
311 + test_cmp ../expect ../actual
312 +'
313 +
314 +test_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 &&
319 +A done/one
320 +A one
321 +A two
322 +?? .gitignore
323 +?? dtwo/
324 +EOF
325 + test_cmp ../status.expect ../actual &&
326 + cat >../trace.expect <<EOF &&
327 +node creation: 0
328 +gitignore invalidation: 0
329 +directory invalidation: 0
330 +opendir: 1
331 +EOF
332 + test_cmp ../trace.expect ../trace
333 +'
334 +
335 +test_expect_success 'verify untracked cache dump' '
336 + test-dump-untracked-cache >../actual &&
337 + cat >../expect <<EOF &&
338 +info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
339 +core.excludesfile 0000000000000000000000000000000000000000
340 +exclude_per_dir .gitignore
341 +flags 00000006
342 +/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
343 +.gitignore
344 +dtwo/
345 +/done/ 0000000000000000000000000000000000000000 recurse valid
346 +/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
347 +/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
348 +two
349 +EOF
350 + test_cmp ../expect ../actual
351 +'
352 +
353 +test_done
test-dump-untracked-cache.c new
+61
@@ -0,0 +1,61 @@
1 +#include "cache.h"
2 +#include "dir.h"
3 +
4 +static int compare_untracked(const void *a_, const void *b_)
5 +{
6 + const char *const *a = a_;
7 + const char *const *b = b_;
8 + return strcmp(*a, *b);
9 +}
10 +
11 +static int compare_dir(const void *a_, const void *b_)
12 +{
13 + const struct untracked_cache_dir *const *a = a_;
14 + const struct untracked_cache_dir *const *b = b_;
15 + return strcmp((*a)->name, (*b)->name);
16 +}
17 +
18 +static void dump(struct untracked_cache_dir *ucd, struct strbuf *base)
19 +{
20 + int i, len;
21 + qsort(ucd->untracked, ucd->untracked_nr, sizeof(*ucd->untracked),
22 + compare_untracked);
23 + qsort(ucd->dirs, ucd->dirs_nr, sizeof(*ucd->dirs),
24 + compare_dir);
25 + len = base->len;
26 + strbuf_addf(base, "%s/", ucd->name);
27 + printf("%s %s", base->buf,
28 + sha1_to_hex(ucd->exclude_sha1));
29 + if (ucd->recurse)
30 + fputs(" recurse", stdout);
31 + if (ucd->check_only)
32 + fputs(" check_only", stdout);
33 + if (ucd->valid)
34 + fputs(" valid", stdout);
35 + printf("\n");
36 + for (i = 0; i < ucd->untracked_nr; i++)
37 + printf("%s\n", ucd->untracked[i]);
38 + for (i = 0; i < ucd->dirs_nr; i++)
39 + dump(ucd->dirs[i], base);
40 + strbuf_setlen(base, len);
41 +}
42 +
43 +int main(int ac, char **av)
44 +{
45 + struct untracked_cache *uc;
46 + struct strbuf base = STRBUF_INIT;
47 + if (read_cache() < 0)
48 + die("unable to read index file");
49 + uc = the_index.untracked;
50 + if (!uc) {
51 + printf("no untracked cache\n");
52 + return 0;
53 + }
54 + printf("info/exclude %s\n", sha1_to_hex(uc->ss_info_exclude.sha1));
55 + printf("core.excludesfile %s\n", sha1_to_hex(uc->ss_excludes_file.sha1));
56 + printf("exclude_per_dir %s\n", uc->exclude_per_dir);
57 + printf("flags %08x\n", uc->dir_flags);
58 + if (uc->root)
59 + dump(uc->root, &base);
60 + return 0;
61 +}