3 test_description='test for-each-refs usage of ref-filter APIs'
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
9 . "$TEST_DIRECTORY"/lib-gpg.sh
11 test_expect_success 'setup some history and refs' '
15 git checkout -b side &&
17 git tag -m "An annotated tag" annotated-tag &&
18 git tag -m "Annonated doubly" doubly-annotated-tag annotated-tag &&
20 # Note that these "signed" tags might not actually be signed.
21 # Tests which care about the distinction should be marked
22 # with the GPG prereq.
23 if test_have_prereq GPG
29 git tag $sign -m "A signed tag" signed-tag &&
30 git tag $sign -m "Signed doubly" doubly-signed-tag signed-tag &&
32 git checkout master &&
33 git update-ref refs/odd/spot master
36 test_expect_success 'filtering with --points-at' '
37 cat >expect <<-\EOF &&
42 git for-each-ref --format="%(refname)" --points-at=master >actual &&
43 test_cmp expect actual
46 test_expect_success 'check signed tags with --points-at' '
47 sed -e "s/Z$//" >expect <<-\EOF &&
49 refs/tags/annotated-tag four
51 refs/tags/signed-tag four
53 git for-each-ref --format="%(refname) %(*subject)" --points-at=side >actual &&
54 test_cmp expect actual
57 test_expect_success 'filtering with --merged' '
58 cat >expect <<-\EOF &&
65 git for-each-ref --format="%(refname)" --merged=master >actual &&
66 test_cmp expect actual
69 test_expect_success 'filtering with --no-merged' '
70 cat >expect <<-\EOF &&
72 refs/tags/annotated-tag
73 refs/tags/doubly-annotated-tag
74 refs/tags/doubly-signed-tag
78 git for-each-ref --format="%(refname)" --no-merged=master >actual &&
79 test_cmp expect actual
82 test_expect_success 'filtering with --contains' '
83 cat >expect <<-\EOF &&
87 refs/tags/annotated-tag
88 refs/tags/doubly-annotated-tag
89 refs/tags/doubly-signed-tag
95 git for-each-ref --format="%(refname)" --contains=two >actual &&
96 test_cmp expect actual
99 test_expect_success 'filtering with --no-contains' '
100 cat >expect <<-\EOF &&
103 git for-each-ref --format="%(refname)" --no-contains=two >actual &&
104 test_cmp expect actual
107 test_expect_success 'filtering with --contains and --no-contains' '
108 cat >expect <<-\EOF &&
111 git for-each-ref --format="%(refname)" --contains=two --no-contains=three >actual &&
112 test_cmp expect actual
115 test_expect_success '%(color) must fail' '
116 test_must_fail git for-each-ref --format="%(color)%(refname)"
119 test_expect_success PREPARE_FOR_MAIN_BRANCH 'left alignment is default' '
120 cat >expect <<-\EOF &&
121 refname is refs/heads/main |refs/heads/main
122 refname is refs/heads/side |refs/heads/side
123 refname is refs/odd/spot |refs/odd/spot
124 refname is refs/tags/annotated-tag|refs/tags/annotated-tag
125 refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
126 refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
127 refname is refs/tags/four |refs/tags/four
128 refname is refs/tags/one |refs/tags/one
129 refname is refs/tags/signed-tag|refs/tags/signed-tag
130 refname is refs/tags/three |refs/tags/three
131 refname is refs/tags/two |refs/tags/two
133 git for-each-ref --format="%(align:30)refname is %(refname)%(end)|%(refname)" >actual &&
134 test_cmp expect actual
137 test_expect_success PREPARE_FOR_MAIN_BRANCH 'middle alignment' '
138 cat >expect <<-\EOF &&
139 | refname is refs/heads/main |refs/heads/main
140 | refname is refs/heads/side |refs/heads/side
141 | refname is refs/odd/spot |refs/odd/spot
142 |refname is refs/tags/annotated-tag|refs/tags/annotated-tag
143 |refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
144 |refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
145 | refname is refs/tags/four |refs/tags/four
146 | refname is refs/tags/one |refs/tags/one
147 |refname is refs/tags/signed-tag|refs/tags/signed-tag
148 | refname is refs/tags/three |refs/tags/three
149 | refname is refs/tags/two |refs/tags/two
151 git for-each-ref --format="|%(align:middle,30)refname is %(refname)%(end)|%(refname)" >actual &&
152 test_cmp expect actual
155 test_expect_success PREPARE_FOR_MAIN_BRANCH 'right alignment' '
156 cat >expect <<-\EOF &&
157 | refname is refs/heads/main|refs/heads/main
158 | refname is refs/heads/side|refs/heads/side
159 | refname is refs/odd/spot|refs/odd/spot
160 |refname is refs/tags/annotated-tag|refs/tags/annotated-tag
161 |refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
162 |refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
163 | refname is refs/tags/four|refs/tags/four
164 | refname is refs/tags/one|refs/tags/one
165 |refname is refs/tags/signed-tag|refs/tags/signed-tag
166 | refname is refs/tags/three|refs/tags/three
167 | refname is refs/tags/two|refs/tags/two
169 git for-each-ref --format="|%(align:30,right)refname is %(refname)%(end)|%(refname)" >actual &&
170 test_cmp expect actual
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
187 test_align_permutations() {
190 test_expect_success PREPARE_FOR_MAIN_BRANCH "align:$option" '
191 git for-each-ref --format="|%(align:$option)refname is %(refname)%(end)|%(refname)" >actual &&
192 test_cmp expect actual
197 test_align_permutations <<-\EOF
204 position=middle,width=42
205 width=42,position=middle
208 # Last one wins (silently) when multiple arguments of the same type are given
210 test_align_permutations <<-\EOF
213 width=42,position=right,middle
214 42,right,position=middle
217 # Individual atoms inside %(align:...) and %(end) must not be quoted.
219 test_expect_success PREPARE_FOR_MAIN_BRANCH 'alignment with format quote' "
220 cat >expect <<-\EOF &&
221 |' '\''main| A U Thor'\'' '|
222 |' '\''side| A U Thor'\'' '|
223 |' '\''odd/spot| A U Thor'\'' '|
224 |' '\''annotated-tag| '\'' '|
225 |' '\''doubly-annotated-tag| '\'' '|
226 |' '\''doubly-signed-tag| '\'' '|
227 |' '\''four| A U Thor'\'' '|
228 |' '\''one| A U Thor'\'' '|
229 |' '\''signed-tag| '\'' '|
230 |' '\''three| A U Thor'\'' '|
231 |' '\''two| A U Thor'\'' '|
233 git for-each-ref --shell --format=\"|%(align:30,middle)'%(refname:short)| %(authorname)'%(end)|\" >actual &&
234 test_cmp expect actual
237 test_expect_success PREPARE_FOR_MAIN_BRANCH 'nested alignment with quote formatting' "
238 cat >expect <<-\EOF &&
243 |'doubly-annotated-tag '|
244 |'doubly-signed-tag '|
251 git for-each-ref --shell --format='|%(align:30,left)%(align:15,right)%(refname:short)%(end)%(end)|' >actual &&
252 test_cmp expect actual
255 test_expect_success 'check `%(contents:lines=1)`' '
256 cat >expect <<-\EOF &&
260 annotated-tag |An annotated tag
261 doubly-annotated-tag |Annonated doubly
262 doubly-signed-tag |Signed doubly
265 signed-tag |A signed tag
269 git for-each-ref --format="%(refname:short) |%(contents:lines=1)" >actual &&
270 test_cmp expect actual
273 test_expect_success 'check `%(contents:lines=0)`' '
274 cat >expect <<-\EOF &&
279 doubly-annotated-tag |
287 git for-each-ref --format="%(refname:short) |%(contents:lines=0)" >actual &&
288 test_cmp expect actual
291 test_expect_success 'check `%(contents:lines=99999)`' '
292 cat >expect <<-\EOF &&
296 annotated-tag |An annotated tag
297 doubly-annotated-tag |Annonated doubly
298 doubly-signed-tag |Signed doubly
301 signed-tag |A signed tag
305 git for-each-ref --format="%(refname:short) |%(contents:lines=99999)" >actual &&
306 test_cmp expect actual
309 test_expect_success '`%(contents:lines=-1)` should fail' '
310 test_must_fail git for-each-ref --format="%(refname:short) |%(contents:lines=-1)"
313 test_expect_success 'setup for version sort' '
314 test_commit foo1.3 &&
315 test_commit foo1.6 &&
319 test_expect_success 'version sort' '
320 git for-each-ref --sort=version:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
321 cat >expect <<-\EOF &&
326 test_cmp expect actual
329 test_expect_success 'version sort (shortened)' '
330 git for-each-ref --sort=v:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
331 cat >expect <<-\EOF &&
336 test_cmp expect actual
339 test_expect_success 'reverse version sort' '
340 git for-each-ref --sort=-version:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
341 cat >expect <<-\EOF &&
346 test_cmp expect actual
349 test_expect_success 'improper usage of %(if), %(then), %(else) and %(end) atoms' '
350 test_must_fail git for-each-ref --format="%(if)" &&
351 test_must_fail git for-each-ref --format="%(then) %(end)" &&
352 test_must_fail git for-each-ref --format="%(else) %(end)" &&
353 test_must_fail git for-each-ref --format="%(if) %(else) %(end)" &&
354 test_must_fail git for-each-ref --format="%(if) %(then) %(then) %(end)" &&
355 test_must_fail git for-each-ref --format="%(then) %(else) %(end)" &&
356 test_must_fail git for-each-ref --format="%(if) %(else) %(end)" &&
357 test_must_fail git for-each-ref --format="%(if) %(then) %(else)" &&
358 test_must_fail git for-each-ref --format="%(if) %(else) %(then) %(end)" &&
359 test_must_fail git for-each-ref --format="%(if) %(then) %(else) %(else) %(end)" &&
360 test_must_fail git for-each-ref --format="%(if) %(end)"
363 test_expect_success 'check %(if)...%(then)...%(end) atoms' '
364 git for-each-ref --format="%(refname)%(if)%(authorname)%(then) Author: %(authorname)%(end)" >actual &&
365 cat >expect <<-\EOF &&
366 refs/heads/master Author: A U Thor
367 refs/heads/side Author: A U Thor
368 refs/odd/spot Author: A U Thor
369 refs/tags/annotated-tag
370 refs/tags/doubly-annotated-tag
371 refs/tags/doubly-signed-tag
372 refs/tags/foo1.10 Author: A U Thor
373 refs/tags/foo1.3 Author: A U Thor
374 refs/tags/foo1.6 Author: A U Thor
375 refs/tags/four Author: A U Thor
376 refs/tags/one Author: A U Thor
378 refs/tags/three Author: A U Thor
379 refs/tags/two Author: A U Thor
381 test_cmp expect actual
384 test_expect_success 'check %(if)...%(then)...%(else)...%(end) atoms' '
385 git for-each-ref --format="%(if)%(authorname)%(then)%(authorname)%(else)No author%(end): %(refname)" >actual &&
386 cat >expect <<-\EOF &&
387 A U Thor: refs/heads/master
388 A U Thor: refs/heads/side
389 A U Thor: refs/odd/spot
390 No author: refs/tags/annotated-tag
391 No author: refs/tags/doubly-annotated-tag
392 No author: refs/tags/doubly-signed-tag
393 A U Thor: refs/tags/foo1.10
394 A U Thor: refs/tags/foo1.3
395 A U Thor: refs/tags/foo1.6
396 A U Thor: refs/tags/four
397 A U Thor: refs/tags/one
398 No author: refs/tags/signed-tag
399 A U Thor: refs/tags/three
400 A U Thor: refs/tags/two
402 test_cmp expect actual
404 test_expect_success 'ignore spaces in %(if) atom usage' '
405 git for-each-ref --format="%(refname:short): %(if)%(HEAD)%(then)Head ref%(else)Not Head ref%(end)" >actual &&
406 cat >expect <<-\EOF &&
409 odd/spot: Not Head ref
410 annotated-tag: Not Head ref
411 doubly-annotated-tag: Not Head ref
412 doubly-signed-tag: Not Head ref
413 foo1.10: Not Head ref
418 signed-tag: Not Head ref
422 test_cmp expect actual
425 test_expect_success 'check %(if:equals=<string>)' '
426 git for-each-ref --format="%(if:equals=master)%(refname:short)%(then)Found master%(else)Not master%(end)" refs/heads/ >actual &&
427 cat >expect <<-\EOF &&
431 test_cmp expect actual
434 test_expect_success 'check %(if:notequals=<string>)' '
435 git for-each-ref --format="%(if:notequals=master)%(refname:short)%(then)Not master%(else)Found master%(end)" refs/heads/ >actual &&
436 cat >expect <<-\EOF &&
440 test_cmp expect actual
443 test_expect_success '--merged is compatible with --no-merged' '
444 git for-each-ref --merged HEAD --no-merged HEAD
447 test_expect_success 'validate worktree atom' '
448 cat >expect <<-EOF &&
450 master_worktree: $(pwd)/worktree_dir
451 side: not checked out
453 git worktree add -b master_worktree worktree_dir master &&
454 git for-each-ref --format="%(refname:short): %(if)%(worktreepath)%(then)%(worktreepath)%(else)not checked out%(end)" refs/heads/ >actual &&
455 rm -r worktree_dir &&
456 git worktree prune &&
457 test_cmp expect actual