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_PATH" -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 test_config format.thread true &&
461 check_threading expect.thread master
462'
463
464test_expect_success 'thread deep via config' '
465 test_config format.thread deep &&
466 check_threading expect.deep master
467'
468
469test_expect_success 'thread config + override' '
470 test_config format.thread deep &&
471 check_threading expect.thread --thread master
472'
473
474test_expect_success 'thread config + --no-thread' '
475 test_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
521index 40f36c6..2dc5c23 100644
522--- a/file
523+++ b/file
524@@ -13,4 +13,20 @@ C
525 10
526 D
527 E
528 F
529+5
530EOF
531
532test_expect_success 'format-patch respects -U' '
533
534 git format-patch -U4 -2 &&
535 sed -e "1,/^diff/d" -e "/^+5/q" \
536 <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
537 >output &&
538 test_cmp expect output
539
540'
541
542cat > expect << EOF
543
544diff --git a/file b/file
545index 40f36c6..2dc5c23 100644
546--- a/file
547+++ b/file
548@@ -14,3 +14,19 @@ C
549 D
550 E
551 F
552+5
553EOF
554
555test_expect_success 'format-patch -p suppresses stat' '
556
557 git format-patch -p -2 &&
558 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
559 test_cmp expect output
560
561'
562
563test_expect_success 'format-patch from a subdirectory (1)' '
564 filename=$(
565 rm -rf sub &&
566 mkdir -p sub/dir &&
567 cd sub/dir &&
568 git format-patch -1
569 ) &&
570 case "$filename" in
571 0*)
572 ;; # ok
573 *)
574 echo "Oops? $filename"
575 false
576 ;;
577 esac &&
578 test -f "$filename"
579'
580
581test_expect_success 'format-patch from a subdirectory (2)' '
582 filename=$(
583 rm -rf sub &&
584 mkdir -p sub/dir &&
585 cd sub/dir &&
586 git format-patch -1 -o ..
587 ) &&
588 case "$filename" in
589 ../0*)
590 ;; # ok
591 *)
592 echo "Oops? $filename"
593 false
594 ;;
595 esac &&
596 basename=$(expr "$filename" : ".*/\(.*\)") &&
597 test -f "sub/$basename"
598'
599
600test_expect_success 'format-patch from a subdirectory (3)' '
601 rm -f 0* &&
602 filename=$(
603 rm -rf sub &&
604 mkdir -p sub/dir &&
605 cd sub/dir &&
606 git format-patch -1 -o "$TRASH_DIRECTORY"
607 ) &&
608 basename=$(expr "$filename" : ".*/\(.*\)") &&
609 test -f "$basename"
610'
611
612test_expect_success 'format-patch --in-reply-to' '
613 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
614 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
615 grep "^References: <baz@foo.bar>" patch8
616'
617
618test_expect_success 'format-patch --signoff' '
619 git format-patch -1 --signoff --stdout >out &&
620 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
621'
622
623test_expect_success 'format-patch --notes --signoff' '
624 git notes --ref test add -m "test message" HEAD &&
625 git format-patch -1 --signoff --stdout --notes=test >out &&
626 # Three dashes must come after S-o-b
627 ! sed "/^Signed-off-by: /q" out | grep "test message" &&
628 sed "1,/^Signed-off-by: /d" out | grep "test message" &&
629 # Notes message must come after three dashes
630 ! sed "/^---$/q" out | grep "test message" &&
631 sed "1,/^---$/d" out | grep "test message"
632'
633
634echo "fatal: --name-only does not make sense" > expect.name-only
635echo "fatal: --name-status does not make sense" > expect.name-status
636echo "fatal: --check does not make sense" > expect.check
637
638test_expect_success 'options no longer allowed for format-patch' '
639 test_must_fail git format-patch --name-only 2> output &&
640 test_i18ncmp expect.name-only output &&
641 test_must_fail git format-patch --name-status 2> output &&
642 test_i18ncmp expect.name-status output &&
643 test_must_fail git format-patch --check 2> output &&
644 test_i18ncmp expect.check output'
645
646test_expect_success 'format-patch --numstat should produce a patch' '
647 git format-patch --numstat --stdout master..side > output &&
648 test 6 = $(grep "^diff --git a/" output | wc -l)'
649
650test_expect_success 'format-patch -- <path>' '
651 git format-patch master..side -- file 2>error &&
652 ! grep "Use .--" error
653'
654
655test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
656 git format-patch --ignore-if-in-upstream HEAD
657'
658
659test_expect_success 'format-patch --signature' '
660 git format-patch --stdout --signature="my sig" -1 >output &&
661 grep "my sig" output
662'
663
664test_expect_success 'format-patch with format.signature config' '
665 git config format.signature "config sig" &&
666 git format-patch --stdout -1 >output &&
667 grep "config sig" output
668'
669
670test_expect_success 'format-patch --signature overrides format.signature' '
671 git config format.signature "config sig" &&
672 git format-patch --stdout --signature="overrides" -1 >output &&
673 ! grep "config sig" output &&
674 grep "overrides" output
675'
676
677test_expect_success 'format-patch --no-signature ignores format.signature' '
678 git config format.signature "config sig" &&
679 git format-patch --stdout --signature="my sig" --no-signature \
680 -1 >output &&
681 check_patch output &&
682 ! grep "config sig" output &&
683 ! grep "my sig" output &&
684 ! grep "^-- \$" output
685'
686
687test_expect_success 'format-patch --signature --cover-letter' '
688 git config --unset-all format.signature &&
689 git format-patch --stdout --signature="my sig" --cover-letter \
690 -1 >output &&
691 grep "my sig" output &&
692 test 2 = $(grep "my sig" output | wc -l)
693'
694
695test_expect_success 'format.signature="" supresses signatures' '
696 git config format.signature "" &&
697 git format-patch --stdout -1 >output &&
698 check_patch output &&
699 ! grep "^-- \$" output
700'
701
702test_expect_success 'format-patch --no-signature supresses signatures' '
703 git config --unset-all format.signature &&
704 git format-patch --stdout --no-signature -1 >output &&
705 check_patch output &&
706 ! grep "^-- \$" output
707'
708
709test_expect_success 'format-patch --signature="" supresses signatures' '
710 git format-patch --stdout --signature="" -1 >output &&
711 check_patch output &&
712 ! grep "^-- \$" output
713'
714
715test_expect_success TTY 'format-patch --stdout paginates' '
716 rm -f pager_used &&
717 (
718 GIT_PAGER="wc >pager_used" &&
719 export GIT_PAGER &&
720 test_terminal git format-patch --stdout --all
721 ) &&
722 test_path_is_file pager_used
723'
724
725 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
726 rm -f pager_used &&
727 (
728 GIT_PAGER="wc >pager_used" &&
729 export GIT_PAGER &&
730 test_terminal git --no-pager format-patch --stdout --all &&
731 test_terminal git -c "pager.format-patch=false" format-patch --stdout --all
732 ) &&
733 test_path_is_missing pager_used &&
734 test_path_is_missing .git/pager_used
735'
736
737test_expect_success 'format-patch handles multi-line subjects' '
738 rm -rf patches/ &&
739 echo content >>file &&
740 for i in one two three; do echo $i; done >msg &&
741 git add file &&
742 git commit -F msg &&
743 git format-patch -o patches -1 &&
744 grep ^Subject: patches/0001-one.patch >actual &&
745 echo "Subject: [PATCH] one two three" >expect &&
746 test_cmp expect actual
747'
748
749test_expect_success 'format-patch handles multi-line encoded subjects' '
750 rm -rf patches/ &&
751 echo content >>file &&
752 for i in en två tre; do echo $i; done >msg &&
753 git add file &&
754 git commit -F msg &&
755 git format-patch -o patches -1 &&
756 grep ^Subject: patches/0001-en.patch >actual &&
757 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
758 test_cmp expect actual
759'
760
761M8="foo bar "
762M64=$M8$M8$M8$M8$M8$M8$M8$M8
763M512=$M64$M64$M64$M64$M64$M64$M64$M64
764cat >expect <<'EOF'
765Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
766 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
767 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
768 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
769 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
770 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
771 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
772 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
773 foo bar foo bar foo bar foo bar
774EOF
775test_expect_success 'format-patch wraps extremely long headers (ascii)' '
776 echo content >>file &&
777 git add file &&
778 git commit -m "$M512" &&
779 git format-patch --stdout -1 >patch &&
780 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
781 test_cmp expect subject
782'
783
784M8="föö bar "
785M64=$M8$M8$M8$M8$M8$M8$M8$M8
786M512=$M64$M64$M64$M64$M64$M64$M64$M64
787cat >expect <<'EOF'
788Subject: [PATCH] =?UTF-8?q?f=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=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
802 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
803 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
804 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
805 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
806 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
807 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
808 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
809 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
810EOF
811test_expect_success 'format-patch wraps extremely long headers (rfc2047)' '
812 rm -rf patches/ &&
813 echo content >>file &&
814 git add file &&
815 git commit -m "$M512" &&
816 git format-patch --stdout -1 >patch &&
817 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
818 test_cmp expect subject
819'
820
821M8="foo_bar_"
822M64=$M8$M8$M8$M8$M8$M8$M8$M8
823cat >expect <<EOF
824From: $M64
825 <foobar@foo.bar>
826EOF
827test_expect_success 'format-patch wraps non-quotable headers' '
828 rm -rf patches/ &&
829 echo content >>file &&
830 git add file &&
831 git commit -mfoo --author "$M64 <foobar@foo.bar>" &&
832 git format-patch --stdout -1 >patch &&
833 sed -n "/^From: /p; /^ /p; /^$/q" <patch >from &&
834 test_cmp expect from
835'
836
837check_author() {
838 echo content >>file &&
839 git add file &&
840 GIT_AUTHOR_NAME=$1 git commit -m author-check &&
841 git format-patch --stdout -1 >patch &&
842 grep ^From: patch >actual &&
843 test_cmp expect actual
844}
845
846cat >expect <<'EOF'
847From: "Foo B. Bar" <author@example.com>
848EOF
849test_expect_success 'format-patch quotes dot in headers' '
850 check_author "Foo B. Bar"
851'
852
853cat >expect <<'EOF'
854From: "Foo \"The Baz\" Bar" <author@example.com>
855EOF
856test_expect_success 'format-patch quotes double-quote in headers' '
857 check_author "Foo \"The Baz\" Bar"
858'
859
860cat >expect <<'EOF'
861From: =?UTF-8?q?"F=C3=B6o=20B.=20Bar"?= <author@example.com>
862EOF
863test_expect_success 'rfc2047-encoded headers also double-quote 822 specials' '
864 check_author "Föo B. Bar"
865'
866
867cat >expect <<'EOF'
868Subject: header with . in it
869EOF
870test_expect_success 'subject lines do not have 822 atom-quoting' '
871 echo content >>file &&
872 git add file &&
873 git commit -m "header with . in it" &&
874 git format-patch -k -1 --stdout >patch &&
875 grep ^Subject: patch >actual &&
876 test_cmp expect actual
877'
878
879cat >expect <<'EOF'
880Subject: [PREFIX 1/1] header with . in it
881EOF
882test_expect_success 'subject prefixes have space prepended' '
883 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
884 grep ^Subject: patch >actual &&
885 test_cmp expect actual
886'
887
888cat >expect <<'EOF'
889Subject: [1/1] header with . in it
890EOF
891test_expect_success 'empty subject prefix does not have extra space' '
892 git format-patch -n -1 --stdout --subject-prefix= >patch &&
893 grep ^Subject: patch >actual &&
894 test_cmp expect actual
895'
896
897test_expect_success 'format patch ignores color.ui' '
898 test_unconfig color.ui &&
899 git format-patch --stdout -1 >expect &&
900 test_config color.ui always &&
901 git format-patch --stdout -1 >actual &&
902 test_cmp expect actual
903'
904
905test_done