describe: teach --match to handle branches and remotes
[git] / t / t7513-interpret-trailers.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2013, 2014 Christian Couder
4 #
5
6 test_description='git interpret-trailers'
7
8 . ./test-lib.sh
9
10 # When we want one trailing space at the end of each line, let's use sed
11 # to make sure that these spaces are not removed by any automatic tool.
12
13 test_expect_success 'setup' '
14         : >empty &&
15         cat >basic_message <<-\EOF &&
16                 subject
17
18                 body
19         EOF
20         cat >complex_message_body <<-\EOF &&
21                 my subject
22
23                 my body which is long
24                 and contains some special
25                 chars like : = ? !
26
27         EOF
28         sed -e "s/ Z\$/ /" >complex_message_trailers <<-\EOF &&
29                 Fixes: Z
30                 Acked-by: Z
31                 Reviewed-by: Z
32                 Signed-off-by: Z
33         EOF
34         cat >basic_patch <<-\EOF
35                 ---
36                  foo.txt | 2 +-
37                  1 file changed, 1 insertion(+), 1 deletion(-)
38
39                 diff --git a/foo.txt b/foo.txt
40                 index 0353767..1d91aa1 100644
41                 --- a/foo.txt
42                 +++ b/foo.txt
43                 @@ -1,3 +1,3 @@
44
45                 -bar
46                 +baz
47
48                 --
49                 1.9.rc0.11.ga562ddc
50
51         EOF
52 '
53
54 test_expect_success 'without config' '
55         sed -e "s/ Z\$/ /" >expected <<-\EOF &&
56
57                 ack: Peff
58                 Reviewed-by: Z
59                 Acked-by: Johan
60         EOF
61         git interpret-trailers --trailer "ack = Peff" --trailer "Reviewed-by" \
62                 --trailer "Acked-by: Johan" empty >actual &&
63         test_cmp expected actual
64 '
65
66 test_expect_success 'without config in another order' '
67         sed -e "s/ Z\$/ /" >expected <<-\EOF &&
68
69                 Acked-by: Johan
70                 Reviewed-by: Z
71                 ack: Peff
72         EOF
73         git interpret-trailers --trailer "Acked-by: Johan" --trailer "Reviewed-by" \
74                 --trailer "ack = Peff" empty >actual &&
75         test_cmp expected actual
76 '
77
78 test_expect_success '--trim-empty without config' '
79         cat >expected <<-\EOF &&
80
81                 ack: Peff
82                 Acked-by: Johan
83         EOF
84         git interpret-trailers --trim-empty --trailer ack=Peff \
85                 --trailer "Reviewed-by" --trailer "Acked-by: Johan" \
86                 --trailer "sob:" empty >actual &&
87         test_cmp expected actual
88 '
89
90 test_expect_success 'with config option on the command line' '
91         cat >expected <<-\EOF &&
92
93                 Acked-by: Johan
94                 Reviewed-by: Peff
95         EOF
96         { echo; echo "Acked-by: Johan"; } |
97         git -c "trailer.Acked-by.ifexists=addifdifferent" interpret-trailers \
98                 --trailer "Reviewed-by: Peff" --trailer "Acked-by: Johan" >actual &&
99         test_cmp expected actual
100 '
101
102 test_expect_success 'with only a title in the message' '
103         cat >expected <<-\EOF &&
104                 area: change
105
106                 Reviewed-by: Peff
107                 Acked-by: Johan
108         EOF
109         echo "area: change" |
110         git interpret-trailers --trailer "Reviewed-by: Peff" \
111                 --trailer "Acked-by: Johan" >actual &&
112         test_cmp expected actual
113 '
114
115 test_expect_success 'with multiline title in the message' '
116         cat >expected <<-\EOF &&
117                 place of
118                 code: change
119
120                 Reviewed-by: Peff
121                 Acked-by: Johan
122         EOF
123         printf "%s\n" "place of" "code: change" |
124         git interpret-trailers --trailer "Reviewed-by: Peff" \
125                 --trailer "Acked-by: Johan" >actual &&
126         test_cmp expected actual
127 '
128
129 test_expect_success 'with non-trailer lines mixed with Signed-off-by' '
130         cat >patch <<-\EOF &&
131
132                 this is not a trailer
133                 this is not a trailer
134                 Signed-off-by: a <a@example.com>
135                 this is not a trailer
136         EOF
137         cat >expected <<-\EOF &&
138
139                 this is not a trailer
140                 this is not a trailer
141                 Signed-off-by: a <a@example.com>
142                 this is not a trailer
143                 token: value
144         EOF
145         git interpret-trailers --trailer "token: value" patch >actual &&
146         test_cmp expected actual
147 '
148
149 test_expect_success 'with non-trailer lines mixed with cherry picked from' '
150         cat >patch <<-\EOF &&
151
152                 this is not a trailer
153                 this is not a trailer
154                 (cherry picked from commit x)
155                 this is not a trailer
156         EOF
157         cat >expected <<-\EOF &&
158
159                 this is not a trailer
160                 this is not a trailer
161                 (cherry picked from commit x)
162                 this is not a trailer
163                 token: value
164         EOF
165         git interpret-trailers --trailer "token: value" patch >actual &&
166         test_cmp expected actual
167 '
168
169 test_expect_success 'with non-trailer lines mixed with a configured trailer' '
170         cat >patch <<-\EOF &&
171
172                 this is not a trailer
173                 this is not a trailer
174                 My-trailer: x
175                 this is not a trailer
176         EOF
177         cat >expected <<-\EOF &&
178
179                 this is not a trailer
180                 this is not a trailer
181                 My-trailer: x
182                 this is not a trailer
183                 token: value
184         EOF
185         test_config trailer.my.key "My-trailer: " &&
186         git interpret-trailers --trailer "token: value" patch >actual &&
187         test_cmp expected actual
188 '
189
190 test_expect_success 'with non-trailer lines mixed with a non-configured trailer' '
191         cat >patch <<-\EOF &&
192
193                 this is not a trailer
194                 this is not a trailer
195                 I-am-not-configured: x
196                 this is not a trailer
197         EOF
198         cat >expected <<-\EOF &&
199
200                 this is not a trailer
201                 this is not a trailer
202                 I-am-not-configured: x
203                 this is not a trailer
204
205                 token: value
206         EOF
207         test_config trailer.my.key "My-trailer: " &&
208         git interpret-trailers --trailer "token: value" patch >actual &&
209         test_cmp expected actual
210 '
211
212 test_expect_success 'with all non-configured trailers' '
213         cat >patch <<-\EOF &&
214
215                 I-am-not-configured: x
216                 I-am-also-not-configured: x
217         EOF
218         cat >expected <<-\EOF &&
219
220                 I-am-not-configured: x
221                 I-am-also-not-configured: x
222                 token: value
223         EOF
224         test_config trailer.my.key "My-trailer: " &&
225         git interpret-trailers --trailer "token: value" patch >actual &&
226         test_cmp expected actual
227 '
228
229 test_expect_success 'with non-trailer lines only' '
230         cat >patch <<-\EOF &&
231
232                 this is not a trailer
233         EOF
234         cat >expected <<-\EOF &&
235
236                 this is not a trailer
237
238                 token: value
239         EOF
240         git interpret-trailers --trailer "token: value" patch >actual &&
241         test_cmp expected actual
242 '
243
244 test_expect_success 'line with leading whitespace is not trailer' '
245         q_to_tab >patch <<-\EOF &&
246
247                 Qtoken: value
248         EOF
249         q_to_tab >expected <<-\EOF &&
250
251                 Qtoken: value
252
253                 token: value
254         EOF
255         git interpret-trailers --trailer "token: value" patch >actual &&
256         test_cmp expected actual
257 '
258
259 test_expect_success 'multiline field treated as one trailer for 25% check' '
260         q_to_tab >patch <<-\EOF &&
261
262                 Signed-off-by: a <a@example.com>
263                 name: value on
264                 Qmultiple lines
265                 this is not a trailer
266                 this is not a trailer
267                 this is not a trailer
268                 this is not a trailer
269                 this is not a trailer
270                 this is not a trailer
271         EOF
272         q_to_tab >expected <<-\EOF &&
273
274                 Signed-off-by: a <a@example.com>
275                 name: value on
276                 Qmultiple lines
277                 this is not a trailer
278                 this is not a trailer
279                 this is not a trailer
280                 this is not a trailer
281                 this is not a trailer
282                 this is not a trailer
283                 name: value
284         EOF
285         git interpret-trailers --trailer "name: value" patch >actual &&
286         test_cmp expected actual
287 '
288
289 test_expect_success 'multiline field treated as atomic for placement' '
290         q_to_tab >patch <<-\EOF &&
291
292                 another: trailer
293                 name: value on
294                 Qmultiple lines
295                 another: trailer
296         EOF
297         q_to_tab >expected <<-\EOF &&
298
299                 another: trailer
300                 name: value on
301                 Qmultiple lines
302                 name: value
303                 another: trailer
304         EOF
305         test_config trailer.name.where after &&
306         git interpret-trailers --trailer "name: value" patch >actual &&
307         test_cmp expected actual
308 '
309
310 test_expect_success 'multiline field treated as atomic for replacement' '
311         q_to_tab >patch <<-\EOF &&
312
313                 another: trailer
314                 name: value on
315                 Qmultiple lines
316                 another: trailer
317         EOF
318         q_to_tab >expected <<-\EOF &&
319
320                 another: trailer
321                 another: trailer
322                 name: value
323         EOF
324         test_config trailer.name.ifexists replace &&
325         git interpret-trailers --trailer "name: value" patch >actual &&
326         test_cmp expected actual
327 '
328
329 test_expect_success 'multiline field treated as atomic for difference check' '
330         q_to_tab >patch <<-\EOF &&
331
332                 another: trailer
333                 name: first line
334                 Qsecond line
335                 another: trailer
336         EOF
337         test_config trailer.name.ifexists addIfDifferent &&
338
339         q_to_tab >trailer <<-\EOF &&
340                 name: first line
341                 Qsecond line
342         EOF
343         q_to_tab >expected <<-\EOF &&
344
345                 another: trailer
346                 name: first line
347                 Qsecond line
348                 another: trailer
349         EOF
350         git interpret-trailers --trailer "$(cat trailer)" patch >actual &&
351         test_cmp expected actual &&
352
353         q_to_tab >trailer <<-\EOF &&
354                 name: first line
355                 QQQQQsecond line
356         EOF
357         q_to_tab >expected <<-\EOF &&
358
359                 another: trailer
360                 name: first line
361                 Qsecond line
362                 another: trailer
363                 name: first line
364                 QQQQQsecond line
365         EOF
366         git interpret-trailers --trailer "$(cat trailer)" patch >actual &&
367         test_cmp expected actual &&
368
369         q_to_tab >trailer <<-\EOF &&
370                 name: first line *DIFFERENT*
371                 Qsecond line
372         EOF
373         q_to_tab >expected <<-\EOF &&
374
375                 another: trailer
376                 name: first line
377                 Qsecond line
378                 another: trailer
379                 name: first line *DIFFERENT*
380                 Qsecond line
381         EOF
382         git interpret-trailers --trailer "$(cat trailer)" patch >actual &&
383         test_cmp expected actual
384 '
385
386 test_expect_success 'multiline field treated as atomic for neighbor check' '
387         q_to_tab >patch <<-\EOF &&
388
389                 another: trailer
390                 name: first line
391                 Qsecond line
392                 another: trailer
393         EOF
394         test_config trailer.name.where after &&
395         test_config trailer.name.ifexists addIfDifferentNeighbor &&
396
397         q_to_tab >trailer <<-\EOF &&
398                 name: first line
399                 Qsecond line
400         EOF
401         q_to_tab >expected <<-\EOF &&
402
403                 another: trailer
404                 name: first line
405                 Qsecond line
406                 another: trailer
407         EOF
408         git interpret-trailers --trailer "$(cat trailer)" patch >actual &&
409         test_cmp expected actual &&
410
411         q_to_tab >trailer <<-\EOF &&
412                 name: first line
413                 QQQQQsecond line
414         EOF
415         q_to_tab >expected <<-\EOF &&
416
417                 another: trailer
418                 name: first line
419                 Qsecond line
420                 name: first line
421                 QQQQQsecond line
422                 another: trailer
423         EOF
424         git interpret-trailers --trailer "$(cat trailer)" patch >actual &&
425         test_cmp expected actual
426 '
427
428 test_expect_success 'with config setup' '
429         git config trailer.ack.key "Acked-by: " &&
430         cat >expected <<-\EOF &&
431
432                 Acked-by: Peff
433         EOF
434         git interpret-trailers --trim-empty --trailer "ack = Peff" empty >actual &&
435         test_cmp expected actual &&
436         git interpret-trailers --trim-empty --trailer "Acked-by = Peff" empty >actual &&
437         test_cmp expected actual &&
438         git interpret-trailers --trim-empty --trailer "Acked-by :Peff" empty >actual &&
439         test_cmp expected actual
440 '
441
442 test_expect_success 'with config setup and ":=" as separators' '
443         git config trailer.separators ":=" &&
444         git config trailer.ack.key "Acked-by= " &&
445         cat >expected <<-\EOF &&
446
447                 Acked-by= Peff
448         EOF
449         git interpret-trailers --trim-empty --trailer "ack = Peff" empty >actual &&
450         test_cmp expected actual &&
451         git interpret-trailers --trim-empty --trailer "Acked-by= Peff" empty >actual &&
452         test_cmp expected actual &&
453         git interpret-trailers --trim-empty --trailer "Acked-by : Peff" empty >actual &&
454         test_cmp expected actual
455 '
456
457 test_expect_success 'with config setup and "%" as separators' '
458         git config trailer.separators "%" &&
459         cat >expected <<-\EOF &&
460
461                 bug% 42
462                 count% 10
463                 bug% 422
464         EOF
465         git interpret-trailers --trim-empty --trailer "bug = 42" \
466                 --trailer count%10 --trailer "test: stuff" \
467                 --trailer "bug % 422" empty >actual &&
468         test_cmp expected actual
469 '
470
471 test_expect_success 'with "%" as separators and a message with trailers' '
472         cat >special_message <<-\EOF &&
473                 Special Message
474
475                 bug% 42
476                 count% 10
477                 bug% 422
478         EOF
479         cat >expected <<-\EOF &&
480                 Special Message
481
482                 bug% 42
483                 count% 10
484                 bug% 422
485                 count% 100
486         EOF
487         git interpret-trailers --trailer count%100 \
488                 special_message >actual &&
489         test_cmp expected actual
490 '
491
492 test_expect_success 'with config setup and ":=#" as separators' '
493         git config trailer.separators ":=#" &&
494         git config trailer.bug.key "Bug #" &&
495         cat >expected <<-\EOF &&
496
497                 Bug #42
498         EOF
499         git interpret-trailers --trim-empty --trailer "bug = 42" empty >actual &&
500         test_cmp expected actual
501 '
502
503 test_expect_success 'with commit basic message' '
504         cat basic_message >expected &&
505         echo >>expected &&
506         git interpret-trailers <basic_message >actual &&
507         test_cmp expected actual
508 '
509
510 test_expect_success 'with basic patch' '
511         cat basic_message >input &&
512         cat basic_patch >>input &&
513         cat basic_message >expected &&
514         echo >>expected &&
515         cat basic_patch >>expected &&
516         git interpret-trailers <input >actual &&
517         test_cmp expected actual
518 '
519
520 test_expect_success 'with commit complex message as argument' '
521         cat complex_message_body complex_message_trailers >complex_message &&
522         cat complex_message_body >expected &&
523         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
524                 Fixes: Z
525                 Acked-by= Z
526                 Reviewed-by: Z
527                 Signed-off-by: Z
528         EOF
529         git interpret-trailers complex_message >actual &&
530         test_cmp expected actual
531 '
532
533 test_expect_success 'with 2 files arguments' '
534         cat basic_message >>expected &&
535         echo >>expected &&
536         cat basic_patch >>expected &&
537         git interpret-trailers complex_message input >actual &&
538         test_cmp expected actual
539 '
540
541 test_expect_success 'with message that has comments' '
542         cat basic_message >message_with_comments &&
543         sed -e "s/ Z\$/ /" >>message_with_comments <<-\EOF &&
544                 # comment
545
546                 # other comment
547                 Cc: Z
548                 # yet another comment
549                 Reviewed-by: Johan
550                 Reviewed-by: Z
551                 # last comment
552
553         EOF
554         cat basic_patch >>message_with_comments &&
555         cat basic_message >expected &&
556         cat >>expected <<-\EOF &&
557                 # comment
558
559                 Reviewed-by: Johan
560                 Cc: Peff
561                 # last comment
562
563         EOF
564         cat basic_patch >>expected &&
565         git interpret-trailers --trim-empty --trailer "Cc: Peff" message_with_comments >actual &&
566         test_cmp expected actual
567 '
568
569 test_expect_success 'with message that has an old style conflict block' '
570         cat basic_message >message_with_comments &&
571         sed -e "s/ Z\$/ /" >>message_with_comments <<-\EOF &&
572                 # comment
573
574                 # other comment
575                 Cc: Z
576                 # yet another comment
577                 Reviewed-by: Johan
578                 Reviewed-by: Z
579                 # last comment
580
581                 Conflicts:
582
583         EOF
584         cat basic_message >expected &&
585         cat >>expected <<-\EOF &&
586                 # comment
587
588                 Reviewed-by: Johan
589                 Cc: Peff
590                 # last comment
591
592                 Conflicts:
593
594         EOF
595         git interpret-trailers --trim-empty --trailer "Cc: Peff" message_with_comments >actual &&
596         test_cmp expected actual
597 '
598
599 test_expect_success 'with commit complex message and trailer args' '
600         cat complex_message_body >expected &&
601         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
602                 Fixes: Z
603                 Acked-by= Z
604                 Reviewed-by: Z
605                 Signed-off-by: Z
606                 Acked-by= Peff
607                 Bug #42
608         EOF
609         git interpret-trailers --trailer "ack: Peff" \
610                 --trailer "bug: 42" <complex_message >actual &&
611         test_cmp expected actual
612 '
613
614 test_expect_success 'with complex patch, args and --trim-empty' '
615         cat complex_message >complex_patch &&
616         cat basic_patch >>complex_patch &&
617         cat complex_message_body >expected &&
618         cat >>expected <<-\EOF &&
619                 Acked-by= Peff
620                 Bug #42
621         EOF
622         cat basic_patch >>expected &&
623         git interpret-trailers --trim-empty --trailer "ack: Peff" \
624                 --trailer "bug: 42" <complex_patch >actual &&
625         test_cmp expected actual
626 '
627
628 test_expect_success 'in-place editing with basic patch' '
629         cat basic_message >message &&
630         cat basic_patch >>message &&
631         cat basic_message >expected &&
632         echo >>expected &&
633         cat basic_patch >>expected &&
634         git interpret-trailers --in-place message &&
635         test_cmp expected message
636 '
637
638 test_expect_success 'in-place editing with additional trailer' '
639         cat basic_message >message &&
640         cat basic_patch >>message &&
641         cat basic_message >expected &&
642         echo >>expected &&
643         cat >>expected <<-\EOF &&
644                 Reviewed-by: Alice
645         EOF
646         cat basic_patch >>expected &&
647         git interpret-trailers --trailer "Reviewed-by: Alice" --in-place message &&
648         test_cmp expected message
649 '
650
651 test_expect_success 'in-place editing on stdin disallowed' '
652         test_must_fail git interpret-trailers --trailer "Reviewed-by: Alice" --in-place < basic_message
653 '
654
655 test_expect_success 'in-place editing on non-existing file' '
656         test_must_fail git interpret-trailers --trailer "Reviewed-by: Alice" --in-place nonexisting &&
657         test_path_is_missing nonexisting
658 '
659
660 test_expect_success POSIXPERM,SANITY "in-place editing doesn't clobber original file on error" '
661         cat basic_message >message &&
662         chmod -r message &&
663         test_must_fail git interpret-trailers --trailer "Reviewed-by: Alice" --in-place message &&
664         chmod +r message &&
665         test_cmp message basic_message
666 '
667
668 test_expect_success 'using "where = before"' '
669         git config trailer.bug.where "before" &&
670         cat complex_message_body >expected &&
671         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
672                 Bug #42
673                 Fixes: Z
674                 Acked-by= Z
675                 Reviewed-by: Z
676                 Signed-off-by: Z
677                 Acked-by= Peff
678         EOF
679         git interpret-trailers --trailer "ack: Peff" \
680                 --trailer "bug: 42" complex_message >actual &&
681         test_cmp expected actual
682 '
683
684 test_expect_success 'overriding configuration with "--where after"' '
685         git config trailer.ack.where "before" &&
686         cat complex_message_body >expected &&
687         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
688                 Fixes: Z
689                 Acked-by= Z
690                 Acked-by= Peff
691                 Reviewed-by: Z
692                 Signed-off-by: Z
693         EOF
694         git interpret-trailers --where after --trailer "ack: Peff" \
695                 complex_message >actual &&
696         test_cmp expected actual
697 '
698
699 test_expect_success 'using "where = before" with "--no-where"' '
700         cat complex_message_body >expected &&
701         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
702                 Bug #42
703                 Fixes: Z
704                 Acked-by= Peff
705                 Acked-by= Z
706                 Reviewed-by: Z
707                 Signed-off-by: Z
708         EOF
709         git interpret-trailers --where after --no-where --trailer "ack: Peff" \
710                 --trailer "bug: 42" complex_message >actual &&
711         test_cmp expected actual
712 '
713
714 test_expect_success 'using "where = after"' '
715         git config trailer.ack.where "after" &&
716         cat complex_message_body >expected &&
717         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
718                 Bug #42
719                 Fixes: Z
720                 Acked-by= Z
721                 Acked-by= Peff
722                 Reviewed-by: Z
723                 Signed-off-by: Z
724         EOF
725         git interpret-trailers --trailer "ack: Peff" \
726                 --trailer "bug: 42" complex_message >actual &&
727         test_cmp expected actual
728 '
729
730 test_expect_success 'using "where = end"' '
731         git config trailer.review.key "Reviewed-by" &&
732         git config trailer.review.where "end" &&
733         cat complex_message_body >expected &&
734         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
735                 Fixes: Z
736                 Acked-by= Z
737                 Acked-by= Peff
738                 Reviewed-by: Z
739                 Signed-off-by: Z
740                 Reviewed-by: Junio
741                 Reviewed-by: Johannes
742         EOF
743         git interpret-trailers --trailer "ack: Peff" \
744                 --trailer "Reviewed-by: Junio" --trailer "Reviewed-by: Johannes" \
745                 complex_message >actual &&
746         test_cmp expected actual
747 '
748
749 test_expect_success 'using "where = start"' '
750         git config trailer.review.key "Reviewed-by" &&
751         git config trailer.review.where "start" &&
752         cat complex_message_body >expected &&
753         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
754                 Reviewed-by: Johannes
755                 Reviewed-by: Junio
756                 Fixes: Z
757                 Acked-by= Z
758                 Acked-by= Peff
759                 Reviewed-by: Z
760                 Signed-off-by: Z
761         EOF
762         git interpret-trailers --trailer "ack: Peff" \
763                 --trailer "Reviewed-by: Junio" --trailer "Reviewed-by: Johannes" \
764                 complex_message >actual &&
765         test_cmp expected actual
766 '
767
768 test_expect_success 'using "where = before" for a token in the middle of the message' '
769         git config trailer.review.key "Reviewed-by:" &&
770         git config trailer.review.where "before" &&
771         cat complex_message_body >expected &&
772         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
773                 Bug #42
774                 Fixes: Z
775                 Acked-by= Z
776                 Acked-by= Peff
777                 Reviewed-by:Johan
778                 Reviewed-by:
779                 Signed-off-by: Z
780         EOF
781         git interpret-trailers --trailer "ack: Peff" --trailer "bug: 42" \
782                 --trailer "review: Johan" <complex_message >actual &&
783         test_cmp expected actual
784 '
785
786 test_expect_success 'using "where = before" and --trim-empty' '
787         cat complex_message_body >expected &&
788         cat >>expected <<-\EOF &&
789                 Bug #46
790                 Bug #42
791                 Acked-by= Peff
792                 Reviewed-by:Johan
793         EOF
794         git interpret-trailers --trim-empty --trailer "ack: Peff" \
795                 --trailer "bug: 42" --trailer "review: Johan" \
796                 --trailer "Bug: 46" <complex_message >actual &&
797         test_cmp expected actual
798 '
799
800 test_expect_success 'the default is "ifExists = addIfDifferentNeighbor"' '
801         cat complex_message_body >expected &&
802         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
803                 Bug #42
804                 Fixes: Z
805                 Acked-by= Z
806                 Acked-by= Peff
807                 Acked-by= Junio
808                 Acked-by= Peff
809                 Reviewed-by:
810                 Signed-off-by: Z
811         EOF
812         git interpret-trailers --trailer "ack: Peff" --trailer "review:" \
813                 --trailer "ack: Junio" --trailer "bug: 42" --trailer "ack: Peff" \
814                 --trailer "ack: Peff" <complex_message >actual &&
815         test_cmp expected actual
816 '
817
818 test_expect_success 'default "ifExists" is now "addIfDifferent"' '
819         git config trailer.ifexists "addIfDifferent" &&
820         cat complex_message_body >expected &&
821         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
822                 Bug #42
823                 Fixes: Z
824                 Acked-by= Z
825                 Acked-by= Peff
826                 Acked-by= Junio
827                 Reviewed-by:
828                 Signed-off-by: Z
829         EOF
830         git interpret-trailers --trailer "ack: Peff" --trailer "review:" \
831                 --trailer "ack: Junio" --trailer "bug: 42" --trailer "ack: Peff" \
832                 --trailer "ack: Peff" <complex_message >actual &&
833         test_cmp expected actual
834 '
835
836 test_expect_success 'using "ifExists = addIfDifferent" with "where = end"' '
837         git config trailer.ack.ifExists "addIfDifferent" &&
838         git config trailer.ack.where "end" &&
839         cat complex_message_body >expected &&
840         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
841                 Bug #42
842                 Fixes: Z
843                 Acked-by= Z
844                 Reviewed-by:
845                 Signed-off-by: Z
846                 Acked-by= Peff
847         EOF
848         git interpret-trailers --trailer "ack: Peff" --trailer "review:" \
849                 --trailer "bug: 42" --trailer "ack: Peff" \
850                 <complex_message >actual &&
851         test_cmp expected actual
852 '
853
854 test_expect_success 'using "ifExists = addIfDifferent" with "where = before"' '
855         git config trailer.ack.ifExists "addIfDifferent" &&
856         git config trailer.ack.where "before" &&
857         cat complex_message_body >expected &&
858         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
859                 Bug #42
860                 Fixes: Z
861                 Acked-by= Peff
862                 Acked-by= Z
863                 Reviewed-by:
864                 Signed-off-by: Z
865         EOF
866         git interpret-trailers --trailer "ack: Peff" --trailer "review:" \
867                 --trailer "bug: 42" --trailer "ack: Peff" \
868                 <complex_message >actual &&
869         test_cmp expected actual
870 '
871
872 test_expect_success 'using "ifExists = addIfDifferentNeighbor" with "where = end"' '
873         git config trailer.ack.ifExists "addIfDifferentNeighbor" &&
874         git config trailer.ack.where "end" &&
875         cat complex_message_body >expected &&
876         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
877                 Bug #42
878                 Fixes: Z
879                 Acked-by= Z
880                 Reviewed-by:
881                 Signed-off-by: Z
882                 Acked-by= Peff
883                 Acked-by= Junio
884                 Tested-by: Jakub
885                 Acked-by= Junio
886                 Acked-by= Peff
887         EOF
888         git interpret-trailers --trailer "ack: Peff" --trailer "review:" \
889                 --trailer "ack: Junio" --trailer "bug: 42" \
890                 --trailer "Tested-by: Jakub" --trailer "ack: Junio" \
891                 --trailer "ack: Junio" --trailer "ack: Peff" <complex_message >actual &&
892         test_cmp expected actual
893 '
894
895 test_expect_success 'using "ifExists = addIfDifferentNeighbor"  with "where = after"' '
896         git config trailer.ack.ifExists "addIfDifferentNeighbor" &&
897         git config trailer.ack.where "after" &&
898         cat complex_message_body >expected &&
899         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
900                 Bug #42
901                 Fixes: Z
902                 Acked-by= Z
903                 Acked-by= Peff
904                 Acked-by= Junio
905                 Acked-by= Peff
906                 Reviewed-by:
907                 Signed-off-by: Z
908                 Tested-by: Jakub
909         EOF
910         git interpret-trailers --trailer "ack: Peff" --trailer "review:" \
911                 --trailer "ack: Junio" --trailer "bug: 42" \
912                 --trailer "Tested-by: Jakub" --trailer "ack: Junio" \
913                 --trailer "ack: Junio" --trailer "ack: Peff" <complex_message >actual &&
914         test_cmp expected actual
915 '
916
917 test_expect_success 'using "ifExists = addIfDifferentNeighbor" and --trim-empty' '
918         git config trailer.ack.ifExists "addIfDifferentNeighbor" &&
919         cat complex_message_body >expected &&
920         cat >>expected <<-\EOF &&
921                 Bug #42
922                 Acked-by= Peff
923                 Acked-by= Junio
924                 Acked-by= Peff
925         EOF
926         git interpret-trailers --trim-empty --trailer "ack: Peff" \
927                 --trailer "Acked-by= Peff" --trailer "review:" \
928                 --trailer "ack: Junio" --trailer "bug: 42" \
929                 --trailer "ack: Peff" <complex_message >actual &&
930         test_cmp expected actual
931 '
932
933 test_expect_success 'using "ifExists = add" with "where = end"' '
934         git config trailer.ack.ifExists "add" &&
935         git config trailer.ack.where "end" &&
936         cat complex_message_body >expected &&
937         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
938                 Bug #42
939                 Fixes: Z
940                 Acked-by= Z
941                 Reviewed-by:
942                 Signed-off-by: Z
943                 Acked-by= Peff
944                 Acked-by= Peff
945                 Tested-by: Jakub
946                 Acked-by= Junio
947                 Tested-by: Johannes
948                 Acked-by= Peff
949         EOF
950         git interpret-trailers --trailer "ack: Peff" \
951                 --trailer "Acked-by= Peff" --trailer "review:" \
952                 --trailer "Tested-by: Jakub" --trailer "ack: Junio" \
953                 --trailer "bug: 42" --trailer "Tested-by: Johannes" \
954                 --trailer "ack: Peff" <complex_message >actual &&
955         test_cmp expected actual
956 '
957
958 test_expect_success 'using "ifExists = add" with "where = after"' '
959         git config trailer.ack.ifExists "add" &&
960         git config trailer.ack.where "after" &&
961         cat complex_message_body >expected &&
962         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
963                 Bug #42
964                 Fixes: Z
965                 Acked-by= Z
966                 Acked-by= Peff
967                 Acked-by= Peff
968                 Acked-by= Junio
969                 Acked-by= Peff
970                 Reviewed-by:
971                 Signed-off-by: Z
972         EOF
973         git interpret-trailers --trailer "ack: Peff" \
974                 --trailer "Acked-by= Peff" --trailer "review:" \
975                 --trailer "ack: Junio" --trailer "bug: 42" \
976                 --trailer "ack: Peff" <complex_message >actual &&
977         test_cmp expected actual
978 '
979
980 test_expect_success 'overriding configuration with "--if-exists replace"' '
981         git config trailer.fix.key "Fixes: " &&
982         git config trailer.fix.ifExists "add" &&
983         cat complex_message_body >expected &&
984         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
985                 Bug #42
986                 Acked-by= Z
987                 Reviewed-by:
988                 Signed-off-by: Z
989                 Fixes: 22
990         EOF
991         git interpret-trailers --if-exists replace --trailer "review:" \
992                 --trailer "fix=53" --trailer "fix=22" --trailer "bug: 42" \
993                 <complex_message >actual &&
994         test_cmp expected actual
995 '
996
997 test_expect_success 'using "ifExists = replace"' '
998         git config trailer.fix.key "Fixes: " &&
999         git config trailer.fix.ifExists "replace" &&
1000         cat complex_message_body >expected &&
1001         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1002                 Bug #42
1003                 Acked-by= Z
1004                 Acked-by= Junio
1005                 Acked-by= Peff
1006                 Reviewed-by:
1007                 Signed-off-by: Z
1008                 Fixes: 22
1009         EOF
1010         git interpret-trailers --trailer "review:" \
1011                 --trailer "fix=53" --trailer "ack: Junio" --trailer "fix=22" \
1012                 --trailer "bug: 42" --trailer "ack: Peff" \
1013                 <complex_message >actual &&
1014         test_cmp expected actual
1015 '
1016
1017 test_expect_success 'using "ifExists = replace" with "where = after"' '
1018         git config trailer.fix.where "after" &&
1019         cat complex_message_body >expected &&
1020         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1021                 Bug #42
1022                 Fixes: 22
1023                 Acked-by= Z
1024                 Acked-by= Junio
1025                 Acked-by= Peff
1026                 Reviewed-by:
1027                 Signed-off-by: Z
1028         EOF
1029         git interpret-trailers --trailer "review:" \
1030                 --trailer "fix=53" --trailer "ack: Junio" --trailer "fix=22" \
1031                 --trailer "bug: 42" --trailer "ack: Peff" \
1032                 <complex_message >actual &&
1033         test_cmp expected actual
1034 '
1035
1036 test_expect_success 'using "ifExists = doNothing"' '
1037         git config trailer.fix.ifExists "doNothing" &&
1038         cat complex_message_body >expected &&
1039         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1040                 Bug #42
1041                 Fixes: Z
1042                 Acked-by= Z
1043                 Acked-by= Junio
1044                 Acked-by= Peff
1045                 Reviewed-by:
1046                 Signed-off-by: Z
1047         EOF
1048         git interpret-trailers --trailer "review:" --trailer "fix=53" \
1049                 --trailer "ack: Junio" --trailer "fix=22" \
1050                 --trailer "bug: 42" --trailer "ack: Peff" \
1051                 <complex_message >actual &&
1052         test_cmp expected actual
1053 '
1054
1055 test_expect_success 'the default is "ifMissing = add"' '
1056         git config trailer.cc.key "Cc: " &&
1057         git config trailer.cc.where "before" &&
1058         cat complex_message_body >expected &&
1059         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1060                 Bug #42
1061                 Cc: Linus
1062                 Fixes: Z
1063                 Acked-by= Z
1064                 Acked-by= Junio
1065                 Acked-by= Peff
1066                 Reviewed-by:
1067                 Signed-off-by: Z
1068         EOF
1069         git interpret-trailers --trailer "review:" --trailer "fix=53" \
1070                 --trailer "cc=Linus" --trailer "ack: Junio" \
1071                 --trailer "fix=22" --trailer "bug: 42" --trailer "ack: Peff" \
1072                 <complex_message >actual &&
1073         test_cmp expected actual
1074 '
1075
1076 test_expect_success 'overriding configuration with "--if-missing doNothing"' '
1077         git config trailer.ifmissing "add" &&
1078         cat complex_message_body >expected &&
1079         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1080                 Fixes: Z
1081                 Acked-by= Z
1082                 Acked-by= Junio
1083                 Acked-by= Peff
1084                 Reviewed-by:
1085                 Signed-off-by: Z
1086         EOF
1087         git interpret-trailers --if-missing doNothing \
1088                 --trailer "review:" --trailer "fix=53" \
1089                 --trailer "cc=Linus" --trailer "ack: Junio" \
1090                 --trailer "fix=22" --trailer "bug: 42" --trailer "ack: Peff" \
1091                 <complex_message >actual &&
1092         test_cmp expected actual
1093 '
1094
1095 test_expect_success 'when default "ifMissing" is "doNothing"' '
1096         git config trailer.ifmissing "doNothing" &&
1097         cat complex_message_body >expected &&
1098         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1099                 Fixes: Z
1100                 Acked-by= Z
1101                 Acked-by= Junio
1102                 Acked-by= Peff
1103                 Reviewed-by:
1104                 Signed-off-by: Z
1105         EOF
1106         git interpret-trailers --trailer "review:" --trailer "fix=53" \
1107                 --trailer "cc=Linus" --trailer "ack: Junio" \
1108                 --trailer "fix=22" --trailer "bug: 42" --trailer "ack: Peff" \
1109                 <complex_message >actual &&
1110         test_cmp expected actual &&
1111         git config trailer.ifmissing "add"
1112 '
1113
1114 test_expect_success 'using "ifMissing = add" with "where = end"' '
1115         git config trailer.cc.key "Cc: " &&
1116         git config trailer.cc.where "end" &&
1117         git config trailer.cc.ifMissing "add" &&
1118         cat complex_message_body >expected &&
1119         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1120                 Bug #42
1121                 Fixes: Z
1122                 Acked-by= Z
1123                 Acked-by= Junio
1124                 Acked-by= Peff
1125                 Reviewed-by:
1126                 Signed-off-by: Z
1127                 Cc: Linus
1128         EOF
1129         git interpret-trailers --trailer "review:" --trailer "fix=53" \
1130                 --trailer "ack: Junio" --trailer "fix=22" \
1131                 --trailer "bug: 42" --trailer "cc=Linus" --trailer "ack: Peff" \
1132                 <complex_message >actual &&
1133         test_cmp expected actual
1134 '
1135
1136 test_expect_success 'using "ifMissing = add" with "where = before"' '
1137         git config trailer.cc.key "Cc: " &&
1138         git config trailer.cc.where "before" &&
1139         git config trailer.cc.ifMissing "add" &&
1140         cat complex_message_body >expected &&
1141         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1142                 Cc: Linus
1143                 Bug #42
1144                 Fixes: Z
1145                 Acked-by= Z
1146                 Acked-by= Junio
1147                 Acked-by= Peff
1148                 Reviewed-by:
1149                 Signed-off-by: Z
1150         EOF
1151         git interpret-trailers --trailer "review:" --trailer "fix=53" \
1152                 --trailer "ack: Junio" --trailer "fix=22" \
1153                 --trailer "bug: 42" --trailer "cc=Linus" --trailer "ack: Peff" \
1154                 <complex_message >actual &&
1155         test_cmp expected actual
1156 '
1157
1158 test_expect_success 'using "ifMissing = doNothing"' '
1159         git config trailer.cc.ifMissing "doNothing" &&
1160         cat complex_message_body >expected &&
1161         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1162                 Bug #42
1163                 Fixes: Z
1164                 Acked-by= Z
1165                 Acked-by= Junio
1166                 Acked-by= Peff
1167                 Reviewed-by:
1168                 Signed-off-by: Z
1169         EOF
1170         git interpret-trailers --trailer "review:" --trailer "fix=53" \
1171                 --trailer "cc=Linus" --trailer "ack: Junio" \
1172                 --trailer "fix=22" --trailer "bug: 42" --trailer "ack: Peff" \
1173                 <complex_message >actual &&
1174         test_cmp expected actual
1175 '
1176
1177 test_expect_success 'default "where" is now "after"' '
1178         git config trailer.where "after" &&
1179         git config --unset trailer.ack.where &&
1180         cat complex_message_body >expected &&
1181         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1182                 Bug #42
1183                 Fixes: Z
1184                 Acked-by= Z
1185                 Acked-by= Peff
1186                 Acked-by= Peff
1187                 Acked-by= Junio
1188                 Acked-by= Peff
1189                 Reviewed-by:
1190                 Signed-off-by: Z
1191                 Tested-by: Jakub
1192                 Tested-by: Johannes
1193         EOF
1194         git interpret-trailers --trailer "ack: Peff" \
1195                 --trailer "Acked-by= Peff" --trailer "review:" \
1196                 --trailer "Tested-by: Jakub" --trailer "ack: Junio" \
1197                 --trailer "bug: 42" --trailer "Tested-by: Johannes" \
1198                 --trailer "ack: Peff" <complex_message >actual &&
1199         test_cmp expected actual
1200 '
1201
1202 test_expect_success 'with simple command' '
1203         git config trailer.sign.key "Signed-off-by: " &&
1204         git config trailer.sign.where "after" &&
1205         git config trailer.sign.ifExists "addIfDifferentNeighbor" &&
1206         git config trailer.sign.command "echo \"A U Thor <author@example.com>\"" &&
1207         cat complex_message_body >expected &&
1208         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1209                 Fixes: Z
1210                 Acked-by= Z
1211                 Reviewed-by:
1212                 Signed-off-by: Z
1213                 Signed-off-by: A U Thor <author@example.com>
1214         EOF
1215         git interpret-trailers --trailer "review:" --trailer "fix=22" \
1216                 <complex_message >actual &&
1217         test_cmp expected actual
1218 '
1219
1220 test_expect_success 'with command using commiter information' '
1221         git config trailer.sign.ifExists "addIfDifferent" &&
1222         git config trailer.sign.command "echo \"\$GIT_COMMITTER_NAME <\$GIT_COMMITTER_EMAIL>\"" &&
1223         cat complex_message_body >expected &&
1224         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1225                 Fixes: Z
1226                 Acked-by= Z
1227                 Reviewed-by:
1228                 Signed-off-by: Z
1229                 Signed-off-by: C O Mitter <committer@example.com>
1230         EOF
1231         git interpret-trailers --trailer "review:" --trailer "fix=22" \
1232                 <complex_message >actual &&
1233         test_cmp expected actual
1234 '
1235
1236 test_expect_success 'with command using author information' '
1237         git config trailer.sign.key "Signed-off-by: " &&
1238         git config trailer.sign.where "after" &&
1239         git config trailer.sign.ifExists "addIfDifferentNeighbor" &&
1240         git config trailer.sign.command "echo \"\$GIT_AUTHOR_NAME <\$GIT_AUTHOR_EMAIL>\"" &&
1241         cat complex_message_body >expected &&
1242         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1243                 Fixes: Z
1244                 Acked-by= Z
1245                 Reviewed-by:
1246                 Signed-off-by: Z
1247                 Signed-off-by: A U Thor <author@example.com>
1248         EOF
1249         git interpret-trailers --trailer "review:" --trailer "fix=22" \
1250                 <complex_message >actual &&
1251         test_cmp expected actual
1252 '
1253
1254 test_expect_success 'setup a commit' '
1255         echo "Content of the first commit." > a.txt &&
1256         git add a.txt &&
1257         git commit -m "Add file a.txt"
1258 '
1259
1260 test_expect_success 'with command using $ARG' '
1261         git config trailer.fix.ifExists "replace" &&
1262         git config trailer.fix.command "git log -1 --oneline --format=\"%h (%s)\" --abbrev-commit --abbrev=14 \$ARG" &&
1263         FIXED=$(git log -1 --oneline --format="%h (%s)" --abbrev-commit --abbrev=14 HEAD) &&
1264         cat complex_message_body >expected &&
1265         sed -e "s/ Z\$/ /" >>expected <<-EOF &&
1266                 Fixes: $FIXED
1267                 Acked-by= Z
1268                 Reviewed-by:
1269                 Signed-off-by: Z
1270                 Signed-off-by: A U Thor <author@example.com>
1271         EOF
1272         git interpret-trailers --trailer "review:" --trailer "fix=HEAD" \
1273                 <complex_message >actual &&
1274         test_cmp expected actual
1275 '
1276
1277 test_expect_success 'with failing command using $ARG' '
1278         git config trailer.fix.ifExists "replace" &&
1279         git config trailer.fix.command "false \$ARG" &&
1280         cat complex_message_body >expected &&
1281         sed -e "s/ Z\$/ /" >>expected <<-EOF &&
1282                 Fixes: Z
1283                 Acked-by= Z
1284                 Reviewed-by:
1285                 Signed-off-by: Z
1286                 Signed-off-by: A U Thor <author@example.com>
1287         EOF
1288         git interpret-trailers --trailer "review:" --trailer "fix=HEAD" \
1289                 <complex_message >actual &&
1290         test_cmp expected actual
1291 '
1292
1293 test_expect_success 'with empty tokens' '
1294         git config --unset trailer.fix.command &&
1295         cat >expected <<-EOF &&
1296
1297                 Signed-off-by: A U Thor <author@example.com>
1298         EOF
1299         git interpret-trailers --trailer ":" --trailer ":test" >actual <<-EOF &&
1300         EOF
1301         test_cmp expected actual
1302 '
1303
1304 test_expect_success 'with command but no key' '
1305         git config --unset trailer.sign.key &&
1306         cat >expected <<-EOF &&
1307
1308                 sign: A U Thor <author@example.com>
1309         EOF
1310         git interpret-trailers >actual <<-EOF &&
1311         EOF
1312         test_cmp expected actual
1313 '
1314
1315 test_expect_success 'with no command and no key' '
1316         git config --unset trailer.review.key &&
1317         cat >expected <<-EOF &&
1318
1319                 review: Junio
1320                 sign: A U Thor <author@example.com>
1321         EOF
1322         git interpret-trailers --trailer "review:Junio" >actual <<-EOF &&
1323         EOF
1324         test_cmp expected actual
1325 '
1326
1327 test_expect_success 'with cut line' '
1328         cat >expected <<-\EOF &&
1329                 my subject
1330
1331                 review: Brian
1332                 sign: A U Thor <author@example.com>
1333                 # ------------------------ >8 ------------------------
1334                 ignore this
1335         EOF
1336         git interpret-trailers --trailer review:Brian >actual <<-\EOF &&
1337                 my subject
1338                 # ------------------------ >8 ------------------------
1339                 ignore this
1340         EOF
1341         test_cmp expected actual
1342 '
1343
1344 test_expect_success 'only trailers' '
1345         git config trailer.sign.command "echo config-value" &&
1346         cat >expected <<-\EOF &&
1347                 existing: existing-value
1348                 sign: config-value
1349                 added: added-value
1350         EOF
1351         git interpret-trailers \
1352                 --trailer added:added-value \
1353                 --only-trailers >actual <<-\EOF &&
1354                 my subject
1355
1356                 my body
1357
1358                 existing: existing-value
1359         EOF
1360         test_cmp expected actual
1361 '
1362
1363 test_expect_success 'only-trailers omits non-trailer in middle of block' '
1364         git config trailer.sign.command "echo config-value" &&
1365         cat >expected <<-\EOF &&
1366                 Signed-off-by: nobody <nobody@nowhere>
1367                 Signed-off-by: somebody <somebody@somewhere>
1368                 sign: config-value
1369         EOF
1370         git interpret-trailers --only-trailers >actual <<-\EOF &&
1371                 subject
1372
1373                 it is important that the trailers below are signed-off-by
1374                 so that they meet the "25% trailers Git knows about" heuristic
1375
1376                 Signed-off-by: nobody <nobody@nowhere>
1377                 this is not a trailer
1378                 Signed-off-by: somebody <somebody@somewhere>
1379         EOF
1380         test_cmp expected actual
1381 '
1382
1383 test_expect_success 'only input' '
1384         git config trailer.sign.command "echo config-value" &&
1385         cat >expected <<-\EOF &&
1386                 existing: existing-value
1387         EOF
1388         git interpret-trailers \
1389                 --only-trailers --only-input >actual <<-\EOF &&
1390                 my subject
1391
1392                 my body
1393
1394                 existing: existing-value
1395         EOF
1396         test_cmp expected actual
1397 '
1398
1399 test_expect_success 'unfold' '
1400         cat >expected <<-\EOF &&
1401                 foo: continued across several lines
1402         EOF
1403         # pass through tr to make leading and trailing whitespace more obvious
1404         tr _ " " <<-\EOF |
1405                 my subject
1406
1407                 my body
1408
1409                 foo:_
1410                 __continued
1411                 ___across
1412                 ____several
1413                 _____lines
1414                 ___
1415         EOF
1416         git interpret-trailers --only-trailers --only-input --unfold >actual &&
1417         test_cmp expected actual
1418 '
1419
1420 test_done