3 test_description='test for-each-refs usage of ref-filter APIs'
6 . "$TEST_DIRECTORY"/lib-gpg.sh
8 test_expect_success 'setup some history and refs' '
13 git checkout -b side &&
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
27 git tag $sign -m "A signed tag" signed-tag &&
28 git tag $sign -m "Signed doubly" doubly-signed-tag signed-tag &&
31 git update-ref refs/odd/spot main
34 test_expect_success 'filtering with --points-at' '
35 cat >expect <<-\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 &&
47 refs/tags/annotated-tag four
49 refs/tags/signed-tag four
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 &&
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 &&
70 refs/tags/annotated-tag
71 refs/tags/doubly-annotated-tag
72 refs/tags/doubly-signed-tag
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 &&
85 refs/tags/annotated-tag
86 refs/tags/doubly-annotated-tag
87 refs/tags/doubly-signed-tag
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 &&
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 &&
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 'left alignment is default' '
118 cat >expect <<-\EOF &&
119 refname is refs/heads/main |refs/heads/main
120 refname is refs/heads/side |refs/heads/side
121 refname is refs/odd/spot |refs/odd/spot
122 refname is refs/tags/annotated-tag|refs/tags/annotated-tag
123 refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
124 refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
125 refname is refs/tags/four |refs/tags/four
126 refname is refs/tags/one |refs/tags/one
127 refname is refs/tags/signed-tag|refs/tags/signed-tag
128 refname is refs/tags/three |refs/tags/three
129 refname is refs/tags/two |refs/tags/two
131 git for-each-ref --format="%(align:30)refname is %(refname)%(end)|%(refname)" >actual &&
132 test_cmp expect actual
135 test_expect_success 'middle alignment' '
136 cat >expect <<-\EOF &&
137 | refname is refs/heads/main |refs/heads/main
138 | refname is refs/heads/side |refs/heads/side
139 | refname is refs/odd/spot |refs/odd/spot
140 |refname is refs/tags/annotated-tag|refs/tags/annotated-tag
141 |refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
142 |refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
143 | refname is refs/tags/four |refs/tags/four
144 | refname is refs/tags/one |refs/tags/one
145 |refname is refs/tags/signed-tag|refs/tags/signed-tag
146 | refname is refs/tags/three |refs/tags/three
147 | refname is refs/tags/two |refs/tags/two
149 git for-each-ref --format="|%(align:middle,30)refname is %(refname)%(end)|%(refname)" >actual &&
150 test_cmp expect actual
153 test_expect_success 'right alignment' '
154 cat >expect <<-\EOF &&
155 | refname is refs/heads/main|refs/heads/main
156 | refname is refs/heads/side|refs/heads/side
157 | refname is refs/odd/spot|refs/odd/spot
158 |refname is refs/tags/annotated-tag|refs/tags/annotated-tag
159 |refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
160 |refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
161 | refname is refs/tags/four|refs/tags/four
162 | refname is refs/tags/one|refs/tags/one
163 |refname is refs/tags/signed-tag|refs/tags/signed-tag
164 | refname is refs/tags/three|refs/tags/three
165 | refname is refs/tags/two|refs/tags/two
167 git for-each-ref --format="|%(align:30,right)refname is %(refname)%(end)|%(refname)" >actual &&
168 test_cmp expect actual
172 | refname is refs/heads/main |refs/heads/main
173 | refname is refs/heads/side |refs/heads/side
174 | refname is refs/odd/spot |refs/odd/spot
175 | refname is refs/tags/annotated-tag |refs/tags/annotated-tag
176 |refname is refs/tags/doubly-annotated-tag |refs/tags/doubly-annotated-tag
177 | refname is refs/tags/doubly-signed-tag |refs/tags/doubly-signed-tag
178 | refname is refs/tags/four |refs/tags/four
179 | refname is refs/tags/one |refs/tags/one
180 | refname is refs/tags/signed-tag |refs/tags/signed-tag
181 | refname is refs/tags/three |refs/tags/three
182 | refname is refs/tags/two |refs/tags/two
185 test_align_permutations() {
188 test_expect_success "align:$option" '
189 git for-each-ref --format="|%(align:$option)refname is %(refname)%(end)|%(refname)" >actual &&
190 test_cmp expect actual
195 test_align_permutations <<-\EOF
202 position=middle,width=42
203 width=42,position=middle
206 # Last one wins (silently) when multiple arguments of the same type are given
208 test_align_permutations <<-\EOF
211 width=42,position=right,middle
212 42,right,position=middle
215 # Individual atoms inside %(align:...) and %(end) must not be quoted.
217 test_expect_success 'alignment with format quote' "
218 cat >expect <<-\EOF &&
219 |' '\''main| A U Thor'\'' '|
220 |' '\''side| A U Thor'\'' '|
221 |' '\''odd/spot| A U Thor'\'' '|
222 |' '\''annotated-tag| '\'' '|
223 |' '\''doubly-annotated-tag| '\'' '|
224 |' '\''doubly-signed-tag| '\'' '|
225 |' '\''four| A U Thor'\'' '|
226 |' '\''one| A U Thor'\'' '|
227 |' '\''signed-tag| '\'' '|
228 |' '\''three| A U Thor'\'' '|
229 |' '\''two| A U Thor'\'' '|
231 git for-each-ref --shell --format=\"|%(align:30,middle)'%(refname:short)| %(authorname)'%(end)|\" >actual &&
232 test_cmp expect actual
235 test_expect_success 'nested alignment with quote formatting' "
236 cat >expect <<-\EOF &&
241 |'doubly-annotated-tag '|
242 |'doubly-signed-tag '|
249 git for-each-ref --shell --format='|%(align:30,left)%(align:15,right)%(refname:short)%(end)%(end)|' >actual &&
250 test_cmp expect actual
253 test_expect_success 'check `%(contents:lines=1)`' '
254 cat >expect <<-\EOF &&
258 annotated-tag |An annotated tag
259 doubly-annotated-tag |Annonated doubly
260 doubly-signed-tag |Signed doubly
263 signed-tag |A signed tag
267 git for-each-ref --format="%(refname:short) |%(contents:lines=1)" >actual &&
268 test_cmp expect actual
271 test_expect_success 'check `%(contents:lines=0)`' '
272 cat >expect <<-\EOF &&
277 doubly-annotated-tag |
285 git for-each-ref --format="%(refname:short) |%(contents:lines=0)" >actual &&
286 test_cmp expect actual
289 test_expect_success 'check `%(contents:lines=99999)`' '
290 cat >expect <<-\EOF &&
294 annotated-tag |An annotated tag
295 doubly-annotated-tag |Annonated doubly
296 doubly-signed-tag |Signed doubly
299 signed-tag |A signed tag
303 git for-each-ref --format="%(refname:short) |%(contents:lines=99999)" >actual &&
304 test_cmp expect actual
307 test_expect_success '`%(contents:lines=-1)` should fail' '
308 test_must_fail git for-each-ref --format="%(refname:short) |%(contents:lines=-1)"
311 test_expect_success 'setup for version sort' '
312 test_commit foo1.3 &&
313 test_commit foo1.6 &&
317 test_expect_success 'version sort' '
318 git for-each-ref --sort=version:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
319 cat >expect <<-\EOF &&
324 test_cmp expect actual
327 test_expect_success 'version sort (shortened)' '
328 git for-each-ref --sort=v:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
329 cat >expect <<-\EOF &&
334 test_cmp expect actual
337 test_expect_success 'reverse version sort' '
338 git for-each-ref --sort=-version:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
339 cat >expect <<-\EOF &&
344 test_cmp expect actual
347 test_expect_success 'improper usage of %(if), %(then), %(else) and %(end) atoms' '
348 test_must_fail git for-each-ref --format="%(if)" &&
349 test_must_fail git for-each-ref --format="%(then) %(end)" &&
350 test_must_fail git for-each-ref --format="%(else) %(end)" &&
351 test_must_fail git for-each-ref --format="%(if) %(else) %(end)" &&
352 test_must_fail git for-each-ref --format="%(if) %(then) %(then) %(end)" &&
353 test_must_fail git for-each-ref --format="%(then) %(else) %(end)" &&
354 test_must_fail git for-each-ref --format="%(if) %(else) %(end)" &&
355 test_must_fail git for-each-ref --format="%(if) %(then) %(else)" &&
356 test_must_fail git for-each-ref --format="%(if) %(else) %(then) %(end)" &&
357 test_must_fail git for-each-ref --format="%(if) %(then) %(else) %(else) %(end)" &&
358 test_must_fail git for-each-ref --format="%(if) %(end)"
361 test_expect_success 'check %(if)...%(then)...%(end) atoms' '
362 git for-each-ref --format="%(refname)%(if)%(authorname)%(then) Author: %(authorname)%(end)" >actual &&
363 cat >expect <<-\EOF &&
364 refs/heads/main Author: A U Thor
365 refs/heads/side Author: A U Thor
366 refs/odd/spot Author: A U Thor
367 refs/tags/annotated-tag
368 refs/tags/doubly-annotated-tag
369 refs/tags/doubly-signed-tag
370 refs/tags/foo1.10 Author: A U Thor
371 refs/tags/foo1.3 Author: A U Thor
372 refs/tags/foo1.6 Author: A U Thor
373 refs/tags/four Author: A U Thor
374 refs/tags/one Author: A U Thor
376 refs/tags/three Author: A U Thor
377 refs/tags/two Author: A U Thor
379 test_cmp expect actual
382 test_expect_success 'check %(if)...%(then)...%(else)...%(end) atoms' '
383 git for-each-ref --format="%(if)%(authorname)%(then)%(authorname)%(else)No author%(end): %(refname)" >actual &&
384 cat >expect <<-\EOF &&
385 A U Thor: refs/heads/main
386 A U Thor: refs/heads/side
387 A U Thor: refs/odd/spot
388 No author: refs/tags/annotated-tag
389 No author: refs/tags/doubly-annotated-tag
390 No author: refs/tags/doubly-signed-tag
391 A U Thor: refs/tags/foo1.10
392 A U Thor: refs/tags/foo1.3
393 A U Thor: refs/tags/foo1.6
394 A U Thor: refs/tags/four
395 A U Thor: refs/tags/one
396 No author: refs/tags/signed-tag
397 A U Thor: refs/tags/three
398 A U Thor: refs/tags/two
400 test_cmp expect actual
402 test_expect_success 'ignore spaces in %(if) atom usage' '
403 git for-each-ref --format="%(refname:short): %(if)%(HEAD)%(then)Head ref%(else)Not Head ref%(end)" >actual &&
404 cat >expect <<-\EOF &&
407 odd/spot: Not Head ref
408 annotated-tag: Not Head ref
409 doubly-annotated-tag: Not Head ref
410 doubly-signed-tag: Not Head ref
411 foo1.10: Not Head ref
416 signed-tag: Not Head ref
420 test_cmp expect actual
423 test_expect_success 'check %(if:equals=<string>)' '
424 git for-each-ref --format="%(if:equals=main)%(refname:short)%(then)Found main%(else)Not main%(end)" refs/heads/ >actual &&
425 cat >expect <<-\EOF &&
429 test_cmp expect actual
432 test_expect_success 'check %(if:notequals=<string>)' '
433 git for-each-ref --format="%(if:notequals=main)%(refname:short)%(then)Not main%(else)Found main%(end)" refs/heads/ >actual &&
434 cat >expect <<-\EOF &&
438 test_cmp expect actual
441 test_expect_success '--merged is compatible with --no-merged' '
442 git for-each-ref --merged HEAD --no-merged HEAD
445 test_expect_success 'validate worktree atom' '
446 cat >expect <<-EOF &&
448 main_worktree: $(pwd)/worktree_dir
449 side: not checked out
451 git worktree add -b main_worktree worktree_dir main &&
452 git for-each-ref --format="%(refname:short): %(if)%(worktreepath)%(then)%(worktreepath)%(else)not checked out%(end)" refs/heads/ >actual &&
453 rm -r worktree_dir &&
454 git worktree prune &&
455 test_cmp expect actual