3 test_description='test for-each-refs usage of ref-filter APIs'
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
9 . "$TEST_DIRECTORY"/lib-gpg.sh
11 test_expect_success 'setup some history and refs' '
16 git checkout -b side &&
18 git tag -m "An annotated tag" annotated-tag &&
19 git tag -m "Annonated doubly" doubly-annotated-tag annotated-tag &&
21 # Note that these "signed" tags might not actually be signed.
22 # Tests which care about the distinction should be marked
23 # with the GPG prereq.
24 if test_have_prereq GPG
30 git tag $sign -m "A signed tag" signed-tag &&
31 git tag $sign -m "Signed doubly" doubly-signed-tag signed-tag &&
34 git update-ref refs/odd/spot main
37 test_expect_success 'filtering with --points-at' '
38 cat >expect <<-\EOF &&
43 git for-each-ref --format="%(refname)" --points-at=main >actual &&
44 test_cmp expect actual
47 test_expect_success 'check signed tags with --points-at' '
48 sed -e "s/Z$//" >expect <<-\EOF &&
50 refs/tags/annotated-tag four
52 refs/tags/signed-tag four
54 git for-each-ref --format="%(refname) %(*subject)" --points-at=side >actual &&
55 test_cmp expect actual
58 test_expect_success 'filtering with --merged' '
59 cat >expect <<-\EOF &&
66 git for-each-ref --format="%(refname)" --merged=main >actual &&
67 test_cmp expect actual
70 test_expect_success 'filtering with --no-merged' '
71 cat >expect <<-\EOF &&
73 refs/tags/annotated-tag
74 refs/tags/doubly-annotated-tag
75 refs/tags/doubly-signed-tag
79 git for-each-ref --format="%(refname)" --no-merged=main >actual &&
80 test_cmp expect actual
83 test_expect_success 'filtering with --contains' '
84 cat >expect <<-\EOF &&
88 refs/tags/annotated-tag
89 refs/tags/doubly-annotated-tag
90 refs/tags/doubly-signed-tag
96 git for-each-ref --format="%(refname)" --contains=two >actual &&
97 test_cmp expect actual
100 test_expect_success 'filtering with --no-contains' '
101 cat >expect <<-\EOF &&
104 git for-each-ref --format="%(refname)" --no-contains=two >actual &&
105 test_cmp expect actual
108 test_expect_success 'filtering with --contains and --no-contains' '
109 cat >expect <<-\EOF &&
112 git for-each-ref --format="%(refname)" --contains=two --no-contains=three >actual &&
113 test_cmp expect actual
116 test_expect_success '%(color) must fail' '
117 test_must_fail git for-each-ref --format="%(color)%(refname)"
120 test_expect_success 'left alignment is default' '
121 cat >expect <<-\EOF &&
122 refname is refs/heads/main |refs/heads/main
123 refname is refs/heads/side |refs/heads/side
124 refname is refs/odd/spot |refs/odd/spot
125 refname is refs/tags/annotated-tag|refs/tags/annotated-tag
126 refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
127 refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
128 refname is refs/tags/four |refs/tags/four
129 refname is refs/tags/one |refs/tags/one
130 refname is refs/tags/signed-tag|refs/tags/signed-tag
131 refname is refs/tags/three |refs/tags/three
132 refname is refs/tags/two |refs/tags/two
134 git for-each-ref --format="%(align:30)refname is %(refname)%(end)|%(refname)" >actual &&
135 test_cmp expect actual
138 test_expect_success 'middle alignment' '
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
152 git for-each-ref --format="|%(align:middle,30)refname is %(refname)%(end)|%(refname)" >actual &&
153 test_cmp expect actual
156 test_expect_success 'right 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
170 git for-each-ref --format="|%(align:30,right)refname is %(refname)%(end)|%(refname)" >actual &&
171 test_cmp expect actual
175 | refname is refs/heads/main |refs/heads/main
176 | refname is refs/heads/side |refs/heads/side
177 | refname is refs/odd/spot |refs/odd/spot
178 | refname is refs/tags/annotated-tag |refs/tags/annotated-tag
179 |refname is refs/tags/doubly-annotated-tag |refs/tags/doubly-annotated-tag
180 | refname is refs/tags/doubly-signed-tag |refs/tags/doubly-signed-tag
181 | refname is refs/tags/four |refs/tags/four
182 | refname is refs/tags/one |refs/tags/one
183 | refname is refs/tags/signed-tag |refs/tags/signed-tag
184 | refname is refs/tags/three |refs/tags/three
185 | refname is refs/tags/two |refs/tags/two
188 test_align_permutations() {
191 test_expect_success "align:$option" '
192 git for-each-ref --format="|%(align:$option)refname is %(refname)%(end)|%(refname)" >actual &&
193 test_cmp expect actual
198 test_align_permutations <<-\EOF
205 position=middle,width=42
206 width=42,position=middle
209 # Last one wins (silently) when multiple arguments of the same type are given
211 test_align_permutations <<-\EOF
214 width=42,position=right,middle
215 42,right,position=middle
218 # Individual atoms inside %(align:...) and %(end) must not be quoted.
220 test_expect_success 'alignment with format quote' "
221 cat >expect <<-\EOF &&
222 |' '\''main| A U Thor'\'' '|
223 |' '\''side| A U Thor'\'' '|
224 |' '\''odd/spot| A U Thor'\'' '|
225 |' '\''annotated-tag| '\'' '|
226 |' '\''doubly-annotated-tag| '\'' '|
227 |' '\''doubly-signed-tag| '\'' '|
228 |' '\''four| A U Thor'\'' '|
229 |' '\''one| A U Thor'\'' '|
230 |' '\''signed-tag| '\'' '|
231 |' '\''three| A U Thor'\'' '|
232 |' '\''two| A U Thor'\'' '|
234 git for-each-ref --shell --format=\"|%(align:30,middle)'%(refname:short)| %(authorname)'%(end)|\" >actual &&
235 test_cmp expect actual
238 test_expect_success 'nested alignment with quote formatting' "
239 cat >expect <<-\EOF &&
244 |'doubly-annotated-tag '|
245 |'doubly-signed-tag '|
252 git for-each-ref --shell --format='|%(align:30,left)%(align:15,right)%(refname:short)%(end)%(end)|' >actual &&
253 test_cmp expect actual
256 test_expect_success 'check `%(contents:lines=1)`' '
257 cat >expect <<-\EOF &&
261 annotated-tag |An annotated tag
262 doubly-annotated-tag |Annonated doubly
263 doubly-signed-tag |Signed doubly
266 signed-tag |A signed tag
270 git for-each-ref --format="%(refname:short) |%(contents:lines=1)" >actual &&
271 test_cmp expect actual
274 test_expect_success 'check `%(contents:lines=0)`' '
275 cat >expect <<-\EOF &&
280 doubly-annotated-tag |
288 git for-each-ref --format="%(refname:short) |%(contents:lines=0)" >actual &&
289 test_cmp expect actual
292 test_expect_success 'check `%(contents:lines=99999)`' '
293 cat >expect <<-\EOF &&
297 annotated-tag |An annotated tag
298 doubly-annotated-tag |Annonated doubly
299 doubly-signed-tag |Signed doubly
302 signed-tag |A signed tag
306 git for-each-ref --format="%(refname:short) |%(contents:lines=99999)" >actual &&
307 test_cmp expect actual
310 test_expect_success '`%(contents:lines=-1)` should fail' '
311 test_must_fail git for-each-ref --format="%(refname:short) |%(contents:lines=-1)"
314 test_expect_success 'setup for version sort' '
315 test_commit foo1.3 &&
316 test_commit foo1.6 &&
320 test_expect_success 'version sort' '
321 git for-each-ref --sort=version:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
322 cat >expect <<-\EOF &&
327 test_cmp expect actual
330 test_expect_success 'version sort (shortened)' '
331 git for-each-ref --sort=v:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
332 cat >expect <<-\EOF &&
337 test_cmp expect actual
340 test_expect_success 'reverse version sort' '
341 git for-each-ref --sort=-version:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
342 cat >expect <<-\EOF &&
347 test_cmp expect actual
350 test_expect_success 'improper usage of %(if), %(then), %(else) and %(end) atoms' '
351 test_must_fail git for-each-ref --format="%(if)" &&
352 test_must_fail git for-each-ref --format="%(then) %(end)" &&
353 test_must_fail git for-each-ref --format="%(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) %(then) %(end)" &&
356 test_must_fail git for-each-ref --format="%(then) %(else) %(end)" &&
357 test_must_fail git for-each-ref --format="%(if) %(else) %(end)" &&
358 test_must_fail git for-each-ref --format="%(if) %(then) %(else)" &&
359 test_must_fail git for-each-ref --format="%(if) %(else) %(then) %(end)" &&
360 test_must_fail git for-each-ref --format="%(if) %(then) %(else) %(else) %(end)" &&
361 test_must_fail git for-each-ref --format="%(if) %(end)"
364 test_expect_success 'check %(if)...%(then)...%(end) atoms' '
365 git for-each-ref --format="%(refname)%(if)%(authorname)%(then) Author: %(authorname)%(end)" >actual &&
366 cat >expect <<-\EOF &&
367 refs/heads/main Author: A U Thor
368 refs/heads/side Author: A U Thor
369 refs/odd/spot Author: A U Thor
370 refs/tags/annotated-tag
371 refs/tags/doubly-annotated-tag
372 refs/tags/doubly-signed-tag
373 refs/tags/foo1.10 Author: A U Thor
374 refs/tags/foo1.3 Author: A U Thor
375 refs/tags/foo1.6 Author: A U Thor
376 refs/tags/four Author: A U Thor
377 refs/tags/one Author: A U Thor
379 refs/tags/three Author: A U Thor
380 refs/tags/two Author: A U Thor
382 test_cmp expect actual
385 test_expect_success 'check %(if)...%(then)...%(else)...%(end) atoms' '
386 git for-each-ref --format="%(if)%(authorname)%(then)%(authorname)%(else)No author%(end): %(refname)" >actual &&
387 cat >expect <<-\EOF &&
388 A U Thor: refs/heads/main
389 A U Thor: refs/heads/side
390 A U Thor: refs/odd/spot
391 No author: refs/tags/annotated-tag
392 No author: refs/tags/doubly-annotated-tag
393 No author: refs/tags/doubly-signed-tag
394 A U Thor: refs/tags/foo1.10
395 A U Thor: refs/tags/foo1.3
396 A U Thor: refs/tags/foo1.6
397 A U Thor: refs/tags/four
398 A U Thor: refs/tags/one
399 No author: refs/tags/signed-tag
400 A U Thor: refs/tags/three
401 A U Thor: refs/tags/two
403 test_cmp expect actual
405 test_expect_success 'ignore spaces in %(if) atom usage' '
406 git for-each-ref --format="%(refname:short): %(if)%(HEAD)%(then)Head ref%(else)Not Head ref%(end)" >actual &&
407 cat >expect <<-\EOF &&
410 odd/spot: Not Head ref
411 annotated-tag: Not Head ref
412 doubly-annotated-tag: Not Head ref
413 doubly-signed-tag: Not Head ref
414 foo1.10: Not Head ref
419 signed-tag: Not Head ref
423 test_cmp expect actual
426 test_expect_success 'check %(if:equals=<string>)' '
427 git for-each-ref --format="%(if:equals=main)%(refname:short)%(then)Found main%(else)Not main%(end)" refs/heads/ >actual &&
428 cat >expect <<-\EOF &&
432 test_cmp expect actual
435 test_expect_success 'check %(if:notequals=<string>)' '
436 git for-each-ref --format="%(if:notequals=main)%(refname:short)%(then)Not main%(else)Found main%(end)" refs/heads/ >actual &&
437 cat >expect <<-\EOF &&
441 test_cmp expect actual
444 test_expect_success '--merged is compatible with --no-merged' '
445 git for-each-ref --merged HEAD --no-merged HEAD
448 test_expect_success 'validate worktree atom' '
449 cat >expect <<-EOF &&
451 main_worktree: $(pwd)/worktree_dir
452 side: not checked out
454 git worktree add -b main_worktree worktree_dir main &&
455 git for-each-ref --format="%(refname:short): %(if)%(worktreepath)%(then)%(worktreepath)%(else)not checked out%(end)" refs/heads/ >actual &&
456 rm -r worktree_dir &&
457 git worktree prune &&
458 test_cmp expect actual