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