Merge tag 'v2.23.0-rc0' of git://git.kernel.org/pub/scm/git/git
[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 # Cover multiple comment characters with the same test input.
542 for char in "#" ";"
543 do
544         case "$char" in
545         "#")
546                 # This is the default, so let's explicitly _not_
547                 # set any config to make sure it behaves as we expect.
548                 ;;
549         *)
550                 config="-c core.commentChar=$char"
551                 ;;
552         esac
553
554         test_expect_success "with message that has comments ($char)" '
555                 cat basic_message >message_with_comments &&
556                 sed -e "s/ Z\$/ /" \
557                     -e "s/#/$char/g" >>message_with_comments <<-EOF &&
558                         # comment
559
560                         # other comment
561                         Cc: Z
562                         # yet another comment
563                         Reviewed-by: Johan
564                         Reviewed-by: Z
565                         # last comment
566
567                 EOF
568                 cat basic_patch >>message_with_comments &&
569                 cat basic_message >expected &&
570                 sed -e "s/#/$char/g" >>expected <<-\EOF &&
571                         # comment
572
573                         Reviewed-by: Johan
574                         Cc: Peff
575                         # last comment
576
577                 EOF
578                 cat basic_patch >>expected &&
579                 git $config interpret-trailers \
580                         --trim-empty --trailer "Cc: Peff" \
581                         message_with_comments >actual &&
582                 test_cmp expected actual
583         '
584 done
585
586 test_expect_success 'with message that has an old style conflict block' '
587         cat basic_message >message_with_comments &&
588         sed -e "s/ Z\$/ /" >>message_with_comments <<-\EOF &&
589                 # comment
590
591                 # other comment
592                 Cc: Z
593                 # yet another comment
594                 Reviewed-by: Johan
595                 Reviewed-by: Z
596                 # last comment
597
598                 Conflicts:
599
600         EOF
601         cat basic_message >expected &&
602         cat >>expected <<-\EOF &&
603                 # comment
604
605                 Reviewed-by: Johan
606                 Cc: Peff
607                 # last comment
608
609                 Conflicts:
610
611         EOF
612         git interpret-trailers --trim-empty --trailer "Cc: Peff" message_with_comments >actual &&
613         test_cmp expected actual
614 '
615
616 test_expect_success 'with commit complex message and trailer args' '
617         cat complex_message_body >expected &&
618         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
619                 Fixes: Z
620                 Acked-by= Z
621                 Reviewed-by: Z
622                 Signed-off-by: Z
623                 Acked-by= Peff
624                 Bug #42
625         EOF
626         git interpret-trailers --trailer "ack: Peff" \
627                 --trailer "bug: 42" <complex_message >actual &&
628         test_cmp expected actual
629 '
630
631 test_expect_success 'with complex patch, args and --trim-empty' '
632         cat complex_message >complex_patch &&
633         cat basic_patch >>complex_patch &&
634         cat complex_message_body >expected &&
635         cat >>expected <<-\EOF &&
636                 Acked-by= Peff
637                 Bug #42
638         EOF
639         cat basic_patch >>expected &&
640         git interpret-trailers --trim-empty --trailer "ack: Peff" \
641                 --trailer "bug: 42" <complex_patch >actual &&
642         test_cmp expected actual
643 '
644
645 test_expect_success 'in-place editing with basic patch' '
646         cat basic_message >message &&
647         cat basic_patch >>message &&
648         cat basic_message >expected &&
649         echo >>expected &&
650         cat basic_patch >>expected &&
651         git interpret-trailers --in-place message &&
652         test_cmp expected message
653 '
654
655 test_expect_success 'in-place editing with additional trailer' '
656         cat basic_message >message &&
657         cat basic_patch >>message &&
658         cat basic_message >expected &&
659         echo >>expected &&
660         cat >>expected <<-\EOF &&
661                 Reviewed-by: Alice
662         EOF
663         cat basic_patch >>expected &&
664         git interpret-trailers --trailer "Reviewed-by: Alice" --in-place message &&
665         test_cmp expected message
666 '
667
668 test_expect_success 'in-place editing on stdin disallowed' '
669         test_must_fail git interpret-trailers --trailer "Reviewed-by: Alice" --in-place < basic_message
670 '
671
672 test_expect_success 'in-place editing on non-existing file' '
673         test_must_fail git interpret-trailers --trailer "Reviewed-by: Alice" --in-place nonexisting &&
674         test_path_is_missing nonexisting
675 '
676
677 test_expect_success POSIXPERM,SANITY "in-place editing doesn't clobber original file on error" '
678         cat basic_message >message &&
679         chmod -r message &&
680         test_must_fail git interpret-trailers --trailer "Reviewed-by: Alice" --in-place message &&
681         chmod +r message &&
682         test_cmp message basic_message
683 '
684
685 test_expect_success 'using "where = before"' '
686         git config trailer.bug.where "before" &&
687         cat complex_message_body >expected &&
688         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
689                 Bug #42
690                 Fixes: Z
691                 Acked-by= Z
692                 Reviewed-by: Z
693                 Signed-off-by: Z
694                 Acked-by= Peff
695         EOF
696         git interpret-trailers --trailer "ack: Peff" \
697                 --trailer "bug: 42" complex_message >actual &&
698         test_cmp expected actual
699 '
700
701 test_expect_success 'overriding configuration with "--where after"' '
702         git config trailer.ack.where "before" &&
703         cat complex_message_body >expected &&
704         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
705                 Fixes: Z
706                 Acked-by= Z
707                 Acked-by= Peff
708                 Reviewed-by: Z
709                 Signed-off-by: Z
710         EOF
711         git interpret-trailers --where after --trailer "ack: Peff" \
712                 complex_message >actual &&
713         test_cmp expected actual
714 '
715
716 test_expect_success 'using "where = before" with "--no-where"' '
717         cat complex_message_body >expected &&
718         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
719                 Bug #42
720                 Fixes: Z
721                 Acked-by= Peff
722                 Acked-by= Z
723                 Reviewed-by: Z
724                 Signed-off-by: Z
725         EOF
726         git interpret-trailers --where after --no-where --trailer "ack: Peff" \
727                 --trailer "bug: 42" complex_message >actual &&
728         test_cmp expected actual
729 '
730
731 test_expect_success 'using "where = after"' '
732         git config trailer.ack.where "after" &&
733         cat complex_message_body >expected &&
734         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
735                 Bug #42
736                 Fixes: Z
737                 Acked-by= Z
738                 Acked-by= Peff
739                 Reviewed-by: Z
740                 Signed-off-by: Z
741         EOF
742         git interpret-trailers --trailer "ack: Peff" \
743                 --trailer "bug: 42" complex_message >actual &&
744         test_cmp expected actual
745 '
746
747 test_expect_success 'using "where = end"' '
748         git config trailer.review.key "Reviewed-by" &&
749         git config trailer.review.where "end" &&
750         cat complex_message_body >expected &&
751         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
752                 Fixes: Z
753                 Acked-by= Z
754                 Acked-by= Peff
755                 Reviewed-by: Z
756                 Signed-off-by: Z
757                 Reviewed-by: Junio
758                 Reviewed-by: Johannes
759         EOF
760         git interpret-trailers --trailer "ack: Peff" \
761                 --trailer "Reviewed-by: Junio" --trailer "Reviewed-by: Johannes" \
762                 complex_message >actual &&
763         test_cmp expected actual
764 '
765
766 test_expect_success 'using "where = start"' '
767         git config trailer.review.key "Reviewed-by" &&
768         git config trailer.review.where "start" &&
769         cat complex_message_body >expected &&
770         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
771                 Reviewed-by: Johannes
772                 Reviewed-by: Junio
773                 Fixes: Z
774                 Acked-by= Z
775                 Acked-by= Peff
776                 Reviewed-by: Z
777                 Signed-off-by: Z
778         EOF
779         git interpret-trailers --trailer "ack: Peff" \
780                 --trailer "Reviewed-by: Junio" --trailer "Reviewed-by: Johannes" \
781                 complex_message >actual &&
782         test_cmp expected actual
783 '
784
785 test_expect_success 'using "where = before" for a token in the middle of the message' '
786         git config trailer.review.key "Reviewed-by:" &&
787         git config trailer.review.where "before" &&
788         cat complex_message_body >expected &&
789         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
790                 Bug #42
791                 Fixes: Z
792                 Acked-by= Z
793                 Acked-by= Peff
794                 Reviewed-by:Johan
795                 Reviewed-by:
796                 Signed-off-by: Z
797         EOF
798         git interpret-trailers --trailer "ack: Peff" --trailer "bug: 42" \
799                 --trailer "review: Johan" <complex_message >actual &&
800         test_cmp expected actual
801 '
802
803 test_expect_success 'using "where = before" and --trim-empty' '
804         cat complex_message_body >expected &&
805         cat >>expected <<-\EOF &&
806                 Bug #46
807                 Bug #42
808                 Acked-by= Peff
809                 Reviewed-by:Johan
810         EOF
811         git interpret-trailers --trim-empty --trailer "ack: Peff" \
812                 --trailer "bug: 42" --trailer "review: Johan" \
813                 --trailer "Bug: 46" <complex_message >actual &&
814         test_cmp expected actual
815 '
816
817 test_expect_success 'the default is "ifExists = addIfDifferentNeighbor"' '
818         cat complex_message_body >expected &&
819         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
820                 Bug #42
821                 Fixes: Z
822                 Acked-by= Z
823                 Acked-by= Peff
824                 Acked-by= Junio
825                 Acked-by= Peff
826                 Reviewed-by:
827                 Signed-off-by: Z
828         EOF
829         git interpret-trailers --trailer "ack: Peff" --trailer "review:" \
830                 --trailer "ack: Junio" --trailer "bug: 42" --trailer "ack: Peff" \
831                 --trailer "ack: Peff" <complex_message >actual &&
832         test_cmp expected actual
833 '
834
835 test_expect_success 'default "ifExists" is now "addIfDifferent"' '
836         git config trailer.ifexists "addIfDifferent" &&
837         cat complex_message_body >expected &&
838         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
839                 Bug #42
840                 Fixes: Z
841                 Acked-by= Z
842                 Acked-by= Peff
843                 Acked-by= Junio
844                 Reviewed-by:
845                 Signed-off-by: Z
846         EOF
847         git interpret-trailers --trailer "ack: Peff" --trailer "review:" \
848                 --trailer "ack: Junio" --trailer "bug: 42" --trailer "ack: Peff" \
849                 --trailer "ack: Peff" <complex_message >actual &&
850         test_cmp expected actual
851 '
852
853 test_expect_success 'using "ifExists = addIfDifferent" with "where = end"' '
854         git config trailer.ack.ifExists "addIfDifferent" &&
855         git config trailer.ack.where "end" &&
856         cat complex_message_body >expected &&
857         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
858                 Bug #42
859                 Fixes: Z
860                 Acked-by= Z
861                 Reviewed-by:
862                 Signed-off-by: Z
863                 Acked-by= Peff
864         EOF
865         git interpret-trailers --trailer "ack: Peff" --trailer "review:" \
866                 --trailer "bug: 42" --trailer "ack: Peff" \
867                 <complex_message >actual &&
868         test_cmp expected actual
869 '
870
871 test_expect_success 'using "ifExists = addIfDifferent" with "where = before"' '
872         git config trailer.ack.ifExists "addIfDifferent" &&
873         git config trailer.ack.where "before" &&
874         cat complex_message_body >expected &&
875         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
876                 Bug #42
877                 Fixes: Z
878                 Acked-by= Peff
879                 Acked-by= Z
880                 Reviewed-by:
881                 Signed-off-by: Z
882         EOF
883         git interpret-trailers --trailer "ack: Peff" --trailer "review:" \
884                 --trailer "bug: 42" --trailer "ack: Peff" \
885                 <complex_message >actual &&
886         test_cmp expected actual
887 '
888
889 test_expect_success 'using "ifExists = addIfDifferentNeighbor" with "where = end"' '
890         git config trailer.ack.ifExists "addIfDifferentNeighbor" &&
891         git config trailer.ack.where "end" &&
892         cat complex_message_body >expected &&
893         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
894                 Bug #42
895                 Fixes: Z
896                 Acked-by= Z
897                 Reviewed-by:
898                 Signed-off-by: Z
899                 Acked-by= Peff
900                 Acked-by= Junio
901                 Tested-by: Jakub
902                 Acked-by= Junio
903                 Acked-by= Peff
904         EOF
905         git interpret-trailers --trailer "ack: Peff" --trailer "review:" \
906                 --trailer "ack: Junio" --trailer "bug: 42" \
907                 --trailer "Tested-by: Jakub" --trailer "ack: Junio" \
908                 --trailer "ack: Junio" --trailer "ack: Peff" <complex_message >actual &&
909         test_cmp expected actual
910 '
911
912 test_expect_success 'using "ifExists = addIfDifferentNeighbor"  with "where = after"' '
913         git config trailer.ack.ifExists "addIfDifferentNeighbor" &&
914         git config trailer.ack.where "after" &&
915         cat complex_message_body >expected &&
916         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
917                 Bug #42
918                 Fixes: Z
919                 Acked-by= Z
920                 Acked-by= Peff
921                 Acked-by= Junio
922                 Acked-by= Peff
923                 Reviewed-by:
924                 Signed-off-by: Z
925                 Tested-by: Jakub
926         EOF
927         git interpret-trailers --trailer "ack: Peff" --trailer "review:" \
928                 --trailer "ack: Junio" --trailer "bug: 42" \
929                 --trailer "Tested-by: Jakub" --trailer "ack: Junio" \
930                 --trailer "ack: Junio" --trailer "ack: Peff" <complex_message >actual &&
931         test_cmp expected actual
932 '
933
934 test_expect_success 'using "ifExists = addIfDifferentNeighbor" and --trim-empty' '
935         git config trailer.ack.ifExists "addIfDifferentNeighbor" &&
936         cat complex_message_body >expected &&
937         cat >>expected <<-\EOF &&
938                 Bug #42
939                 Acked-by= Peff
940                 Acked-by= Junio
941                 Acked-by= Peff
942         EOF
943         git interpret-trailers --trim-empty --trailer "ack: Peff" \
944                 --trailer "Acked-by= Peff" --trailer "review:" \
945                 --trailer "ack: Junio" --trailer "bug: 42" \
946                 --trailer "ack: Peff" <complex_message >actual &&
947         test_cmp expected actual
948 '
949
950 test_expect_success 'using "ifExists = add" with "where = end"' '
951         git config trailer.ack.ifExists "add" &&
952         git config trailer.ack.where "end" &&
953         cat complex_message_body >expected &&
954         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
955                 Bug #42
956                 Fixes: Z
957                 Acked-by= Z
958                 Reviewed-by:
959                 Signed-off-by: Z
960                 Acked-by= Peff
961                 Acked-by= Peff
962                 Tested-by: Jakub
963                 Acked-by= Junio
964                 Tested-by: Johannes
965                 Acked-by= Peff
966         EOF
967         git interpret-trailers --trailer "ack: Peff" \
968                 --trailer "Acked-by= Peff" --trailer "review:" \
969                 --trailer "Tested-by: Jakub" --trailer "ack: Junio" \
970                 --trailer "bug: 42" --trailer "Tested-by: Johannes" \
971                 --trailer "ack: Peff" <complex_message >actual &&
972         test_cmp expected actual
973 '
974
975 test_expect_success 'using "ifExists = add" with "where = after"' '
976         git config trailer.ack.ifExists "add" &&
977         git config trailer.ack.where "after" &&
978         cat complex_message_body >expected &&
979         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
980                 Bug #42
981                 Fixes: Z
982                 Acked-by= Z
983                 Acked-by= Peff
984                 Acked-by= Peff
985                 Acked-by= Junio
986                 Acked-by= Peff
987                 Reviewed-by:
988                 Signed-off-by: Z
989         EOF
990         git interpret-trailers --trailer "ack: Peff" \
991                 --trailer "Acked-by= Peff" --trailer "review:" \
992                 --trailer "ack: Junio" --trailer "bug: 42" \
993                 --trailer "ack: Peff" <complex_message >actual &&
994         test_cmp expected actual
995 '
996
997 test_expect_success 'overriding configuration with "--if-exists replace"' '
998         git config trailer.fix.key "Fixes: " &&
999         git config trailer.fix.ifExists "add" &&
1000         cat complex_message_body >expected &&
1001         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1002                 Bug #42
1003                 Acked-by= Z
1004                 Reviewed-by:
1005                 Signed-off-by: Z
1006                 Fixes: 22
1007         EOF
1008         git interpret-trailers --if-exists replace --trailer "review:" \
1009                 --trailer "fix=53" --trailer "fix=22" --trailer "bug: 42" \
1010                 <complex_message >actual &&
1011         test_cmp expected actual
1012 '
1013
1014 test_expect_success 'using "ifExists = replace"' '
1015         git config trailer.fix.key "Fixes: " &&
1016         git config trailer.fix.ifExists "replace" &&
1017         cat complex_message_body >expected &&
1018         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1019                 Bug #42
1020                 Acked-by= Z
1021                 Acked-by= Junio
1022                 Acked-by= Peff
1023                 Reviewed-by:
1024                 Signed-off-by: Z
1025                 Fixes: 22
1026         EOF
1027         git interpret-trailers --trailer "review:" \
1028                 --trailer "fix=53" --trailer "ack: Junio" --trailer "fix=22" \
1029                 --trailer "bug: 42" --trailer "ack: Peff" \
1030                 <complex_message >actual &&
1031         test_cmp expected actual
1032 '
1033
1034 test_expect_success 'using "ifExists = replace" with "where = after"' '
1035         git config trailer.fix.where "after" &&
1036         cat complex_message_body >expected &&
1037         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1038                 Bug #42
1039                 Fixes: 22
1040                 Acked-by= Z
1041                 Acked-by= Junio
1042                 Acked-by= Peff
1043                 Reviewed-by:
1044                 Signed-off-by: Z
1045         EOF
1046         git interpret-trailers --trailer "review:" \
1047                 --trailer "fix=53" --trailer "ack: Junio" --trailer "fix=22" \
1048                 --trailer "bug: 42" --trailer "ack: Peff" \
1049                 <complex_message >actual &&
1050         test_cmp expected actual
1051 '
1052
1053 test_expect_success 'using "ifExists = doNothing"' '
1054         git config trailer.fix.ifExists "doNothing" &&
1055         cat complex_message_body >expected &&
1056         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1057                 Bug #42
1058                 Fixes: Z
1059                 Acked-by= Z
1060                 Acked-by= Junio
1061                 Acked-by= Peff
1062                 Reviewed-by:
1063                 Signed-off-by: Z
1064         EOF
1065         git interpret-trailers --trailer "review:" --trailer "fix=53" \
1066                 --trailer "ack: Junio" --trailer "fix=22" \
1067                 --trailer "bug: 42" --trailer "ack: Peff" \
1068                 <complex_message >actual &&
1069         test_cmp expected actual
1070 '
1071
1072 test_expect_success 'the default is "ifMissing = add"' '
1073         git config trailer.cc.key "Cc: " &&
1074         git config trailer.cc.where "before" &&
1075         cat complex_message_body >expected &&
1076         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1077                 Bug #42
1078                 Cc: Linus
1079                 Fixes: Z
1080                 Acked-by= Z
1081                 Acked-by= Junio
1082                 Acked-by= Peff
1083                 Reviewed-by:
1084                 Signed-off-by: Z
1085         EOF
1086         git interpret-trailers --trailer "review:" --trailer "fix=53" \
1087                 --trailer "cc=Linus" --trailer "ack: Junio" \
1088                 --trailer "fix=22" --trailer "bug: 42" --trailer "ack: Peff" \
1089                 <complex_message >actual &&
1090         test_cmp expected actual
1091 '
1092
1093 test_expect_success 'overriding configuration with "--if-missing doNothing"' '
1094         git config trailer.ifmissing "add" &&
1095         cat complex_message_body >expected &&
1096         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1097                 Fixes: Z
1098                 Acked-by= Z
1099                 Acked-by= Junio
1100                 Acked-by= Peff
1101                 Reviewed-by:
1102                 Signed-off-by: Z
1103         EOF
1104         git interpret-trailers --if-missing doNothing \
1105                 --trailer "review:" --trailer "fix=53" \
1106                 --trailer "cc=Linus" --trailer "ack: Junio" \
1107                 --trailer "fix=22" --trailer "bug: 42" --trailer "ack: Peff" \
1108                 <complex_message >actual &&
1109         test_cmp expected actual
1110 '
1111
1112 test_expect_success 'when default "ifMissing" is "doNothing"' '
1113         git config trailer.ifmissing "doNothing" &&
1114         cat complex_message_body >expected &&
1115         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1116                 Fixes: Z
1117                 Acked-by= Z
1118                 Acked-by= Junio
1119                 Acked-by= Peff
1120                 Reviewed-by:
1121                 Signed-off-by: Z
1122         EOF
1123         git interpret-trailers --trailer "review:" --trailer "fix=53" \
1124                 --trailer "cc=Linus" --trailer "ack: Junio" \
1125                 --trailer "fix=22" --trailer "bug: 42" --trailer "ack: Peff" \
1126                 <complex_message >actual &&
1127         test_cmp expected actual &&
1128         git config trailer.ifmissing "add"
1129 '
1130
1131 test_expect_success 'using "ifMissing = add" with "where = end"' '
1132         git config trailer.cc.key "Cc: " &&
1133         git config trailer.cc.where "end" &&
1134         git config trailer.cc.ifMissing "add" &&
1135         cat complex_message_body >expected &&
1136         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1137                 Bug #42
1138                 Fixes: Z
1139                 Acked-by= Z
1140                 Acked-by= Junio
1141                 Acked-by= Peff
1142                 Reviewed-by:
1143                 Signed-off-by: Z
1144                 Cc: Linus
1145         EOF
1146         git interpret-trailers --trailer "review:" --trailer "fix=53" \
1147                 --trailer "ack: Junio" --trailer "fix=22" \
1148                 --trailer "bug: 42" --trailer "cc=Linus" --trailer "ack: Peff" \
1149                 <complex_message >actual &&
1150         test_cmp expected actual
1151 '
1152
1153 test_expect_success 'using "ifMissing = add" with "where = before"' '
1154         git config trailer.cc.key "Cc: " &&
1155         git config trailer.cc.where "before" &&
1156         git config trailer.cc.ifMissing "add" &&
1157         cat complex_message_body >expected &&
1158         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1159                 Cc: Linus
1160                 Bug #42
1161                 Fixes: Z
1162                 Acked-by= Z
1163                 Acked-by= Junio
1164                 Acked-by= Peff
1165                 Reviewed-by:
1166                 Signed-off-by: Z
1167         EOF
1168         git interpret-trailers --trailer "review:" --trailer "fix=53" \
1169                 --trailer "ack: Junio" --trailer "fix=22" \
1170                 --trailer "bug: 42" --trailer "cc=Linus" --trailer "ack: Peff" \
1171                 <complex_message >actual &&
1172         test_cmp expected actual
1173 '
1174
1175 test_expect_success 'using "ifMissing = doNothing"' '
1176         git config trailer.cc.ifMissing "doNothing" &&
1177         cat complex_message_body >expected &&
1178         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1179                 Bug #42
1180                 Fixes: Z
1181                 Acked-by= Z
1182                 Acked-by= Junio
1183                 Acked-by= Peff
1184                 Reviewed-by:
1185                 Signed-off-by: Z
1186         EOF
1187         git interpret-trailers --trailer "review:" --trailer "fix=53" \
1188                 --trailer "cc=Linus" --trailer "ack: Junio" \
1189                 --trailer "fix=22" --trailer "bug: 42" --trailer "ack: Peff" \
1190                 <complex_message >actual &&
1191         test_cmp expected actual
1192 '
1193
1194 test_expect_success 'default "where" is now "after"' '
1195         git config trailer.where "after" &&
1196         git config --unset trailer.ack.where &&
1197         cat complex_message_body >expected &&
1198         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1199                 Bug #42
1200                 Fixes: Z
1201                 Acked-by= Z
1202                 Acked-by= Peff
1203                 Acked-by= Peff
1204                 Acked-by= Junio
1205                 Acked-by= Peff
1206                 Reviewed-by:
1207                 Signed-off-by: Z
1208                 Tested-by: Jakub
1209                 Tested-by: Johannes
1210         EOF
1211         git interpret-trailers --trailer "ack: Peff" \
1212                 --trailer "Acked-by= Peff" --trailer "review:" \
1213                 --trailer "Tested-by: Jakub" --trailer "ack: Junio" \
1214                 --trailer "bug: 42" --trailer "Tested-by: Johannes" \
1215                 --trailer "ack: Peff" <complex_message >actual &&
1216         test_cmp expected actual
1217 '
1218
1219 test_expect_success 'with simple command' '
1220         git config trailer.sign.key "Signed-off-by: " &&
1221         git config trailer.sign.where "after" &&
1222         git config trailer.sign.ifExists "addIfDifferentNeighbor" &&
1223         git config trailer.sign.command "echo \"A U Thor <author@example.com>\"" &&
1224         cat complex_message_body >expected &&
1225         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1226                 Fixes: Z
1227                 Acked-by= Z
1228                 Reviewed-by:
1229                 Signed-off-by: Z
1230                 Signed-off-by: A U Thor <author@example.com>
1231         EOF
1232         git interpret-trailers --trailer "review:" --trailer "fix=22" \
1233                 <complex_message >actual &&
1234         test_cmp expected actual
1235 '
1236
1237 test_expect_success 'with command using commiter information' '
1238         git config trailer.sign.ifExists "addIfDifferent" &&
1239         git config trailer.sign.command "echo \"\$GIT_COMMITTER_NAME <\$GIT_COMMITTER_EMAIL>\"" &&
1240         cat complex_message_body >expected &&
1241         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1242                 Fixes: Z
1243                 Acked-by= Z
1244                 Reviewed-by:
1245                 Signed-off-by: Z
1246                 Signed-off-by: C O Mitter <committer@example.com>
1247         EOF
1248         git interpret-trailers --trailer "review:" --trailer "fix=22" \
1249                 <complex_message >actual &&
1250         test_cmp expected actual
1251 '
1252
1253 test_expect_success 'with command using author information' '
1254         git config trailer.sign.key "Signed-off-by: " &&
1255         git config trailer.sign.where "after" &&
1256         git config trailer.sign.ifExists "addIfDifferentNeighbor" &&
1257         git config trailer.sign.command "echo \"\$GIT_AUTHOR_NAME <\$GIT_AUTHOR_EMAIL>\"" &&
1258         cat complex_message_body >expected &&
1259         sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1260                 Fixes: Z
1261                 Acked-by= Z
1262                 Reviewed-by:
1263                 Signed-off-by: Z
1264                 Signed-off-by: A U Thor <author@example.com>
1265         EOF
1266         git interpret-trailers --trailer "review:" --trailer "fix=22" \
1267                 <complex_message >actual &&
1268         test_cmp expected actual
1269 '
1270
1271 test_expect_success 'setup a commit' '
1272         echo "Content of the first commit." > a.txt &&
1273         git add a.txt &&
1274         git commit -m "Add file a.txt"
1275 '
1276
1277 test_expect_success 'with command using $ARG' '
1278         git config trailer.fix.ifExists "replace" &&
1279         git config trailer.fix.command "git log -1 --oneline --format=\"%h (%s)\" --abbrev-commit --abbrev=14 \$ARG" &&
1280         FIXED=$(git log -1 --oneline --format="%h (%s)" --abbrev-commit --abbrev=14 HEAD) &&
1281         cat complex_message_body >expected &&
1282         sed -e "s/ Z\$/ /" >>expected <<-EOF &&
1283                 Fixes: $FIXED
1284                 Acked-by= Z
1285                 Reviewed-by:
1286                 Signed-off-by: Z
1287                 Signed-off-by: A U Thor <author@example.com>
1288         EOF
1289         git interpret-trailers --trailer "review:" --trailer "fix=HEAD" \
1290                 <complex_message >actual &&
1291         test_cmp expected actual
1292 '
1293
1294 test_expect_success 'with failing command using $ARG' '
1295         git config trailer.fix.ifExists "replace" &&
1296         git config trailer.fix.command "false \$ARG" &&
1297         cat complex_message_body >expected &&
1298         sed -e "s/ Z\$/ /" >>expected <<-EOF &&
1299                 Fixes: Z
1300                 Acked-by= Z
1301                 Reviewed-by:
1302                 Signed-off-by: Z
1303                 Signed-off-by: A U Thor <author@example.com>
1304         EOF
1305         git interpret-trailers --trailer "review:" --trailer "fix=HEAD" \
1306                 <complex_message >actual &&
1307         test_cmp expected actual
1308 '
1309
1310 test_expect_success 'with empty tokens' '
1311         git config --unset trailer.fix.command &&
1312         cat >expected <<-EOF &&
1313
1314                 Signed-off-by: A U Thor <author@example.com>
1315         EOF
1316         git interpret-trailers --trailer ":" --trailer ":test" >actual <<-EOF &&
1317         EOF
1318         test_cmp expected actual
1319 '
1320
1321 test_expect_success 'with command but no key' '
1322         git config --unset trailer.sign.key &&
1323         cat >expected <<-EOF &&
1324
1325                 sign: A U Thor <author@example.com>
1326         EOF
1327         git interpret-trailers >actual <<-EOF &&
1328         EOF
1329         test_cmp expected actual
1330 '
1331
1332 test_expect_success 'with no command and no key' '
1333         git config --unset trailer.review.key &&
1334         cat >expected <<-EOF &&
1335
1336                 review: Junio
1337                 sign: A U Thor <author@example.com>
1338         EOF
1339         git interpret-trailers --trailer "review:Junio" >actual <<-EOF &&
1340         EOF
1341         test_cmp expected actual
1342 '
1343
1344 test_expect_success 'with cut line' '
1345         cat >expected <<-\EOF &&
1346                 my subject
1347
1348                 review: Brian
1349                 sign: A U Thor <author@example.com>
1350                 # ------------------------ >8 ------------------------
1351                 ignore this
1352         EOF
1353         git interpret-trailers --trailer review:Brian >actual <<-\EOF &&
1354                 my subject
1355                 # ------------------------ >8 ------------------------
1356                 ignore this
1357         EOF
1358         test_cmp expected actual
1359 '
1360
1361 test_expect_success 'only trailers' '
1362         git config trailer.sign.command "echo config-value" &&
1363         cat >expected <<-\EOF &&
1364                 existing: existing-value
1365                 sign: config-value
1366                 added: added-value
1367         EOF
1368         git interpret-trailers \
1369                 --trailer added:added-value \
1370                 --only-trailers >actual <<-\EOF &&
1371                 my subject
1372
1373                 my body
1374
1375                 existing: existing-value
1376         EOF
1377         test_cmp expected actual
1378 '
1379
1380 test_expect_success 'only-trailers omits non-trailer in middle of block' '
1381         git config trailer.sign.command "echo config-value" &&
1382         cat >expected <<-\EOF &&
1383                 Signed-off-by: nobody <nobody@nowhere>
1384                 Signed-off-by: somebody <somebody@somewhere>
1385                 sign: config-value
1386         EOF
1387         git interpret-trailers --only-trailers >actual <<-\EOF &&
1388                 subject
1389
1390                 it is important that the trailers below are signed-off-by
1391                 so that they meet the "25% trailers Git knows about" heuristic
1392
1393                 Signed-off-by: nobody <nobody@nowhere>
1394                 this is not a trailer
1395                 Signed-off-by: somebody <somebody@somewhere>
1396         EOF
1397         test_cmp expected actual
1398 '
1399
1400 test_expect_success 'only input' '
1401         git config trailer.sign.command "echo config-value" &&
1402         cat >expected <<-\EOF &&
1403                 existing: existing-value
1404         EOF
1405         git interpret-trailers \
1406                 --only-trailers --only-input >actual <<-\EOF &&
1407                 my subject
1408
1409                 my body
1410
1411                 existing: existing-value
1412         EOF
1413         test_cmp expected actual
1414 '
1415
1416 test_expect_success 'unfold' '
1417         cat >expected <<-\EOF &&
1418                 foo: continued across several lines
1419         EOF
1420         # pass through tr to make leading and trailing whitespace more obvious
1421         tr _ " " <<-\EOF |
1422                 my subject
1423
1424                 my body
1425
1426                 foo:_
1427                 __continued
1428                 ___across
1429                 ____several
1430                 _____lines
1431                 ___
1432         EOF
1433         git interpret-trailers --only-trailers --only-input --unfold >actual &&
1434         test_cmp expected actual
1435 '
1436
1437 test_expect_success 'handling of --- lines in input' '
1438         echo "real-trailer: just right" >expected &&
1439
1440         git interpret-trailers --parse >actual <<-\EOF &&
1441         subject
1442
1443         body
1444
1445         not-a-trailer: too soon
1446         ------ this is just a line in the commit message with a bunch of
1447         ------ dashes; it does not have any syntactic meaning.
1448
1449         real-trailer: just right
1450         ---
1451         below the dashed line may be a patch, etc.
1452
1453         not-a-trailer: too late
1454         EOF
1455
1456         test_cmp expected actual
1457 '
1458
1459 test_expect_success 'suppress --- handling' '
1460         echo "real-trailer: just right" >expected &&
1461
1462         git interpret-trailers --parse --no-divider >actual <<-\EOF &&
1463         subject
1464
1465         This commit message has a "---" in it, but because we tell
1466         interpret-trailers not to respect that, it has no effect.
1467
1468         not-a-trailer: too soon
1469         ---
1470
1471         This is still the commit message body.
1472
1473         real-trailer: just right
1474         EOF
1475
1476         test_cmp expected actual
1477 '
1478
1479 test_done