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