]> git.ipfire.org Git - thirdparty/git.git/blob - t/t6302-for-each-ref-filter.sh
submodule-config.c: strengthen URL fsck check
[thirdparty/git.git] / t / t6302-for-each-ref-filter.sh
1 #!/bin/sh
2
3 test_description='test for-each-refs usage of ref-filter APIs'
4
5 . ./test-lib.sh
6 . "$TEST_DIRECTORY"/lib-gpg.sh
7
8 test_expect_success 'setup some history and refs' '
9 test_commit one &&
10 git branch -M main &&
11 test_commit two &&
12 test_commit three &&
13 git checkout -b side &&
14 test_commit four &&
15 git tag -m "An annotated tag" annotated-tag &&
16 git tag -m "Annonated doubly" doubly-annotated-tag annotated-tag &&
17
18 # Note that these "signed" tags might not actually be signed.
19 # Tests which care about the distinction should be marked
20 # with the GPG prereq.
21 if test_have_prereq GPG
22 then
23 sign=-s
24 else
25 sign=
26 fi &&
27 git tag $sign -m "A signed tag" signed-tag &&
28 git tag $sign -m "Signed doubly" doubly-signed-tag signed-tag &&
29
30 git checkout main &&
31 git update-ref refs/odd/spot main
32 '
33
34 test_expect_success 'filtering with --points-at' '
35 cat >expect <<-\EOF &&
36 refs/heads/main
37 refs/odd/spot
38 refs/tags/three
39 EOF
40 git for-each-ref --format="%(refname)" --points-at=main >actual &&
41 test_cmp expect actual
42 '
43
44 test_expect_success 'check signed tags with --points-at' '
45 sed -e "s/Z$//" >expect <<-\EOF &&
46 refs/heads/side Z
47 refs/tags/annotated-tag four
48 refs/tags/doubly-annotated-tag An annotated tag
49 refs/tags/doubly-signed-tag A signed tag
50 refs/tags/four Z
51 refs/tags/signed-tag four
52 EOF
53 git for-each-ref --format="%(refname) %(*subject)" --points-at=side >actual &&
54 test_cmp expect actual
55 '
56
57 test_expect_success 'filtering with --merged' '
58 cat >expect <<-\EOF &&
59 refs/heads/main
60 refs/odd/spot
61 refs/tags/one
62 refs/tags/three
63 refs/tags/two
64 EOF
65 git for-each-ref --format="%(refname)" --merged=main >actual &&
66 test_cmp expect actual
67 '
68
69 test_expect_success 'filtering with --no-merged' '
70 cat >expect <<-\EOF &&
71 refs/heads/side
72 refs/tags/annotated-tag
73 refs/tags/doubly-annotated-tag
74 refs/tags/doubly-signed-tag
75 refs/tags/four
76 refs/tags/signed-tag
77 EOF
78 git for-each-ref --format="%(refname)" --no-merged=main >actual &&
79 test_cmp expect actual
80 '
81
82 test_expect_success 'filtering with --contains' '
83 cat >expect <<-\EOF &&
84 refs/heads/main
85 refs/heads/side
86 refs/odd/spot
87 refs/tags/annotated-tag
88 refs/tags/doubly-annotated-tag
89 refs/tags/doubly-signed-tag
90 refs/tags/four
91 refs/tags/signed-tag
92 refs/tags/three
93 refs/tags/two
94 EOF
95 git for-each-ref --format="%(refname)" --contains=two >actual &&
96 test_cmp expect actual
97 '
98
99 test_expect_success 'filtering with --no-contains' '
100 cat >expect <<-\EOF &&
101 refs/tags/one
102 EOF
103 git for-each-ref --format="%(refname)" --no-contains=two >actual &&
104 test_cmp expect actual
105 '
106
107 test_expect_success 'filtering with --contains and --no-contains' '
108 cat >expect <<-\EOF &&
109 refs/tags/two
110 EOF
111 git for-each-ref --format="%(refname)" --contains=two --no-contains=three >actual &&
112 test_cmp expect actual
113 '
114
115 test_expect_success '%(color) must fail' '
116 test_must_fail git for-each-ref --format="%(color)%(refname)"
117 '
118
119 test_expect_success '%(color:#aa22ac) must succeed' '
120 test_when_finished rm -rf test &&
121 git init test &&
122 (
123 cd test &&
124 test_commit initial &&
125 git branch -M main &&
126 cat >expect <<-\EOF &&
127 refs/heads/main
128 refs/tags/initial
129 EOF
130 git remote add origin nowhere &&
131 git config branch.main.remote origin &&
132 git config branch.main.merge refs/heads/main &&
133 git for-each-ref --format="%(color:#aa22ac)%(refname)" >actual &&
134 test_cmp expect actual
135 )
136 '
137
138 test_expect_success 'left alignment is default' '
139 cat >expect <<-\EOF &&
140 refname is refs/heads/main |refs/heads/main
141 refname is refs/heads/side |refs/heads/side
142 refname is refs/odd/spot |refs/odd/spot
143 refname is refs/tags/annotated-tag|refs/tags/annotated-tag
144 refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
145 refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
146 refname is refs/tags/four |refs/tags/four
147 refname is refs/tags/one |refs/tags/one
148 refname is refs/tags/signed-tag|refs/tags/signed-tag
149 refname is refs/tags/three |refs/tags/three
150 refname is refs/tags/two |refs/tags/two
151 EOF
152 git for-each-ref --format="%(align:30)refname is %(refname)%(end)|%(refname)" >actual &&
153 test_cmp expect actual
154 '
155
156 test_expect_success 'middle alignment' '
157 cat >expect <<-\EOF &&
158 | refname is refs/heads/main |refs/heads/main
159 | refname is refs/heads/side |refs/heads/side
160 | refname is refs/odd/spot |refs/odd/spot
161 |refname is refs/tags/annotated-tag|refs/tags/annotated-tag
162 |refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
163 |refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
164 | refname is refs/tags/four |refs/tags/four
165 | refname is refs/tags/one |refs/tags/one
166 |refname is refs/tags/signed-tag|refs/tags/signed-tag
167 | refname is refs/tags/three |refs/tags/three
168 | refname is refs/tags/two |refs/tags/two
169 EOF
170 git for-each-ref --format="|%(align:middle,30)refname is %(refname)%(end)|%(refname)" >actual &&
171 test_cmp expect actual
172 '
173
174 test_expect_success 'right alignment' '
175 cat >expect <<-\EOF &&
176 | refname is refs/heads/main|refs/heads/main
177 | refname is refs/heads/side|refs/heads/side
178 | refname is refs/odd/spot|refs/odd/spot
179 |refname is refs/tags/annotated-tag|refs/tags/annotated-tag
180 |refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
181 |refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
182 | refname is refs/tags/four|refs/tags/four
183 | refname is refs/tags/one|refs/tags/one
184 |refname is refs/tags/signed-tag|refs/tags/signed-tag
185 | refname is refs/tags/three|refs/tags/three
186 | refname is refs/tags/two|refs/tags/two
187 EOF
188 git for-each-ref --format="|%(align:30,right)refname is %(refname)%(end)|%(refname)" >actual &&
189 test_cmp expect actual
190 '
191
192 cat >expect <<-\EOF
193 | refname is refs/heads/main |refs/heads/main
194 | refname is refs/heads/side |refs/heads/side
195 | refname is refs/odd/spot |refs/odd/spot
196 | refname is refs/tags/annotated-tag |refs/tags/annotated-tag
197 |refname is refs/tags/doubly-annotated-tag |refs/tags/doubly-annotated-tag
198 | refname is refs/tags/doubly-signed-tag |refs/tags/doubly-signed-tag
199 | refname is refs/tags/four |refs/tags/four
200 | refname is refs/tags/one |refs/tags/one
201 | refname is refs/tags/signed-tag |refs/tags/signed-tag
202 | refname is refs/tags/three |refs/tags/three
203 | refname is refs/tags/two |refs/tags/two
204 EOF
205
206 test_align_permutations() {
207 while read -r option
208 do
209 test_expect_success "align:$option" '
210 git for-each-ref --format="|%(align:$option)refname is %(refname)%(end)|%(refname)" >actual &&
211 test_cmp expect actual
212 '
213 done
214 }
215
216 test_align_permutations <<-\EOF
217 middle,42
218 42,middle
219 position=middle,42
220 42,position=middle
221 middle,width=42
222 width=42,middle
223 position=middle,width=42
224 width=42,position=middle
225 EOF
226
227 # Last one wins (silently) when multiple arguments of the same type are given
228
229 test_align_permutations <<-\EOF
230 32,width=42,middle
231 width=30,42,middle
232 width=42,position=right,middle
233 42,right,position=middle
234 EOF
235
236 # Individual atoms inside %(align:...) and %(end) must not be quoted.
237
238 test_expect_success 'alignment with format quote' "
239 cat >expect <<-\EOF &&
240 |' '\''main| A U Thor'\'' '|
241 |' '\''side| A U Thor'\'' '|
242 |' '\''odd/spot| A U Thor'\'' '|
243 |' '\''annotated-tag| '\'' '|
244 |' '\''doubly-annotated-tag| '\'' '|
245 |' '\''doubly-signed-tag| '\'' '|
246 |' '\''four| A U Thor'\'' '|
247 |' '\''one| A U Thor'\'' '|
248 |' '\''signed-tag| '\'' '|
249 |' '\''three| A U Thor'\'' '|
250 |' '\''two| A U Thor'\'' '|
251 EOF
252 git for-each-ref --shell --format=\"|%(align:30,middle)'%(refname:short)| %(authorname)'%(end)|\" >actual &&
253 test_cmp expect actual
254 "
255
256 test_expect_success 'nested alignment with quote formatting' "
257 cat >expect <<-\EOF &&
258 |' main '|
259 |' side '|
260 |' odd/spot '|
261 |' annotated-tag '|
262 |'doubly-annotated-tag '|
263 |'doubly-signed-tag '|
264 |' four '|
265 |' one '|
266 |' signed-tag '|
267 |' three '|
268 |' two '|
269 EOF
270 git for-each-ref --shell --format='|%(align:30,left)%(align:15,right)%(refname:short)%(end)%(end)|' >actual &&
271 test_cmp expect actual
272 "
273
274 test_expect_success 'check `%(contents:lines=1)`' '
275 cat >expect <<-\EOF &&
276 main |three
277 side |four
278 odd/spot |three
279 annotated-tag |An annotated tag
280 doubly-annotated-tag |Annonated doubly
281 doubly-signed-tag |Signed doubly
282 four |four
283 one |one
284 signed-tag |A signed tag
285 three |three
286 two |two
287 EOF
288 git for-each-ref --format="%(refname:short) |%(contents:lines=1)" >actual &&
289 test_cmp expect actual
290 '
291
292 test_expect_success 'check `%(contents:lines=0)`' '
293 cat >expect <<-\EOF &&
294 main |
295 side |
296 odd/spot |
297 annotated-tag |
298 doubly-annotated-tag |
299 doubly-signed-tag |
300 four |
301 one |
302 signed-tag |
303 three |
304 two |
305 EOF
306 git for-each-ref --format="%(refname:short) |%(contents:lines=0)" >actual &&
307 test_cmp expect actual
308 '
309
310 test_expect_success 'check `%(contents:lines=99999)`' '
311 cat >expect <<-\EOF &&
312 main |three
313 side |four
314 odd/spot |three
315 annotated-tag |An annotated tag
316 doubly-annotated-tag |Annonated doubly
317 doubly-signed-tag |Signed doubly
318 four |four
319 one |one
320 signed-tag |A signed tag
321 three |three
322 two |two
323 EOF
324 git for-each-ref --format="%(refname:short) |%(contents:lines=99999)" >actual &&
325 test_cmp expect actual
326 '
327
328 test_expect_success '`%(contents:lines=-1)` should fail' '
329 test_must_fail git for-each-ref --format="%(refname:short) |%(contents:lines=-1)"
330 '
331
332 test_expect_success 'setup for version sort' '
333 test_commit foo1.3 &&
334 test_commit foo1.6 &&
335 test_commit foo1.10
336 '
337
338 test_expect_success 'version sort' '
339 git for-each-ref --sort=version:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
340 cat >expect <<-\EOF &&
341 foo1.3
342 foo1.6
343 foo1.10
344 EOF
345 test_cmp expect actual
346 '
347
348 test_expect_success 'version sort (shortened)' '
349 git for-each-ref --sort=v:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
350 cat >expect <<-\EOF &&
351 foo1.3
352 foo1.6
353 foo1.10
354 EOF
355 test_cmp expect actual
356 '
357
358 test_expect_success 'reverse version sort' '
359 git for-each-ref --sort=-version:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
360 cat >expect <<-\EOF &&
361 foo1.10
362 foo1.6
363 foo1.3
364 EOF
365 test_cmp expect actual
366 '
367
368 test_expect_success 'improper usage of %(if), %(then), %(else) and %(end) atoms' '
369 test_must_fail git for-each-ref --format="%(if)" &&
370 test_must_fail git for-each-ref --format="%(then) %(end)" &&
371 test_must_fail git for-each-ref --format="%(else) %(end)" &&
372 test_must_fail git for-each-ref --format="%(if) %(else) %(end)" &&
373 test_must_fail git for-each-ref --format="%(if) %(then) %(then) %(end)" &&
374 test_must_fail git for-each-ref --format="%(then) %(else) %(end)" &&
375 test_must_fail git for-each-ref --format="%(if) %(else) %(end)" &&
376 test_must_fail git for-each-ref --format="%(if) %(then) %(else)" &&
377 test_must_fail git for-each-ref --format="%(if) %(else) %(then) %(end)" &&
378 test_must_fail git for-each-ref --format="%(if) %(then) %(else) %(else) %(end)" &&
379 test_must_fail git for-each-ref --format="%(if) %(end)"
380 '
381
382 test_expect_success 'check %(if)...%(then)...%(end) atoms' '
383 git for-each-ref --format="%(refname)%(if)%(authorname)%(then) Author: %(authorname)%(end)" >actual &&
384 cat >expect <<-\EOF &&
385 refs/heads/main Author: A U Thor
386 refs/heads/side Author: A U Thor
387 refs/odd/spot Author: A U Thor
388 refs/tags/annotated-tag
389 refs/tags/doubly-annotated-tag
390 refs/tags/doubly-signed-tag
391 refs/tags/foo1.10 Author: A U Thor
392 refs/tags/foo1.3 Author: A U Thor
393 refs/tags/foo1.6 Author: A U Thor
394 refs/tags/four Author: A U Thor
395 refs/tags/one Author: A U Thor
396 refs/tags/signed-tag
397 refs/tags/three Author: A U Thor
398 refs/tags/two Author: A U Thor
399 EOF
400 test_cmp expect actual
401 '
402
403 test_expect_success 'check %(if)...%(then)...%(else)...%(end) atoms' '
404 git for-each-ref --format="%(if)%(authorname)%(then)%(authorname)%(else)No author%(end): %(refname)" >actual &&
405 cat >expect <<-\EOF &&
406 A U Thor: refs/heads/main
407 A U Thor: refs/heads/side
408 A U Thor: refs/odd/spot
409 No author: refs/tags/annotated-tag
410 No author: refs/tags/doubly-annotated-tag
411 No author: refs/tags/doubly-signed-tag
412 A U Thor: refs/tags/foo1.10
413 A U Thor: refs/tags/foo1.3
414 A U Thor: refs/tags/foo1.6
415 A U Thor: refs/tags/four
416 A U Thor: refs/tags/one
417 No author: refs/tags/signed-tag
418 A U Thor: refs/tags/three
419 A U Thor: refs/tags/two
420 EOF
421 test_cmp expect actual
422 '
423 test_expect_success 'ignore spaces in %(if) atom usage' '
424 git for-each-ref --format="%(refname:short): %(if)%(HEAD)%(then)Head ref%(else)Not Head ref%(end)" >actual &&
425 cat >expect <<-\EOF &&
426 main: Head ref
427 side: Not Head ref
428 odd/spot: Not Head ref
429 annotated-tag: Not Head ref
430 doubly-annotated-tag: Not Head ref
431 doubly-signed-tag: Not Head ref
432 foo1.10: Not Head ref
433 foo1.3: Not Head ref
434 foo1.6: Not Head ref
435 four: Not Head ref
436 one: Not Head ref
437 signed-tag: Not Head ref
438 three: Not Head ref
439 two: Not Head ref
440 EOF
441 test_cmp expect actual
442 '
443
444 test_expect_success 'check %(if:equals=<string>)' '
445 git for-each-ref --format="%(if:equals=main)%(refname:short)%(then)Found main%(else)Not main%(end)" refs/heads/ >actual &&
446 cat >expect <<-\EOF &&
447 Found main
448 Not main
449 EOF
450 test_cmp expect actual
451 '
452
453 test_expect_success 'check %(if:notequals=<string>)' '
454 git for-each-ref --format="%(if:notequals=main)%(refname:short)%(then)Not main%(else)Found main%(end)" refs/heads/ >actual &&
455 cat >expect <<-\EOF &&
456 Found main
457 Not main
458 EOF
459 test_cmp expect actual
460 '
461
462 test_expect_success '--merged is compatible with --no-merged' '
463 git for-each-ref --merged HEAD --no-merged HEAD
464 '
465
466 test_expect_success 'validate worktree atom' '
467 cat >expect <<-EOF &&
468 main: $(pwd)
469 main_worktree: $(pwd)/worktree_dir
470 side: not checked out
471 EOF
472 git worktree add -b main_worktree worktree_dir main &&
473 git for-each-ref --format="%(refname:short): %(if)%(worktreepath)%(then)%(worktreepath)%(else)not checked out%(end)" refs/heads/ >actual &&
474 rm -r worktree_dir &&
475 git worktree prune &&
476 test_cmp expect actual
477 '
478
479 test_done