1#!/bin/sh
2#
3# Copyright (c) 2006 Junio C Hamano
4#
5
6test_description='various format-patch tests'
7
8. ./test-lib.sh
9. "$TEST_DIRECTORY"/lib-terminal.sh
10
11test_expect_success setup '
12
13 for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i"; done >file &&
14 cat file >elif &&
15 git add file elif &&
16 test_tick &&
17 git commit -m Initial &&
18 git checkout -b side &&
19
20 for i in 1 2 5 6 A B C 7 8 9 10; do echo "$i"; done >file &&
21 test_chmod +x elif &&
22 test_tick &&
23 git commit -m "Side changes #1" &&
24
25 for i in D E F; do echo "$i"; done >>file &&
26 git update-index file &&
27 test_tick &&
28 git commit -m "Side changes #2" &&
29 git tag C2 &&
30
31 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file &&
32 git update-index file &&
33 test_tick &&
34 git commit -m "Side changes #3 with \\n backslash-n in it." &&
35
36 git checkout master &&
37 git diff-tree -p C2 | git apply --index &&
38 test_tick &&
39 git commit -m "Master accepts moral equivalent of #2"
40
41'
42
43test_expect_success "format-patch --ignore-if-in-upstream" '
44
45 git format-patch --stdout master..side >patch0 &&
46 cnt=`grep "^From " patch0 | wc -l` &&
47 test $cnt = 3
48
49'
50
51test_expect_success "format-patch --ignore-if-in-upstream" '
52
53 git format-patch --stdout \
54 --ignore-if-in-upstream master..side >patch1 &&
55 cnt=`grep "^From " patch1 | wc -l` &&
56 test $cnt = 2
57
58'
59
60test_expect_success "format-patch doesn't consider merge commits" '
61
62 git checkout -b slave master &&
63 echo "Another line" >>file &&
64 test_tick &&
65 git commit -am "Slave change #1" &&
66 echo "Yet another line" >>file &&
67 test_tick &&
68 git commit -am "Slave change #2" &&
69 git checkout -b merger master &&
70 test_tick &&
71 git merge --no-ff slave &&
72 cnt=`git format-patch -3 --stdout | grep "^From " | wc -l` &&
73 test $cnt = 3
74'
75
76test_expect_success "format-patch result applies" '
77
78 git checkout -b rebuild-0 master &&
79 git am -3 patch0 &&
80 cnt=`git rev-list master.. | wc -l` &&
81 test $cnt = 2
82'
83
84test_expect_success "format-patch --ignore-if-in-upstream result applies" '
85
86 git checkout -b rebuild-1 master &&
87 git am -3 patch1 &&
88 cnt=`git rev-list master.. | wc -l` &&
89 test $cnt = 2
90'
91
92test_expect_success 'commit did not screw up the log message' '
93
94 git cat-file commit side | grep "^Side .* with .* backslash-n"
95
96'
97
98test_expect_success 'format-patch did not screw up the log message' '
99
100 grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
101 grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
102
103'
104
105test_expect_success 'replay did not screw up the log message' '
106
107 git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
108
109'
110
111test_expect_success 'extra headers' '
112
113 git config format.headers "To: R. E. Cipient <rcipient@example.com>
114" &&
115 git config --add format.headers "Cc: S. E. Cipient <scipient@example.com>
116" &&
117 git format-patch --stdout master..side > patch2 &&
118 sed -e "/^\$/q" patch2 > hdrs2 &&
119 grep "^To: R. E. Cipient <rcipient@example.com>\$" hdrs2 &&
120 grep "^Cc: S. E. Cipient <scipient@example.com>\$" hdrs2
121
122'
123
124test_expect_success 'extra headers without newlines' '
125
126 git config --replace-all format.headers "To: R. E. Cipient <rcipient@example.com>" &&
127 git config --add format.headers "Cc: S. E. Cipient <scipient@example.com>" &&
128 git format-patch --stdout master..side >patch3 &&
129 sed -e "/^\$/q" patch3 > hdrs3 &&
130 grep "^To: R. E. Cipient <rcipient@example.com>\$" hdrs3 &&
131 grep "^Cc: S. E. Cipient <scipient@example.com>\$" hdrs3
132
133'
134
135test_expect_success 'extra headers with multiple To:s' '
136
137 git config --replace-all format.headers "To: R. E. Cipient <rcipient@example.com>" &&
138 git config --add format.headers "To: S. E. Cipient <scipient@example.com>" &&
139 git format-patch --stdout master..side > patch4 &&
140 sed -e "/^\$/q" patch4 > hdrs4 &&
141 grep "^To: R. E. Cipient <rcipient@example.com>,\$" hdrs4 &&
142 grep "^ *S. E. Cipient <scipient@example.com>\$" hdrs4
143'
144
145test_expect_success 'additional command line cc' '
146
147 git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" &&
148 git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
149 grep "^Cc: R. E. Cipient <rcipient@example.com>,\$" patch5 &&
150 grep "^ *S. E. Cipient <scipient@example.com>\$" patch5
151'
152
153test_expect_success 'command line headers' '
154
155 git config --unset-all format.headers &&
156 git format-patch --add-header="Cc: R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 &&
157 grep "^Cc: R. E. Cipient <rcipient@example.com>\$" patch6
158'
159
160test_expect_success 'configuration headers and command line headers' '
161
162 git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" &&
163 git format-patch --add-header="Cc: S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 &&
164 grep "^Cc: R. E. Cipient <rcipient@example.com>,\$" patch7 &&
165 grep "^ *S. E. Cipient <scipient@example.com>\$" patch7
166'
167
168test_expect_success 'command line To: header' '
169
170 git config --unset-all format.headers &&
171 git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
172 grep "^To: R. E. Cipient <rcipient@example.com>\$" patch8
173'
174
175test_expect_success 'configuration To: header' '
176
177 git config format.to "R. E. Cipient <rcipient@example.com>" &&
178 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
179 grep "^To: R. E. Cipient <rcipient@example.com>\$" patch9
180'
181
182# check_patch <patch>: Verify that <patch> looks like a half-sane
183# patch email to avoid a false positive with !grep
184check_patch () {
185 grep -e "^From:" "$1" &&
186 grep -e "^Date:" "$1" &&
187 grep -e "^Subject:" "$1"
188}
189
190test_expect_success '--no-to overrides config.to' '
191
192 git config --replace-all format.to \
193 "R. E. Cipient <rcipient@example.com>" &&
194 git format-patch --no-to --stdout master..side |
195 sed -e "/^\$/q" >patch10 &&
196 check_patch patch10 &&
197 ! grep "^To: R. E. Cipient <rcipient@example.com>\$" patch10
198'
199
200test_expect_success '--no-to and --to replaces config.to' '
201
202 git config --replace-all format.to \
203 "Someone <someone@out.there>" &&
204 git format-patch --no-to --to="Someone Else <else@out.there>" \
205 --stdout master..side |
206 sed -e "/^\$/q" >patch11 &&
207 check_patch patch11 &&
208 ! grep "^To: Someone <someone@out.there>\$" patch11 &&
209 grep "^To: Someone Else <else@out.there>\$" patch11
210'
211
212test_expect_success '--no-cc overrides config.cc' '
213
214 git config --replace-all format.cc \
215 "C. E. Cipient <rcipient@example.com>" &&
216 git format-patch --no-cc --stdout master..side |
217 sed -e "/^\$/q" >patch12 &&
218 check_patch patch12 &&
219 ! grep "^Cc: C. E. Cipient <rcipient@example.com>\$" patch12
220'
221
222test_expect_success '--no-add-header overrides config.headers' '
223
224 git config --replace-all format.headers \
225 "Header1: B. E. Cipient <rcipient@example.com>" &&
226 git format-patch --no-add-header --stdout master..side |
227 sed -e "/^\$/q" >patch13 &&
228 check_patch patch13 &&
229 ! grep "^Header1: B. E. Cipient <rcipient@example.com>\$" patch13
230'
231
232test_expect_success 'multiple files' '
233
234 rm -rf patches/ &&
235 git checkout side &&
236 git format-patch -o patches/ master &&
237 ls patches/0001-Side-changes-1.patch patches/0002-Side-changes-2.patch patches/0003-Side-changes-3-with-n-backslash-n-in-it.patch
238'
239
240check_threading () {
241 expect="$1" &&
242 shift &&
243 (git format-patch --stdout "$@"; echo $? > status.out) |
244 # Prints everything between the Message-ID and In-Reply-To,
245 # and replaces all Message-ID-lookalikes by a sequence number
246 perl -ne '
247 if (/^(message-id|references|in-reply-to)/i) {
248 $printing = 1;
249 } elsif (/^\S/) {
250 $printing = 0;
251 }
252 if ($printing) {
253 $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
254 for $k (keys %h) {s/$k/$h{$k}/};
255 print;
256 }
257 print "---\n" if /^From /i;
258 ' > actual &&
259 test 0 = "$(cat status.out)" &&
260 test_cmp "$expect" actual
261}
262
263cat >> expect.no-threading <<EOF
264---
265---
266---
267EOF
268
269test_expect_success 'no threading' '
270 git checkout side &&
271 check_threading expect.no-threading master
272'
273
274cat > expect.thread <<EOF
275---
276Message-Id: <0>
277---
278Message-Id: <1>
279In-Reply-To: <0>
280References: <0>
281---
282Message-Id: <2>
283In-Reply-To: <0>
284References: <0>
285EOF
286
287test_expect_success 'thread' '
288 check_threading expect.thread --thread master
289'
290
291cat > expect.in-reply-to <<EOF
292---
293Message-Id: <0>
294In-Reply-To: <1>
295References: <1>
296---
297Message-Id: <2>
298In-Reply-To: <1>
299References: <1>
300---
301Message-Id: <3>
302In-Reply-To: <1>
303References: <1>
304EOF
305
306test_expect_success 'thread in-reply-to' '
307 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
308 --thread master
309'
310
311cat > expect.cover-letter <<EOF
312---
313Message-Id: <0>
314---
315Message-Id: <1>
316In-Reply-To: <0>
317References: <0>
318---
319Message-Id: <2>
320In-Reply-To: <0>
321References: <0>
322---
323Message-Id: <3>
324In-Reply-To: <0>
325References: <0>
326EOF
327
328test_expect_success 'thread cover-letter' '
329 check_threading expect.cover-letter --cover-letter --thread master
330'
331
332cat > expect.cl-irt <<EOF
333---
334Message-Id: <0>
335In-Reply-To: <1>
336References: <1>
337---
338Message-Id: <2>
339In-Reply-To: <0>
340References: <1>
341 <0>
342---
343Message-Id: <3>
344In-Reply-To: <0>
345References: <1>
346 <0>
347---
348Message-Id: <4>
349In-Reply-To: <0>
350References: <1>
351 <0>
352EOF
353
354test_expect_success 'thread cover-letter in-reply-to' '
355 check_threading expect.cl-irt --cover-letter \
356 --in-reply-to="<test.message>" --thread master
357'
358
359test_expect_success 'thread explicit shallow' '
360 check_threading expect.cl-irt --cover-letter \
361 --in-reply-to="<test.message>" --thread=shallow master
362'
363
364cat > expect.deep <<EOF
365---
366Message-Id: <0>
367---
368Message-Id: <1>
369In-Reply-To: <0>
370References: <0>
371---
372Message-Id: <2>
373In-Reply-To: <1>
374References: <0>
375 <1>
376EOF
377
378test_expect_success 'thread deep' '
379 check_threading expect.deep --thread=deep master
380'
381
382cat > expect.deep-irt <<EOF
383---
384Message-Id: <0>
385In-Reply-To: <1>
386References: <1>
387---
388Message-Id: <2>
389In-Reply-To: <0>
390References: <1>
391 <0>
392---
393Message-Id: <3>
394In-Reply-To: <2>
395References: <1>
396 <0>
397 <2>
398EOF
399
400test_expect_success 'thread deep in-reply-to' '
401 check_threading expect.deep-irt --thread=deep \
402 --in-reply-to="<test.message>" master
403'
404
405cat > expect.deep-cl <<EOF
406---
407Message-Id: <0>
408---
409Message-Id: <1>
410In-Reply-To: <0>
411References: <0>
412---
413Message-Id: <2>
414In-Reply-To: <1>
415References: <0>
416 <1>
417---
418Message-Id: <3>
419In-Reply-To: <2>
420References: <0>
421 <1>
422 <2>
423EOF
424
425test_expect_success 'thread deep cover-letter' '
426 check_threading expect.deep-cl --cover-letter --thread=deep master
427'
428
429cat > expect.deep-cl-irt <<EOF
430---
431Message-Id: <0>
432In-Reply-To: <1>
433References: <1>
434---
435Message-Id: <2>
436In-Reply-To: <0>
437References: <1>
438 <0>
439---
440Message-Id: <3>
441In-Reply-To: <2>
442References: <1>
443 <0>
444 <2>
445---
446Message-Id: <4>
447In-Reply-To: <3>
448References: <1>
449 <0>
450 <2>
451 <3>
452EOF
453
454test_expect_success 'thread deep cover-letter in-reply-to' '
455 check_threading expect.deep-cl-irt --cover-letter \
456 --in-reply-to="<test.message>" --thread=deep master
457'
458
459test_expect_success 'thread via config' '
460 git config format.thread true &&
461 check_threading expect.thread master
462'
463
464test_expect_success 'thread deep via config' '
465 git config format.thread deep &&
466 check_threading expect.deep master
467'
468
469test_expect_success 'thread config + override' '
470 git config format.thread deep &&
471 check_threading expect.thread --thread master
472'
473
474test_expect_success 'thread config + --no-thread' '
475 git config format.thread deep &&
476 check_threading expect.no-threading --no-thread master
477'
478
479test_expect_success 'excessive subject' '
480
481 rm -rf patches/ &&
482 git checkout side &&
483 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
484 git update-index file &&
485 git commit -m "This is an excessively long subject line for a message due to the habit some projects have of not having a short, one-line subject at the start of the commit message, but rather sticking a whole paragraph right at the start as the only thing in the commit message. It had better not become the filename for the patch." &&
486 git format-patch -o patches/ master..side &&
487 ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
488'
489
490test_expect_success 'cover-letter inherits diff options' '
491
492 git mv file foo &&
493 git commit -m foo &&
494 git format-patch --cover-letter -1 &&
495 check_patch 0000-cover-letter.patch &&
496 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
497 git format-patch --cover-letter -1 -M &&
498 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
499
500'
501
502cat > expect << EOF
503 This is an excessively long subject line for a message due to the
504 habit some projects have of not having a short, one-line subject at
505 the start of the commit message, but rather sticking a whole
506 paragraph right at the start as the only thing in the commit
507 message. It had better not become the filename for the patch.
508 foo
509
510EOF
511
512test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
513
514 git format-patch --cover-letter -2 &&
515 sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
516 test_cmp expect output
517
518'
519
520cat > expect << EOF
521---
522 file | 16 ++++++++++++++++
523 1 files changed, 16 insertions(+), 0 deletions(-)
524
525diff --git a/file b/file
526index 40f36c6..2dc5c23 100644
527--- a/file
528+++ b/file
529@@ -13,4 +13,20 @@ C
530 10
531 D
532 E
533 F
534+5
535EOF
536
537test_expect_success 'format-patch respects -U' '
538
539 git format-patch -U4 -2 &&
540 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
541 test_cmp expect output
542
543'
544
545cat > expect << EOF
546
547diff --git a/file b/file
548index 40f36c6..2dc5c23 100644
549--- a/file
550+++ b/file
551@@ -14,3 +14,19 @@ C
552 D
553 E
554 F
555+5
556EOF
557
558test_expect_success 'format-patch -p suppresses stat' '
559
560 git format-patch -p -2 &&
561 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
562 test_cmp expect output
563
564'
565
566test_expect_success 'format-patch from a subdirectory (1)' '
567 filename=$(
568 rm -rf sub &&
569 mkdir -p sub/dir &&
570 cd sub/dir &&
571 git format-patch -1
572 ) &&
573 case "$filename" in
574 0*)
575 ;; # ok
576 *)
577 echo "Oops? $filename"
578 false
579 ;;
580 esac &&
581 test -f "$filename"
582'
583
584test_expect_success 'format-patch from a subdirectory (2)' '
585 filename=$(
586 rm -rf sub &&
587 mkdir -p sub/dir &&
588 cd sub/dir &&
589 git format-patch -1 -o ..
590 ) &&
591 case "$filename" in
592 ../0*)
593 ;; # ok
594 *)
595 echo "Oops? $filename"
596 false
597 ;;
598 esac &&
599 basename=$(expr "$filename" : ".*/\(.*\)") &&
600 test -f "sub/$basename"
601'
602
603test_expect_success 'format-patch from a subdirectory (3)' '
604 rm -f 0* &&
605 filename=$(
606 rm -rf sub &&
607 mkdir -p sub/dir &&
608 cd sub/dir &&
609 git format-patch -1 -o "$TRASH_DIRECTORY"
610 ) &&
611 basename=$(expr "$filename" : ".*/\(.*\)") &&
612 test -f "$basename"
613'
614
615test_expect_success 'format-patch --in-reply-to' '
616 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
617 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
618 grep "^References: <baz@foo.bar>" patch8
619'
620
621test_expect_success 'format-patch --signoff' '
622 git format-patch -1 --signoff --stdout |
623 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
624'
625
626echo "fatal: --name-only does not make sense" > expect.name-only
627echo "fatal: --name-status does not make sense" > expect.name-status
628echo "fatal: --check does not make sense" > expect.check
629
630test_expect_success 'options no longer allowed for format-patch' '
631 test_must_fail git format-patch --name-only 2> output &&
632 test_i18ncmp expect.name-only output &&
633 test_must_fail git format-patch --name-status 2> output &&
634 test_i18ncmp expect.name-status output &&
635 test_must_fail git format-patch --check 2> output &&
636 test_i18ncmp expect.check output'
637
638test_expect_success 'format-patch --numstat should produce a patch' '
639 git format-patch --numstat --stdout master..side > output &&
640 test 6 = $(grep "^diff --git a/" output | wc -l)'
641
642test_expect_success 'format-patch -- <path>' '
643 git format-patch master..side -- file 2>error &&
644 ! grep "Use .--" error
645'
646
647test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
648 git format-patch --ignore-if-in-upstream HEAD
649'
650
651test_expect_success 'format-patch --signature' '
652 git format-patch --stdout --signature="my sig" -1 >output &&
653 grep "my sig" output
654'
655
656test_expect_success 'format-patch with format.signature config' '
657 git config format.signature "config sig" &&
658 git format-patch --stdout -1 >output &&
659 grep "config sig" output
660'
661
662test_expect_success 'format-patch --signature overrides format.signature' '
663 git config format.signature "config sig" &&
664 git format-patch --stdout --signature="overrides" -1 >output &&
665 ! grep "config sig" output &&
666 grep "overrides" output
667'
668
669test_expect_success 'format-patch --no-signature ignores format.signature' '
670 git config format.signature "config sig" &&
671 git format-patch --stdout --signature="my sig" --no-signature \
672 -1 >output &&
673 check_patch output &&
674 ! grep "config sig" output &&
675 ! grep "my sig" output &&
676 ! grep "^-- \$" output
677'
678
679test_expect_success 'format-patch --signature --cover-letter' '
680 git config --unset-all format.signature &&
681 git format-patch --stdout --signature="my sig" --cover-letter \
682 -1 >output &&
683 grep "my sig" output &&
684 test 2 = $(grep "my sig" output | wc -l)
685'
686
687test_expect_success 'format.signature="" supresses signatures' '
688 git config format.signature "" &&
689 git format-patch --stdout -1 >output &&
690 check_patch output &&
691 ! grep "^-- \$" output
692'
693
694test_expect_success 'format-patch --no-signature supresses signatures' '
695 git config --unset-all format.signature &&
696 git format-patch --stdout --no-signature -1 >output &&
697 check_patch output &&
698 ! grep "^-- \$" output
699'
700
701test_expect_success 'format-patch --signature="" supresses signatures' '
702 git format-patch --stdout --signature="" -1 >output &&
703 check_patch output &&
704 ! grep "^-- \$" output
705'
706
707test_expect_success TTY 'format-patch --stdout paginates' '
708 rm -f pager_used &&
709 (
710 GIT_PAGER="wc >pager_used" &&
711 export GIT_PAGER &&
712 test_terminal git format-patch --stdout --all
713 ) &&
714 test_path_is_file pager_used
715'
716
717 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
718 rm -f pager_used &&
719 (
720 GIT_PAGER="wc >pager_used" &&
721 export GIT_PAGER &&
722 test_terminal git --no-pager format-patch --stdout --all &&
723 test_terminal git -c "pager.format-patch=false" format-patch --stdout --all
724 ) &&
725 test_path_is_missing pager_used &&
726 test_path_is_missing .git/pager_used
727'
728
729test_expect_success 'format-patch handles multi-line subjects' '
730 rm -rf patches/ &&
731 echo content >>file &&
732 for i in one two three; do echo $i; done >msg &&
733 git add file &&
734 git commit -F msg &&
735 git format-patch -o patches -1 &&
736 grep ^Subject: patches/0001-one.patch >actual &&
737 echo "Subject: [PATCH] one two three" >expect &&
738 test_cmp expect actual
739'
740
741test_expect_success 'format-patch handles multi-line encoded subjects' '
742 rm -rf patches/ &&
743 echo content >>file &&
744 for i in en två tre; do echo $i; done >msg &&
745 git add file &&
746 git commit -F msg &&
747 git format-patch -o patches -1 &&
748 grep ^Subject: patches/0001-en.patch >actual &&
749 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
750 test_cmp expect actual
751'
752
753M8="foo bar "
754M64=$M8$M8$M8$M8$M8$M8$M8$M8
755M512=$M64$M64$M64$M64$M64$M64$M64$M64
756cat >expect <<'EOF'
757Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
758 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
759 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
760 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
761 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
762 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
763 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
764 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
765 foo bar foo bar foo bar foo bar
766EOF
767test_expect_success 'format-patch wraps extremely long headers (ascii)' '
768 echo content >>file &&
769 git add file &&
770 git commit -m "$M512" &&
771 git format-patch --stdout -1 >patch &&
772 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
773 test_cmp expect subject
774'
775
776M8="föö bar "
777M64=$M8$M8$M8$M8$M8$M8$M8$M8
778M512=$M64$M64$M64$M64$M64$M64$M64$M64
779cat >expect <<'EOF'
780Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
781 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
782 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
783 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
784 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
785 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
786 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
787 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
788 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
789 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
790 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
791 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
792 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
793 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
794 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
795 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
796 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
797 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
798 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
799 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
800 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
801 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
802EOF
803test_expect_success 'format-patch wraps extremely long headers (rfc2047)' '
804 rm -rf patches/ &&
805 echo content >>file &&
806 git add file &&
807 git commit -m "$M512" &&
808 git format-patch --stdout -1 >patch &&
809 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
810 test_cmp expect subject
811'
812
813M8="foo_bar_"
814M64=$M8$M8$M8$M8$M8$M8$M8$M8
815cat >expect <<EOF
816From: $M64
817 <foobar@foo.bar>
818EOF
819test_expect_success 'format-patch wraps non-quotable headers' '
820 rm -rf patches/ &&
821 echo content >>file &&
822 git add file &&
823 git commit -mfoo --author "$M64 <foobar@foo.bar>" &&
824 git format-patch --stdout -1 >patch &&
825 sed -n "/^From: /p; /^ /p; /^$/q" <patch >from &&
826 test_cmp expect from
827'
828
829check_author() {
830 echo content >>file &&
831 git add file &&
832 GIT_AUTHOR_NAME=$1 git commit -m author-check &&
833 git format-patch --stdout -1 >patch &&
834 grep ^From: patch >actual &&
835 test_cmp expect actual
836}
837
838cat >expect <<'EOF'
839From: "Foo B. Bar" <author@example.com>
840EOF
841test_expect_success 'format-patch quotes dot in headers' '
842 check_author "Foo B. Bar"
843'
844
845cat >expect <<'EOF'
846From: "Foo \"The Baz\" Bar" <author@example.com>
847EOF
848test_expect_success 'format-patch quotes double-quote in headers' '
849 check_author "Foo \"The Baz\" Bar"
850'
851
852cat >expect <<'EOF'
853From: =?UTF-8?q?"F=C3=B6o=20B.=20Bar"?= <author@example.com>
854EOF
855test_expect_success 'rfc2047-encoded headers also double-quote 822 specials' '
856 check_author "Föo B. Bar"
857'
858
859cat >expect <<'EOF'
860Subject: header with . in it
861EOF
862test_expect_success 'subject lines do not have 822 atom-quoting' '
863 echo content >>file &&
864 git add file &&
865 git commit -m "header with . in it" &&
866 git format-patch -k -1 --stdout >patch &&
867 grep ^Subject: patch >actual &&
868 test_cmp expect actual
869'
870
871cat >expect <<'EOF'
872Subject: [PREFIX 1/1] header with . in it
873EOF
874test_expect_success 'subject prefixes have space prepended' '
875 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
876 grep ^Subject: patch >actual &&
877 test_cmp expect actual
878'
879
880cat >expect <<'EOF'
881Subject: [1/1] header with . in it
882EOF
883test_expect_success 'empty subject prefix does not have extra space' '
884 git format-patch -n -1 --stdout --subject-prefix= >patch &&
885 grep ^Subject: patch >actual &&
886 test_cmp expect actual
887'
888
889test_done