Merge branch 'bw/grep-recurse-submodules' into next
[git] / t / t6302-for-each-ref-filter.sh
1 #!/bin/sh
2
3 test_description='test for-each-refs usage of ref-filter APIs'
4
5 . ./test-lib.sh
6 . "$TEST_DIRECTORY"/lib-gpg.sh
7
8 test_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
33 test_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
43 test_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
54 test_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
66 test_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
79 test_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
96 test_expect_success '%(color) must fail' '
97         test_must_fail git for-each-ref --format="%(color)%(refname)"
98 '
99
100 test_expect_success 'left alignment is default' '
101         cat >expect <<-\EOF &&
102         refname is refs/heads/master  |refs/heads/master
103         refname is refs/heads/side    |refs/heads/side
104         refname is refs/odd/spot      |refs/odd/spot
105         refname is refs/tags/annotated-tag|refs/tags/annotated-tag
106         refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
107         refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
108         refname is refs/tags/four     |refs/tags/four
109         refname is refs/tags/one      |refs/tags/one
110         refname is refs/tags/signed-tag|refs/tags/signed-tag
111         refname is refs/tags/three    |refs/tags/three
112         refname is refs/tags/two      |refs/tags/two
113         EOF
114         git for-each-ref --format="%(align:30)refname is %(refname)%(end)|%(refname)" >actual &&
115         test_cmp expect actual
116 '
117
118 test_expect_success 'middle alignment' '
119         cat >expect <<-\EOF &&
120         | refname is refs/heads/master |refs/heads/master
121         |  refname is refs/heads/side  |refs/heads/side
122         |   refname is refs/odd/spot   |refs/odd/spot
123         |refname is refs/tags/annotated-tag|refs/tags/annotated-tag
124         |refname is refs/tags/doubly-annotated-tag|refs/tags/doubly-annotated-tag
125         |refname is refs/tags/doubly-signed-tag|refs/tags/doubly-signed-tag
126         |  refname is refs/tags/four   |refs/tags/four
127         |   refname is refs/tags/one   |refs/tags/one
128         |refname is refs/tags/signed-tag|refs/tags/signed-tag
129         |  refname is refs/tags/three  |refs/tags/three
130         |   refname is refs/tags/two   |refs/tags/two
131         EOF
132         git for-each-ref --format="|%(align:middle,30)refname is %(refname)%(end)|%(refname)" >actual &&
133         test_cmp expect actual
134 '
135
136 test_expect_success 'right alignment' '
137         cat >expect <<-\EOF &&
138         |  refname is refs/heads/master|refs/heads/master
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
149         EOF
150         git for-each-ref --format="|%(align:30,right)refname is %(refname)%(end)|%(refname)" >actual &&
151         test_cmp expect actual
152 '
153
154 cat >expect <<-\EOF
155 |       refname is refs/heads/master       |refs/heads/master
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
166 EOF
167
168 test_align_permutations() {
169         while read -r option
170         do
171                 test_expect_success "align:$option" '
172                         git for-each-ref --format="|%(align:$option)refname is %(refname)%(end)|%(refname)" >actual &&
173                         test_cmp expect actual
174                 '
175         done
176 }
177
178 test_align_permutations <<-\EOF
179         middle,42
180         42,middle
181         position=middle,42
182         42,position=middle
183         middle,width=42
184         width=42,middle
185         position=middle,width=42
186         width=42,position=middle
187 EOF
188
189 # Last one wins (silently) when multiple arguments of the same type are given
190
191 test_align_permutations <<-\EOF
192         32,width=42,middle
193         width=30,42,middle
194         width=42,position=right,middle
195         42,right,position=middle
196 EOF
197
198 # Individual atoms inside %(align:...) and %(end) must not be quoted.
199
200 test_expect_success 'alignment with format quote' "
201         cat >expect <<-\EOF &&
202         |'      '\''master| A U Thor'\''      '|
203         |'       '\''side| A U Thor'\''       '|
204         |'     '\''odd/spot| A U Thor'\''     '|
205         |'      '\''annotated-tag| '\''       '|
206         |'   '\''doubly-annotated-tag| '\''   '|
207         |'    '\''doubly-signed-tag| '\''     '|
208         |'       '\''four| A U Thor'\''       '|
209         |'       '\''one| A U Thor'\''        '|
210         |'        '\''signed-tag| '\''        '|
211         |'      '\''three| A U Thor'\''       '|
212         |'       '\''two| A U Thor'\''        '|
213         EOF
214         git for-each-ref --shell --format=\"|%(align:30,middle)'%(refname:short)| %(authorname)'%(end)|\" >actual &&
215         test_cmp expect actual
216 "
217
218 test_expect_success 'nested alignment with quote formatting' "
219         cat >expect <<-\EOF &&
220         |'         master               '|
221         |'           side               '|
222         |'       odd/spot               '|
223         |'  annotated-tag               '|
224         |'doubly-annotated-tag          '|
225         |'doubly-signed-tag             '|
226         |'           four               '|
227         |'            one               '|
228         |'     signed-tag               '|
229         |'          three               '|
230         |'            two               '|
231         EOF
232         git for-each-ref --shell --format='|%(align:30,left)%(align:15,right)%(refname:short)%(end)%(end)|' >actual &&
233         test_cmp expect actual
234 "
235
236 test_expect_success 'check `%(contents:lines=1)`' '
237         cat >expect <<-\EOF &&
238         master |three
239         side |four
240         odd/spot |three
241         annotated-tag |An annotated tag
242         doubly-annotated-tag |Annonated doubly
243         doubly-signed-tag |Signed doubly
244         four |four
245         one |one
246         signed-tag |A signed tag
247         three |three
248         two |two
249         EOF
250         git for-each-ref --format="%(refname:short) |%(contents:lines=1)" >actual &&
251         test_cmp expect actual
252 '
253
254 test_expect_success 'check `%(contents:lines=0)`' '
255         cat >expect <<-\EOF &&
256         master |
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 |
267         EOF
268         git for-each-ref --format="%(refname:short) |%(contents:lines=0)" >actual &&
269         test_cmp expect actual
270 '
271
272 test_expect_success 'check `%(contents:lines=99999)`' '
273         cat >expect <<-\EOF &&
274         master |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
285         EOF
286         git for-each-ref --format="%(refname:short) |%(contents:lines=99999)" >actual &&
287         test_cmp expect actual
288 '
289
290 test_expect_success '`%(contents:lines=-1)` should fail' '
291         test_must_fail git for-each-ref --format="%(refname:short) |%(contents:lines=-1)"
292 '
293
294 test_expect_success 'setup for version sort' '
295         test_commit foo1.3 &&
296         test_commit foo1.6 &&
297         test_commit foo1.10
298 '
299
300 test_expect_success 'version sort' '
301         git for-each-ref --sort=version:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
302         cat >expect <<-\EOF &&
303         foo1.3
304         foo1.6
305         foo1.10
306         EOF
307         test_cmp expect actual
308 '
309
310 test_expect_success 'version sort (shortened)' '
311         git for-each-ref --sort=v:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
312         cat >expect <<-\EOF &&
313         foo1.3
314         foo1.6
315         foo1.10
316         EOF
317         test_cmp expect actual
318 '
319
320 test_expect_success 'reverse version sort' '
321         git for-each-ref --sort=-version:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
322         cat >expect <<-\EOF &&
323         foo1.10
324         foo1.6
325         foo1.3
326         EOF
327         test_cmp expect actual
328 '
329
330 test_expect_success 'improper usage of %(if), %(then), %(else) and %(end) atoms' '
331         test_must_fail git for-each-ref --format="%(if)" &&
332         test_must_fail git for-each-ref --format="%(then) %(end)" &&
333         test_must_fail git for-each-ref --format="%(else) %(end)" &&
334         test_must_fail git for-each-ref --format="%(if) %(else) %(end)" &&
335         test_must_fail git for-each-ref --format="%(if) %(then) %(then) %(end)" &&
336         test_must_fail git for-each-ref --format="%(then) %(else) %(end)" &&
337         test_must_fail git for-each-ref --format="%(if) %(else) %(end)" &&
338         test_must_fail git for-each-ref --format="%(if) %(then) %(else)" &&
339         test_must_fail git for-each-ref --format="%(if) %(else) %(then) %(end)" &&
340         test_must_fail git for-each-ref --format="%(if) %(then) %(else) %(else) %(end)" &&
341         test_must_fail git for-each-ref --format="%(if) %(end)"
342 '
343
344 test_expect_success 'check %(if)...%(then)...%(end) atoms' '
345         git for-each-ref --format="%(refname)%(if)%(authorname)%(then) Author: %(authorname)%(end)" >actual &&
346         cat >expect <<-\EOF &&
347         refs/heads/master Author: A U Thor
348         refs/heads/side Author: A U Thor
349         refs/odd/spot Author: A U Thor
350         refs/tags/annotated-tag
351         refs/tags/doubly-annotated-tag
352         refs/tags/doubly-signed-tag
353         refs/tags/foo1.10 Author: A U Thor
354         refs/tags/foo1.3 Author: A U Thor
355         refs/tags/foo1.6 Author: A U Thor
356         refs/tags/four Author: A U Thor
357         refs/tags/one Author: A U Thor
358         refs/tags/signed-tag
359         refs/tags/three Author: A U Thor
360         refs/tags/two Author: A U Thor
361         EOF
362         test_cmp expect actual
363 '
364
365 test_expect_success 'check %(if)...%(then)...%(else)...%(end) atoms' '
366         git for-each-ref --format="%(if)%(authorname)%(then)%(authorname)%(else)No author%(end): %(refname)" >actual &&
367         cat >expect <<-\EOF &&
368         A U Thor: refs/heads/master
369         A U Thor: refs/heads/side
370         A U Thor: refs/odd/spot
371         No author: refs/tags/annotated-tag
372         No author: refs/tags/doubly-annotated-tag
373         No author: refs/tags/doubly-signed-tag
374         A U Thor: refs/tags/foo1.10
375         A U Thor: refs/tags/foo1.3
376         A U Thor: refs/tags/foo1.6
377         A U Thor: refs/tags/four
378         A U Thor: refs/tags/one
379         No author: refs/tags/signed-tag
380         A U Thor: refs/tags/three
381         A U Thor: refs/tags/two
382         EOF
383         test_cmp expect actual
384 '
385 test_expect_success 'ignore spaces in %(if) atom usage' '
386         git for-each-ref --format="%(refname:short): %(if)%(HEAD)%(then)Head ref%(else)Not Head ref%(end)" >actual &&
387         cat >expect <<-\EOF &&
388         master: Head ref
389         side: Not Head ref
390         odd/spot: Not Head ref
391         annotated-tag: Not Head ref
392         doubly-annotated-tag: Not Head ref
393         doubly-signed-tag: Not Head ref
394         foo1.10: Not Head ref
395         foo1.3: Not Head ref
396         foo1.6: Not Head ref
397         four: Not Head ref
398         one: Not Head ref
399         signed-tag: Not Head ref
400         three: Not Head ref
401         two: Not Head ref
402         EOF
403         test_cmp expect actual
404 '
405
406 test_expect_success 'check %(if:equals=<string>)' '
407         git for-each-ref --format="%(if:equals=master)%(refname:short)%(then)Found master%(else)Not master%(end)" refs/heads/ >actual &&
408         cat >expect <<-\EOF &&
409         Found master
410         Not master
411         EOF
412         test_cmp expect actual
413 '
414
415 test_expect_success 'check %(if:notequals=<string>)' '
416         git for-each-ref --format="%(if:notequals=master)%(refname:short)%(then)Not master%(else)Found master%(end)" refs/heads/ >actual &&
417         cat >expect <<-\EOF &&
418         Found master
419         Not master
420         EOF
421         test_cmp expect actual
422 '
423
424 test_done