Git fork
1#!/bin/sh
2
3test_description='test labels in pathspecs'
4
5. ./test-lib.sh
6
7test_expect_success 'setup a tree' '
8 cat <<-\EOF >expect &&
9 fileA
10 fileAB
11 fileAC
12 fileB
13 fileBC
14 fileC
15 fileNoLabel
16 fileSetLabel
17 fileUnsetLabel
18 fileValue
19 fileWrongLabel
20 sub/fileA
21 sub/fileAB
22 sub/fileAC
23 sub/fileB
24 sub/fileBC
25 sub/fileC
26 sub/fileNoLabel
27 sub/fileSetLabel
28 sub/fileUnsetLabel
29 sub/fileValue
30 sub/fileWrongLabel
31 EOF
32 mkdir sub &&
33 while read path
34 do
35 echo content >$path &&
36 git add $path || return 1
37 done <expect &&
38 git commit -m "initial commit" &&
39 git ls-files >actual &&
40 test_cmp expect actual
41'
42
43test_expect_success 'pathspec with no attr' '
44 test_must_fail git ls-files ":(attr:)"
45'
46
47test_expect_success 'pathspec with labels and non existent .gitattributes' '
48 git ls-files ":(attr:label)" >actual &&
49 test_must_be_empty actual
50'
51
52test_expect_success 'pathspec with labels and non existent .gitattributes (2)' '
53 test_must_fail git grep content HEAD -- ":(attr:label)"
54'
55
56test_expect_success 'setup .gitattributes' '
57 cat <<-\EOF >.gitattributes &&
58 fileA labelA
59 fileB labelB
60 fileC labelC
61 fileAB labelA labelB
62 fileAC labelA labelC
63 fileBC labelB labelC
64 fileUnsetLabel -label
65 fileSetLabel label
66 fileValue label=foo
67 fileWrongLabel label☺
68 newFileA* labelA
69 newFileB* labelB
70 EOF
71 echo fileSetLabel label1 >sub/.gitattributes &&
72 git add .gitattributes sub/.gitattributes &&
73 git commit -m "add attributes"
74'
75
76test_expect_success 'setup .gitignore' '
77 cat <<-\EOF >.gitignore &&
78 actual
79 expect
80 pathspec_file
81 EOF
82 git add .gitignore &&
83 git commit -m "add gitignore"
84'
85
86test_expect_success 'check specific set attr' '
87 cat <<-\EOF >expect &&
88 fileSetLabel
89 sub/fileSetLabel
90 EOF
91 git ls-files ":(attr:label)" >actual &&
92 test_cmp expect actual
93'
94
95test_expect_success 'check set attr with pathspec pattern' '
96 echo sub/fileSetLabel >expect &&
97
98 git ls-files ":(attr:label)sub" >actual &&
99 test_cmp expect actual &&
100
101 git ls-files ":(attr:label)sub/" >actual &&
102 test_cmp expect actual
103'
104
105test_expect_success 'check specific set attr in tree-ish' '
106 cat <<-\EOF >expect &&
107 HEAD:fileSetLabel
108 HEAD:sub/fileSetLabel
109 EOF
110 git grep -l content HEAD ":(attr:label)" >actual &&
111 test_cmp expect actual
112'
113
114test_expect_success 'check specific set attr with pathspec pattern in tree-ish' '
115 echo HEAD:sub/fileSetLabel >expect &&
116
117 git grep -l content HEAD ":(attr:label)sub" >actual &&
118 test_cmp expect actual &&
119
120 git grep -l content HEAD ":(attr:label)sub/" >actual &&
121 test_cmp expect actual
122'
123
124test_expect_success 'check specific unset attr' '
125 cat <<-\EOF >expect &&
126 fileUnsetLabel
127 sub/fileUnsetLabel
128 EOF
129 git ls-files ":(attr:-label)" >actual &&
130 test_cmp expect actual
131'
132
133test_expect_success 'check specific unset attr (2)' '
134 cat <<-\EOF >expect &&
135 HEAD:fileUnsetLabel
136 HEAD:sub/fileUnsetLabel
137 EOF
138 git grep -l content HEAD ":(attr:-label)" >actual &&
139 test_cmp expect actual
140'
141
142test_expect_success 'check specific value attr' '
143 cat <<-\EOF >expect &&
144 fileValue
145 sub/fileValue
146 EOF
147 git ls-files ":(attr:label=foo)" >actual &&
148 test_cmp expect actual &&
149 git ls-files ":(attr:label=bar)" >actual &&
150 test_must_be_empty actual
151'
152
153test_expect_success 'check specific value attr (2)' '
154 cat <<-\EOF >expect &&
155 HEAD:fileValue
156 HEAD:sub/fileValue
157 EOF
158 git grep -l content HEAD ":(attr:label=foo)" >actual &&
159 test_cmp expect actual &&
160 test_must_fail git grep -l content HEAD ":(attr:label=bar)"
161'
162
163test_expect_success 'check unspecified attr' '
164 cat <<-\EOF >expect &&
165 .gitattributes
166 .gitignore
167 fileA
168 fileAB
169 fileAC
170 fileB
171 fileBC
172 fileC
173 fileNoLabel
174 fileWrongLabel
175 sub/.gitattributes
176 sub/fileA
177 sub/fileAB
178 sub/fileAC
179 sub/fileB
180 sub/fileBC
181 sub/fileC
182 sub/fileNoLabel
183 sub/fileWrongLabel
184 EOF
185 git ls-files ":(attr:!label)" >actual &&
186 test_cmp expect actual
187'
188
189test_expect_success 'check unspecified attr (2)' '
190 cat <<-\EOF >expect &&
191 HEAD:.gitattributes
192 HEAD:.gitignore
193 HEAD:fileA
194 HEAD:fileAB
195 HEAD:fileAC
196 HEAD:fileB
197 HEAD:fileBC
198 HEAD:fileC
199 HEAD:fileNoLabel
200 HEAD:fileWrongLabel
201 HEAD:sub/.gitattributes
202 HEAD:sub/fileA
203 HEAD:sub/fileAB
204 HEAD:sub/fileAC
205 HEAD:sub/fileB
206 HEAD:sub/fileBC
207 HEAD:sub/fileC
208 HEAD:sub/fileNoLabel
209 HEAD:sub/fileWrongLabel
210 EOF
211 git grep -l ^ HEAD ":(attr:!label)" >actual &&
212 test_cmp expect actual
213'
214
215test_expect_success 'check multiple unspecified attr' '
216 cat <<-\EOF >expect &&
217 .gitattributes
218 .gitignore
219 fileC
220 fileNoLabel
221 fileWrongLabel
222 sub/.gitattributes
223 sub/fileC
224 sub/fileNoLabel
225 sub/fileWrongLabel
226 EOF
227 git ls-files ":(attr:!labelB !labelA !label)" >actual &&
228 test_cmp expect actual
229'
230
231test_expect_success 'check label with more labels but excluded path' '
232 cat <<-\EOF >expect &&
233 fileAB
234 fileB
235 fileBC
236 EOF
237 git ls-files ":(attr:labelB)" ":(exclude)sub/" >actual &&
238 test_cmp expect actual
239'
240
241test_expect_success 'check label excluding other labels' '
242 cat <<-\EOF >expect &&
243 fileAB
244 fileB
245 fileBC
246 sub/fileAB
247 sub/fileB
248 EOF
249 git ls-files ":(attr:labelB)" ":(exclude,attr:labelC)sub/" >actual &&
250 test_cmp expect actual
251'
252
253test_expect_success 'fail on multiple attr specifiers in one pathspec item' '
254 test_must_fail git ls-files . ":(attr:labelB,attr:labelC)" 2>actual &&
255 test_grep "Only one" actual
256'
257
258test_expect_success 'fail if attr magic is used in places not implemented' '
259 # The main purpose of this test is to check that we actually fail
260 # when you attempt to use attr magic in commands that do not implement
261 # attr magic. This test does not advocate check-ignore to stay that way.
262 # When you teach the command to grok the pathspec, you need to find
263 # another command to replace it for the test.
264 test_must_fail git check-ignore ":(attr:labelB)" 2>actual &&
265 test_grep "magic not supported" actual
266'
267
268test_expect_success 'check that attr magic works for git stash push' '
269 cat <<-\EOF >expect &&
270 A sub/newFileA-foo
271 EOF
272 >sub/newFileA-foo &&
273 >sub/newFileB-foo &&
274 git stash push --include-untracked -- ":(exclude,attr:labelB)" &&
275 git stash show --include-untracked --name-status >actual &&
276 test_cmp expect actual
277'
278
279test_expect_success 'check that attr magic works for git add --all' '
280 cat <<-\EOF >expect &&
281 sub/newFileA-foo
282 EOF
283 >sub/newFileA-foo &&
284 >sub/newFileB-foo &&
285 git add --all ":(exclude,attr:labelB)" &&
286 git diff --name-only --cached >actual &&
287 git restore -W -S . &&
288 test_cmp expect actual
289'
290
291test_expect_success 'check that attr magic works for git add -u' '
292 cat <<-\EOF >expect &&
293 sub/fileA
294 EOF
295 >sub/newFileA-foo &&
296 >sub/newFileB-foo &&
297 >sub/fileA &&
298 >sub/fileB &&
299 git add -u ":(exclude,attr:labelB)" &&
300 git diff --name-only --cached >actual &&
301 git restore -S -W . && rm sub/new* &&
302 test_cmp expect actual
303'
304
305test_expect_success 'check that attr magic works for git add <path>' '
306 cat <<-\EOF >expect &&
307 fileA
308 fileB
309 sub/fileA
310 EOF
311 >fileA &&
312 >fileB &&
313 >sub/fileA &&
314 >sub/fileB &&
315 git add ":(exclude,attr:labelB)sub/*" &&
316 git diff --name-only --cached >actual &&
317 git restore -S -W . &&
318 test_cmp expect actual
319'
320
321test_expect_success 'check that attr magic works for git -add .' '
322 cat <<-\EOF >expect &&
323 sub/fileA
324 EOF
325 >fileA &&
326 >fileB &&
327 >sub/fileA &&
328 >sub/fileB &&
329 cd sub &&
330 git add . ":(exclude,attr:labelB)" &&
331 cd .. &&
332 git diff --name-only --cached >actual &&
333 git restore -S -W . &&
334 test_cmp expect actual
335'
336
337test_expect_success 'check that attr magic works for git add --pathspec-from-file' '
338 cat <<-\EOF >pathspec_file &&
339 :(exclude,attr:labelB)
340 EOF
341 cat <<-\EOF >expect &&
342 sub/newFileA-foo
343 EOF
344 >sub/newFileA-foo &&
345 >sub/newFileB-foo &&
346 git add --all --pathspec-from-file=pathspec_file &&
347 git diff --name-only --cached >actual &&
348 test_cmp expect actual
349'
350
351test_expect_success 'abort on giving invalid label on the command line' '
352 test_must_fail git ls-files . ":(attr:☺)"
353'
354
355test_expect_success 'abort on asking for wrong magic' '
356 test_must_fail git ls-files . ":(attr:-label=foo)" &&
357 test_must_fail git ls-files . ":(attr:!label=foo)"
358'
359
360test_expect_success 'check attribute list' '
361 cat <<-EOF >>.gitattributes &&
362 * whitespace=indent,trail,space
363 EOF
364 git ls-files ":(attr:whitespace=indent\,trail\,space)" >actual &&
365 git ls-files >expect &&
366 test_cmp expect actual
367'
368
369test_expect_success 'backslash cannot be the last character' '
370 test_must_fail git ls-files ":(attr:label=foo\\ labelA=bar)" 2>actual &&
371 test_grep "not allowed as last character in attr value" actual
372'
373
374test_expect_success 'backslash cannot be used as a value' '
375 test_must_fail git ls-files ":(attr:label=f\\\oo)" 2>actual &&
376 test_grep "for value matching" actual
377'
378
379test_expect_success 'reading from .gitattributes in a subdirectory (1)' '
380 git ls-files ":(attr:label1)" >actual &&
381 test_write_lines "sub/fileSetLabel" >expect &&
382 test_cmp expect actual
383'
384
385test_expect_success 'reading from .gitattributes in a subdirectory (2)' '
386 git ls-files ":(attr:label1)sub" >actual &&
387 test_write_lines "sub/fileSetLabel" >expect &&
388 test_cmp expect actual
389'
390
391test_expect_success 'reading from .gitattributes in a subdirectory (3)' '
392 git ls-files ":(attr:label1)sub/" >actual &&
393 test_write_lines "sub/fileSetLabel" >expect &&
394 test_cmp expect actual
395'
396
397test_expect_success POSIXPERM 'pathspec with builtin_objectmode attr can be used' '
398 >mode_exec_file_1 &&
399
400 git status -s ":(attr:builtin_objectmode=100644)mode_exec_*" >actual &&
401 echo ?? mode_exec_file_1 >expect &&
402 test_cmp expect actual &&
403
404 git add mode_exec_file_1 &&
405 chmod +x mode_exec_file_1 &&
406 git status -s ":(attr:builtin_objectmode=100755)mode_exec_*" >actual &&
407 echo AM mode_exec_file_1 >expect &&
408 test_cmp expect actual
409'
410
411test_expect_success POSIXPERM 'builtin_objectmode attr can be excluded' '
412 >mode_1_regular &&
413 >mode_1_exec &&
414 chmod +x mode_1_exec &&
415 git status -s ":(exclude,attr:builtin_objectmode=100644)" "mode_1_*" >actual &&
416 echo ?? mode_1_exec >expect &&
417 test_cmp expect actual &&
418
419 git status -s ":(exclude,attr:builtin_objectmode=100755)" "mode_1_*" >actual &&
420 echo ?? mode_1_regular >expect &&
421 test_cmp expect actual
422'
423
424test_done