Merge branch 'tb/commit-graph-genv2-upgrade-fix' into maint
[git/debian.git] / t / t6302-for-each-ref-filter.sh
blob1ce5f490e99d374e039d29e708ee98dfb8988eab
1 #!/bin/sh
3 test_description='test for-each-refs usage of ref-filter APIs'
5 . ./test-lib.sh
6 . "$TEST_DIRECTORY"/lib-gpg.sh
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 &&
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 &&
30 git checkout main &&
31 git update-ref refs/odd/spot main
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
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/four Z
49 refs/tags/signed-tag four
50 EOF
51 git for-each-ref --format="%(refname) %(*subject)" --points-at=side >actual &&
52 test_cmp expect actual
55 test_expect_success 'filtering with --merged' '
56 cat >expect <<-\EOF &&
57 refs/heads/main
58 refs/odd/spot
59 refs/tags/one
60 refs/tags/three
61 refs/tags/two
62 EOF
63 git for-each-ref --format="%(refname)" --merged=main >actual &&
64 test_cmp expect actual
67 test_expect_success 'filtering with --no-merged' '
68 cat >expect <<-\EOF &&
69 refs/heads/side
70 refs/tags/annotated-tag
71 refs/tags/doubly-annotated-tag
72 refs/tags/doubly-signed-tag
73 refs/tags/four
74 refs/tags/signed-tag
75 EOF
76 git for-each-ref --format="%(refname)" --no-merged=main >actual &&
77 test_cmp expect actual
80 test_expect_success 'filtering with --contains' '
81 cat >expect <<-\EOF &&
82 refs/heads/main
83 refs/heads/side
84 refs/odd/spot
85 refs/tags/annotated-tag
86 refs/tags/doubly-annotated-tag
87 refs/tags/doubly-signed-tag
88 refs/tags/four
89 refs/tags/signed-tag
90 refs/tags/three
91 refs/tags/two
92 EOF
93 git for-each-ref --format="%(refname)" --contains=two >actual &&
94 test_cmp expect actual
97 test_expect_success 'filtering with --no-contains' '
98 cat >expect <<-\EOF &&
99 refs/tags/one
101 git for-each-ref --format="%(refname)" --no-contains=two >actual &&
102 test_cmp expect actual
105 test_expect_success 'filtering with --contains and --no-contains' '
106 cat >expect <<-\EOF &&
107 refs/tags/two
109 git for-each-ref --format="%(refname)" --contains=two --no-contains=three >actual &&
110 test_cmp expect actual
113 test_expect_success '%(color) must fail' '
114 test_must_fail git for-each-ref --format="%(color)%(refname)"
117 test_expect_success '%(color:#aa22ac) must succeed' '
118 test_when_finished rm -rf test &&
119 git init test &&
121 cd test &&
122 test_commit initial &&
123 git branch -M main &&
124 cat >expect <<-\EOF &&
125 refs/heads/main
126 refs/tags/initial
128 git remote add origin nowhere &&
129 git config branch.main.remote origin &&
130 git config branch.main.merge refs/heads/main &&
131 git for-each-ref --format="%(color:#aa22ac)%(refname)" >actual &&
132 test_cmp expect actual
136 test_expect_success 'left alignment is default' '
137 cat >expect <<-\EOF &&
138 refname is refs/heads/main |refs/heads/main
139 refname is refs/heads/side |refs/heads/side
140 refname is refs/odd/spot |refs/odd/spot
141 refname is refs/tags/annotated-tag|refs/tags/annotated-tag
142 refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
143 refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
144 refname is refs/tags/four |refs/tags/four
145 refname is refs/tags/one |refs/tags/one
146 refname is refs/tags/signed-tag|refs/tags/signed-tag
147 refname is refs/tags/three |refs/tags/three
148 refname is refs/tags/two |refs/tags/two
150 git for-each-ref --format="%(align:30)refname is %(refname)%(end)|%(refname)" >actual &&
151 test_cmp expect actual
154 test_expect_success 'middle alignment' '
155 cat >expect <<-\EOF &&
156 | refname is refs/heads/main |refs/heads/main
157 | refname is refs/heads/side |refs/heads/side
158 | refname is refs/odd/spot |refs/odd/spot
159 |refname is refs/tags/annotated-tag|refs/tags/annotated-tag
160 |refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
161 |refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
162 | refname is refs/tags/four |refs/tags/four
163 | refname is refs/tags/one |refs/tags/one
164 |refname is refs/tags/signed-tag|refs/tags/signed-tag
165 | refname is refs/tags/three |refs/tags/three
166 | refname is refs/tags/two |refs/tags/two
168 git for-each-ref --format="|%(align:middle,30)refname is %(refname)%(end)|%(refname)" >actual &&
169 test_cmp expect actual
172 test_expect_success 'right alignment' '
173 cat >expect <<-\EOF &&
174 | refname is refs/heads/main|refs/heads/main
175 | refname is refs/heads/side|refs/heads/side
176 | refname is refs/odd/spot|refs/odd/spot
177 |refname is refs/tags/annotated-tag|refs/tags/annotated-tag
178 |refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
179 |refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
180 | refname is refs/tags/four|refs/tags/four
181 | refname is refs/tags/one|refs/tags/one
182 |refname is refs/tags/signed-tag|refs/tags/signed-tag
183 | refname is refs/tags/three|refs/tags/three
184 | refname is refs/tags/two|refs/tags/two
186 git for-each-ref --format="|%(align:30,right)refname is %(refname)%(end)|%(refname)" >actual &&
187 test_cmp expect actual
190 cat >expect <<-\EOF
191 | refname is refs/heads/main |refs/heads/main
192 | refname is refs/heads/side |refs/heads/side
193 | refname is refs/odd/spot |refs/odd/spot
194 | refname is refs/tags/annotated-tag |refs/tags/annotated-tag
195 |refname is refs/tags/doubly-annotated-tag |refs/tags/doubly-annotated-tag
196 | refname is refs/tags/doubly-signed-tag |refs/tags/doubly-signed-tag
197 | refname is refs/tags/four |refs/tags/four
198 | refname is refs/tags/one |refs/tags/one
199 | refname is refs/tags/signed-tag |refs/tags/signed-tag
200 | refname is refs/tags/three |refs/tags/three
201 | refname is refs/tags/two |refs/tags/two
204 test_align_permutations() {
205 while read -r option
207 test_expect_success "align:$option" '
208 git for-each-ref --format="|%(align:$option)refname is %(refname)%(end)|%(refname)" >actual &&
209 test_cmp expect actual
211 done
214 test_align_permutations <<-\EOF
215 middle,42
216 42,middle
217 position=middle,42
218 42,position=middle
219 middle,width=42
220 width=42,middle
221 position=middle,width=42
222 width=42,position=middle
225 # Last one wins (silently) when multiple arguments of the same type are given
227 test_align_permutations <<-\EOF
228 32,width=42,middle
229 width=30,42,middle
230 width=42,position=right,middle
231 42,right,position=middle
234 # Individual atoms inside %(align:...) and %(end) must not be quoted.
236 test_expect_success 'alignment with format quote' "
237 cat >expect <<-\EOF &&
238 |' '\''main| A U Thor'\'' '|
239 |' '\''side| A U Thor'\'' '|
240 |' '\''odd/spot| A U Thor'\'' '|
241 |' '\''annotated-tag| '\'' '|
242 |' '\''doubly-annotated-tag| '\'' '|
243 |' '\''doubly-signed-tag| '\'' '|
244 |' '\''four| A U Thor'\'' '|
245 |' '\''one| A U Thor'\'' '|
246 |' '\''signed-tag| '\'' '|
247 |' '\''three| A U Thor'\'' '|
248 |' '\''two| A U Thor'\'' '|
250 git for-each-ref --shell --format=\"|%(align:30,middle)'%(refname:short)| %(authorname)'%(end)|\" >actual &&
251 test_cmp expect actual
254 test_expect_success 'nested alignment with quote formatting' "
255 cat >expect <<-\EOF &&
256 |' main '|
257 |' side '|
258 |' odd/spot '|
259 |' annotated-tag '|
260 |'doubly-annotated-tag '|
261 |'doubly-signed-tag '|
262 |' four '|
263 |' one '|
264 |' signed-tag '|
265 |' three '|
266 |' two '|
268 git for-each-ref --shell --format='|%(align:30,left)%(align:15,right)%(refname:short)%(end)%(end)|' >actual &&
269 test_cmp expect actual
272 test_expect_success 'check `%(contents:lines=1)`' '
273 cat >expect <<-\EOF &&
274 main |three
275 side |four
276 odd/spot |three
277 annotated-tag |An annotated tag
278 doubly-annotated-tag |Annonated doubly
279 doubly-signed-tag |Signed doubly
280 four |four
281 one |one
282 signed-tag |A signed tag
283 three |three
284 two |two
286 git for-each-ref --format="%(refname:short) |%(contents:lines=1)" >actual &&
287 test_cmp expect actual
290 test_expect_success 'check `%(contents:lines=0)`' '
291 cat >expect <<-\EOF &&
292 main |
293 side |
294 odd/spot |
295 annotated-tag |
296 doubly-annotated-tag |
297 doubly-signed-tag |
298 four |
299 one |
300 signed-tag |
301 three |
302 two |
304 git for-each-ref --format="%(refname:short) |%(contents:lines=0)" >actual &&
305 test_cmp expect actual
308 test_expect_success 'check `%(contents:lines=99999)`' '
309 cat >expect <<-\EOF &&
310 main |three
311 side |four
312 odd/spot |three
313 annotated-tag |An annotated tag
314 doubly-annotated-tag |Annonated doubly
315 doubly-signed-tag |Signed doubly
316 four |four
317 one |one
318 signed-tag |A signed tag
319 three |three
320 two |two
322 git for-each-ref --format="%(refname:short) |%(contents:lines=99999)" >actual &&
323 test_cmp expect actual
326 test_expect_success '`%(contents:lines=-1)` should fail' '
327 test_must_fail git for-each-ref --format="%(refname:short) |%(contents:lines=-1)"
330 test_expect_success 'setup for version sort' '
331 test_commit foo1.3 &&
332 test_commit foo1.6 &&
333 test_commit foo1.10
336 test_expect_success 'version sort' '
337 git for-each-ref --sort=version:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
338 cat >expect <<-\EOF &&
339 foo1.3
340 foo1.6
341 foo1.10
343 test_cmp expect actual
346 test_expect_success 'version sort (shortened)' '
347 git for-each-ref --sort=v:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
348 cat >expect <<-\EOF &&
349 foo1.3
350 foo1.6
351 foo1.10
353 test_cmp expect actual
356 test_expect_success 'reverse version sort' '
357 git for-each-ref --sort=-version:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
358 cat >expect <<-\EOF &&
359 foo1.10
360 foo1.6
361 foo1.3
363 test_cmp expect actual
366 test_expect_success 'improper usage of %(if), %(then), %(else) and %(end) atoms' '
367 test_must_fail git for-each-ref --format="%(if)" &&
368 test_must_fail git for-each-ref --format="%(then) %(end)" &&
369 test_must_fail git for-each-ref --format="%(else) %(end)" &&
370 test_must_fail git for-each-ref --format="%(if) %(else) %(end)" &&
371 test_must_fail git for-each-ref --format="%(if) %(then) %(then) %(end)" &&
372 test_must_fail git for-each-ref --format="%(then) %(else) %(end)" &&
373 test_must_fail git for-each-ref --format="%(if) %(else) %(end)" &&
374 test_must_fail git for-each-ref --format="%(if) %(then) %(else)" &&
375 test_must_fail git for-each-ref --format="%(if) %(else) %(then) %(end)" &&
376 test_must_fail git for-each-ref --format="%(if) %(then) %(else) %(else) %(end)" &&
377 test_must_fail git for-each-ref --format="%(if) %(end)"
380 test_expect_success 'check %(if)...%(then)...%(end) atoms' '
381 git for-each-ref --format="%(refname)%(if)%(authorname)%(then) Author: %(authorname)%(end)" >actual &&
382 cat >expect <<-\EOF &&
383 refs/heads/main Author: A U Thor
384 refs/heads/side Author: A U Thor
385 refs/odd/spot Author: A U Thor
386 refs/tags/annotated-tag
387 refs/tags/doubly-annotated-tag
388 refs/tags/doubly-signed-tag
389 refs/tags/foo1.10 Author: A U Thor
390 refs/tags/foo1.3 Author: A U Thor
391 refs/tags/foo1.6 Author: A U Thor
392 refs/tags/four Author: A U Thor
393 refs/tags/one Author: A U Thor
394 refs/tags/signed-tag
395 refs/tags/three Author: A U Thor
396 refs/tags/two Author: A U Thor
398 test_cmp expect actual
401 test_expect_success 'check %(if)...%(then)...%(else)...%(end) atoms' '
402 git for-each-ref --format="%(if)%(authorname)%(then)%(authorname)%(else)No author%(end): %(refname)" >actual &&
403 cat >expect <<-\EOF &&
404 A U Thor: refs/heads/main
405 A U Thor: refs/heads/side
406 A U Thor: refs/odd/spot
407 No author: refs/tags/annotated-tag
408 No author: refs/tags/doubly-annotated-tag
409 No author: refs/tags/doubly-signed-tag
410 A U Thor: refs/tags/foo1.10
411 A U Thor: refs/tags/foo1.3
412 A U Thor: refs/tags/foo1.6
413 A U Thor: refs/tags/four
414 A U Thor: refs/tags/one
415 No author: refs/tags/signed-tag
416 A U Thor: refs/tags/three
417 A U Thor: refs/tags/two
419 test_cmp expect actual
421 test_expect_success 'ignore spaces in %(if) atom usage' '
422 git for-each-ref --format="%(refname:short): %(if)%(HEAD)%(then)Head ref%(else)Not Head ref%(end)" >actual &&
423 cat >expect <<-\EOF &&
424 main: Head ref
425 side: Not Head ref
426 odd/spot: Not Head ref
427 annotated-tag: Not Head ref
428 doubly-annotated-tag: Not Head ref
429 doubly-signed-tag: Not Head ref
430 foo1.10: Not Head ref
431 foo1.3: Not Head ref
432 foo1.6: Not Head ref
433 four: Not Head ref
434 one: Not Head ref
435 signed-tag: Not Head ref
436 three: Not Head ref
437 two: Not Head ref
439 test_cmp expect actual
442 test_expect_success 'check %(if:equals=<string>)' '
443 git for-each-ref --format="%(if:equals=main)%(refname:short)%(then)Found main%(else)Not main%(end)" refs/heads/ >actual &&
444 cat >expect <<-\EOF &&
445 Found main
446 Not main
448 test_cmp expect actual
451 test_expect_success 'check %(if:notequals=<string>)' '
452 git for-each-ref --format="%(if:notequals=main)%(refname:short)%(then)Not main%(else)Found main%(end)" refs/heads/ >actual &&
453 cat >expect <<-\EOF &&
454 Found main
455 Not main
457 test_cmp expect actual
460 test_expect_success '--merged is compatible with --no-merged' '
461 git for-each-ref --merged HEAD --no-merged HEAD
464 test_expect_success 'validate worktree atom' '
465 cat >expect <<-EOF &&
466 main: $(pwd)
467 main_worktree: $(pwd)/worktree_dir
468 side: not checked out
470 git worktree add -b main_worktree worktree_dir main &&
471 git for-each-ref --format="%(refname:short): %(if)%(worktreepath)%(then)%(worktreepath)%(else)not checked out%(end)" refs/heads/ >actual &&
472 rm -r worktree_dir &&
473 git worktree prune &&
474 test_cmp expect actual
477 test_done