sparse-index: loose integration with cache_tree_verify()
[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 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7
8 . ./test-lib.sh
9 . "$TEST_DIRECTORY"/lib-gpg.sh
10
11 test_expect_success 'setup some history and refs' '
12         test_commit one &&
13         git branch -M main &&
14         test_commit two &&
15         test_commit three &&
16         git checkout -b side &&
17         test_commit four &&
18         git tag -m "An annotated tag" annotated-tag &&
19         git tag -m "Annonated doubly" doubly-annotated-tag annotated-tag &&
20
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
25         then
26                 sign=-s
27         else
28                 sign=
29         fi &&
30         git tag $sign -m "A signed tag" signed-tag &&
31         git tag $sign -m "Signed doubly" doubly-signed-tag signed-tag &&
32
33         git checkout main &&
34         git update-ref refs/odd/spot main
35 '
36
37 test_expect_success 'filtering with --points-at' '
38         cat >expect <<-\EOF &&
39         refs/heads/main
40         refs/odd/spot
41         refs/tags/three
42         EOF
43         git for-each-ref --format="%(refname)" --points-at=main >actual &&
44         test_cmp expect actual
45 '
46
47 test_expect_success 'check signed tags with --points-at' '
48         sed -e "s/Z$//" >expect <<-\EOF &&
49         refs/heads/side Z
50         refs/tags/annotated-tag four
51         refs/tags/four Z
52         refs/tags/signed-tag four
53         EOF
54         git for-each-ref --format="%(refname) %(*subject)" --points-at=side >actual &&
55         test_cmp expect actual
56 '
57
58 test_expect_success 'filtering with --merged' '
59         cat >expect <<-\EOF &&
60         refs/heads/main
61         refs/odd/spot
62         refs/tags/one
63         refs/tags/three
64         refs/tags/two
65         EOF
66         git for-each-ref --format="%(refname)" --merged=main >actual &&
67         test_cmp expect actual
68 '
69
70 test_expect_success 'filtering with --no-merged' '
71         cat >expect <<-\EOF &&
72         refs/heads/side
73         refs/tags/annotated-tag
74         refs/tags/doubly-annotated-tag
75         refs/tags/doubly-signed-tag
76         refs/tags/four
77         refs/tags/signed-tag
78         EOF
79         git for-each-ref --format="%(refname)" --no-merged=main >actual &&
80         test_cmp expect actual
81 '
82
83 test_expect_success 'filtering with --contains' '
84         cat >expect <<-\EOF &&
85         refs/heads/main
86         refs/heads/side
87         refs/odd/spot
88         refs/tags/annotated-tag
89         refs/tags/doubly-annotated-tag
90         refs/tags/doubly-signed-tag
91         refs/tags/four
92         refs/tags/signed-tag
93         refs/tags/three
94         refs/tags/two
95         EOF
96         git for-each-ref --format="%(refname)" --contains=two >actual &&
97         test_cmp expect actual
98 '
99
100 test_expect_success 'filtering with --no-contains' '
101         cat >expect <<-\EOF &&
102         refs/tags/one
103         EOF
104         git for-each-ref --format="%(refname)" --no-contains=two >actual &&
105         test_cmp expect actual
106 '
107
108 test_expect_success 'filtering with --contains and --no-contains' '
109         cat >expect <<-\EOF &&
110         refs/tags/two
111         EOF
112         git for-each-ref --format="%(refname)" --contains=two --no-contains=three >actual &&
113         test_cmp expect actual
114 '
115
116 test_expect_success '%(color) must fail' '
117         test_must_fail git for-each-ref --format="%(color)%(refname)"
118 '
119
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
133         EOF
134         git for-each-ref --format="%(align:30)refname is %(refname)%(end)|%(refname)" >actual &&
135         test_cmp expect actual
136 '
137
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
151         EOF
152         git for-each-ref --format="|%(align:middle,30)refname is %(refname)%(end)|%(refname)" >actual &&
153         test_cmp expect actual
154 '
155
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
169         EOF
170         git for-each-ref --format="|%(align:30,right)refname is %(refname)%(end)|%(refname)" >actual &&
171         test_cmp expect actual
172 '
173
174 cat >expect <<-\EOF
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
186 EOF
187
188 test_align_permutations() {
189         while read -r option
190         do
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
194                 '
195         done
196 }
197
198 test_align_permutations <<-\EOF
199         middle,42
200         42,middle
201         position=middle,42
202         42,position=middle
203         middle,width=42
204         width=42,middle
205         position=middle,width=42
206         width=42,position=middle
207 EOF
208
209 # Last one wins (silently) when multiple arguments of the same type are given
210
211 test_align_permutations <<-\EOF
212         32,width=42,middle
213         width=30,42,middle
214         width=42,position=right,middle
215         42,right,position=middle
216 EOF
217
218 # Individual atoms inside %(align:...) and %(end) must not be quoted.
219
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'\''        '|
233         EOF
234         git for-each-ref --shell --format=\"|%(align:30,middle)'%(refname:short)| %(authorname)'%(end)|\" >actual &&
235         test_cmp expect actual
236 "
237
238 test_expect_success 'nested alignment with quote formatting' "
239         cat >expect <<-\EOF &&
240         |'           main               '|
241         |'           side               '|
242         |'       odd/spot               '|
243         |'  annotated-tag               '|
244         |'doubly-annotated-tag          '|
245         |'doubly-signed-tag             '|
246         |'           four               '|
247         |'            one               '|
248         |'     signed-tag               '|
249         |'          three               '|
250         |'            two               '|
251         EOF
252         git for-each-ref --shell --format='|%(align:30,left)%(align:15,right)%(refname:short)%(end)%(end)|' >actual &&
253         test_cmp expect actual
254 "
255
256 test_expect_success 'check `%(contents:lines=1)`' '
257         cat >expect <<-\EOF &&
258         main |three
259         side |four
260         odd/spot |three
261         annotated-tag |An annotated tag
262         doubly-annotated-tag |Annonated doubly
263         doubly-signed-tag |Signed doubly
264         four |four
265         one |one
266         signed-tag |A signed tag
267         three |three
268         two |two
269         EOF
270         git for-each-ref --format="%(refname:short) |%(contents:lines=1)" >actual &&
271         test_cmp expect actual
272 '
273
274 test_expect_success 'check `%(contents:lines=0)`' '
275         cat >expect <<-\EOF &&
276         main |
277         side |
278         odd/spot |
279         annotated-tag |
280         doubly-annotated-tag |
281         doubly-signed-tag |
282         four |
283         one |
284         signed-tag |
285         three |
286         two |
287         EOF
288         git for-each-ref --format="%(refname:short) |%(contents:lines=0)" >actual &&
289         test_cmp expect actual
290 '
291
292 test_expect_success 'check `%(contents:lines=99999)`' '
293         cat >expect <<-\EOF &&
294         main |three
295         side |four
296         odd/spot |three
297         annotated-tag |An annotated tag
298         doubly-annotated-tag |Annonated doubly
299         doubly-signed-tag |Signed doubly
300         four |four
301         one |one
302         signed-tag |A signed tag
303         three |three
304         two |two
305         EOF
306         git for-each-ref --format="%(refname:short) |%(contents:lines=99999)" >actual &&
307         test_cmp expect actual
308 '
309
310 test_expect_success '`%(contents:lines=-1)` should fail' '
311         test_must_fail git for-each-ref --format="%(refname:short) |%(contents:lines=-1)"
312 '
313
314 test_expect_success 'setup for version sort' '
315         test_commit foo1.3 &&
316         test_commit foo1.6 &&
317         test_commit foo1.10
318 '
319
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 &&
323         foo1.3
324         foo1.6
325         foo1.10
326         EOF
327         test_cmp expect actual
328 '
329
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 &&
333         foo1.3
334         foo1.6
335         foo1.10
336         EOF
337         test_cmp expect actual
338 '
339
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 &&
343         foo1.10
344         foo1.6
345         foo1.3
346         EOF
347         test_cmp expect actual
348 '
349
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)"
362 '
363
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
378         refs/tags/signed-tag
379         refs/tags/three Author: A U Thor
380         refs/tags/two Author: A U Thor
381         EOF
382         test_cmp expect actual
383 '
384
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
402         EOF
403         test_cmp expect actual
404 '
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 &&
408         main: Head ref
409         side: Not Head ref
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
415         foo1.3: Not Head ref
416         foo1.6: Not Head ref
417         four: Not Head ref
418         one: Not Head ref
419         signed-tag: Not Head ref
420         three: Not Head ref
421         two: Not Head ref
422         EOF
423         test_cmp expect actual
424 '
425
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 &&
429         Found main
430         Not main
431         EOF
432         test_cmp expect actual
433 '
434
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 &&
438         Found main
439         Not main
440         EOF
441         test_cmp expect actual
442 '
443
444 test_expect_success '--merged is compatible with --no-merged' '
445         git for-each-ref --merged HEAD --no-merged HEAD
446 '
447
448 test_expect_success 'validate worktree atom' '
449         cat >expect <<-EOF &&
450         main: $(pwd)
451         main_worktree: $(pwd)/worktree_dir
452         side: not checked out
453         EOF
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
459 '
460
461 test_done