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
+}