1#!/bin/sh
2#
3# Copyright (c) 2013, 2014 Christian Couder
4#
5
6test_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
13test_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
54test_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
66test_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
78test_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
90test_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
102test_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
115test_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
129test_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
149test_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
169test_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
190test_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
212test_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
229test_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
244test_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
259test_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
289test_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
310test_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
329test_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
386test_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
428test_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
442test_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
457test_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
471test_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
492test_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
503test_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
510test_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
520test_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
533test_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
541test_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
569test_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
599test_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
614test_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
628test_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
638test_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
651test_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
655test_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
660test_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
668test_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
684test_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
699test_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
714test_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
730test_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
749test_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
768test_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
786test_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
800test_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
818test_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
836test_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
854test_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
872test_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
895test_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
917test_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
933test_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
958test_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
980test_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
997test_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
1017test_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
1036test_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
1055test_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
1076test_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
1095test_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
1114test_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
1136test_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
1158test_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
1177test_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
1202test_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
1220test_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
1236test_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
1254test_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
1260test_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
1277test_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
1293test_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
1304test_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
1315test_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
1327test_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
1344test_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
1363test_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
1383test_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
1399test_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
1420test_done