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
240test_expect_success 'reroll count' '
241 rm -fr patches &&
242 git format-patch -o patches --cover-letter --reroll-count 4 master..side >list &&
243 ! grep -v "^patches/v4-000[0-3]-" list &&
244 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
245 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
246'
247
248test_expect_success 'reroll count (-v)' '
249 rm -fr patches &&
250 git format-patch -o patches --cover-letter -v4 master..side >list &&
251 ! grep -v "^patches/v4-000[0-3]-" list &&
252 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
253 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
254'
255
256check_threading () {
257 expect="$1" &&
258 shift &&
259 (git format-patch --stdout "$@"; echo $? > status.out) |
260 # Prints everything between the Message-ID and In-Reply-To,
261 # and replaces all Message-ID-lookalikes by a sequence number
262 "$PERL_PATH" -ne '
263 if (/^(message-id|references|in-reply-to)/i) {
264 $printing = 1;
265 } elsif (/^\S/) {
266 $printing = 0;
267 }
268 if ($printing) {
269 $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
270 for $k (keys %h) {s/$k/$h{$k}/};
271 print;
272 }
273 print "---\n" if /^From /i;
274 ' > actual &&
275 test 0 = "$(cat status.out)" &&
276 test_cmp "$expect" actual
277}
278
279cat >> expect.no-threading <<EOF
280---
281---
282---
283EOF
284
285test_expect_success 'no threading' '
286 git checkout side &&
287 check_threading expect.no-threading master
288'
289
290cat > expect.thread <<EOF
291---
292Message-Id: <0>
293---
294Message-Id: <1>
295In-Reply-To: <0>
296References: <0>
297---
298Message-Id: <2>
299In-Reply-To: <0>
300References: <0>
301EOF
302
303test_expect_success 'thread' '
304 check_threading expect.thread --thread master
305'
306
307cat > expect.in-reply-to <<EOF
308---
309Message-Id: <0>
310In-Reply-To: <1>
311References: <1>
312---
313Message-Id: <2>
314In-Reply-To: <1>
315References: <1>
316---
317Message-Id: <3>
318In-Reply-To: <1>
319References: <1>
320EOF
321
322test_expect_success 'thread in-reply-to' '
323 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
324 --thread master
325'
326
327cat > expect.cover-letter <<EOF
328---
329Message-Id: <0>
330---
331Message-Id: <1>
332In-Reply-To: <0>
333References: <0>
334---
335Message-Id: <2>
336In-Reply-To: <0>
337References: <0>
338---
339Message-Id: <3>
340In-Reply-To: <0>
341References: <0>
342EOF
343
344test_expect_success 'thread cover-letter' '
345 check_threading expect.cover-letter --cover-letter --thread master
346'
347
348cat > expect.cl-irt <<EOF
349---
350Message-Id: <0>
351In-Reply-To: <1>
352References: <1>
353---
354Message-Id: <2>
355In-Reply-To: <0>
356References: <1>
357 <0>
358---
359Message-Id: <3>
360In-Reply-To: <0>
361References: <1>
362 <0>
363---
364Message-Id: <4>
365In-Reply-To: <0>
366References: <1>
367 <0>
368EOF
369
370test_expect_success 'thread cover-letter in-reply-to' '
371 check_threading expect.cl-irt --cover-letter \
372 --in-reply-to="<test.message>" --thread master
373'
374
375test_expect_success 'thread explicit shallow' '
376 check_threading expect.cl-irt --cover-letter \
377 --in-reply-to="<test.message>" --thread=shallow master
378'
379
380cat > expect.deep <<EOF
381---
382Message-Id: <0>
383---
384Message-Id: <1>
385In-Reply-To: <0>
386References: <0>
387---
388Message-Id: <2>
389In-Reply-To: <1>
390References: <0>
391 <1>
392EOF
393
394test_expect_success 'thread deep' '
395 check_threading expect.deep --thread=deep master
396'
397
398cat > expect.deep-irt <<EOF
399---
400Message-Id: <0>
401In-Reply-To: <1>
402References: <1>
403---
404Message-Id: <2>
405In-Reply-To: <0>
406References: <1>
407 <0>
408---
409Message-Id: <3>
410In-Reply-To: <2>
411References: <1>
412 <0>
413 <2>
414EOF
415
416test_expect_success 'thread deep in-reply-to' '
417 check_threading expect.deep-irt --thread=deep \
418 --in-reply-to="<test.message>" master
419'
420
421cat > expect.deep-cl <<EOF
422---
423Message-Id: <0>
424---
425Message-Id: <1>
426In-Reply-To: <0>
427References: <0>
428---
429Message-Id: <2>
430In-Reply-To: <1>
431References: <0>
432 <1>
433---
434Message-Id: <3>
435In-Reply-To: <2>
436References: <0>
437 <1>
438 <2>
439EOF
440
441test_expect_success 'thread deep cover-letter' '
442 check_threading expect.deep-cl --cover-letter --thread=deep master
443'
444
445cat > expect.deep-cl-irt <<EOF
446---
447Message-Id: <0>
448In-Reply-To: <1>
449References: <1>
450---
451Message-Id: <2>
452In-Reply-To: <0>
453References: <1>
454 <0>
455---
456Message-Id: <3>
457In-Reply-To: <2>
458References: <1>
459 <0>
460 <2>
461---
462Message-Id: <4>
463In-Reply-To: <3>
464References: <1>
465 <0>
466 <2>
467 <3>
468EOF
469
470test_expect_success 'thread deep cover-letter in-reply-to' '
471 check_threading expect.deep-cl-irt --cover-letter \
472 --in-reply-to="<test.message>" --thread=deep master
473'
474
475test_expect_success 'thread via config' '
476 test_config format.thread true &&
477 check_threading expect.thread master
478'
479
480test_expect_success 'thread deep via config' '
481 test_config format.thread deep &&
482 check_threading expect.deep master
483'
484
485test_expect_success 'thread config + override' '
486 test_config format.thread deep &&
487 check_threading expect.thread --thread master
488'
489
490test_expect_success 'thread config + --no-thread' '
491 test_config format.thread deep &&
492 check_threading expect.no-threading --no-thread master
493'
494
495test_expect_success 'excessive subject' '
496
497 rm -rf patches/ &&
498 git checkout side &&
499 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
500 git update-index file &&
501 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." &&
502 git format-patch -o patches/ master..side &&
503 ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
504'
505
506test_expect_success 'cover-letter inherits diff options' '
507
508 git mv file foo &&
509 git commit -m foo &&
510 git format-patch --cover-letter -1 &&
511 check_patch 0000-cover-letter.patch &&
512 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
513 git format-patch --cover-letter -1 -M &&
514 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
515
516'
517
518cat > expect << EOF
519 This is an excessively long subject line for a message due to the
520 habit some projects have of not having a short, one-line subject at
521 the start of the commit message, but rather sticking a whole
522 paragraph right at the start as the only thing in the commit
523 message. It had better not become the filename for the patch.
524 foo
525
526EOF
527
528test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
529
530 git format-patch --cover-letter -2 &&
531 sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
532 test_cmp expect output
533
534'
535
536cat > expect << EOF
537index 40f36c6..2dc5c23 100644
538--- a/file
539+++ b/file
540@@ -13,4 +13,20 @@ C
541 10
542 D
543 E
544 F
545+5
546EOF
547
548test_expect_success 'format-patch respects -U' '
549
550 git format-patch -U4 -2 &&
551 sed -e "1,/^diff/d" -e "/^+5/q" \
552 <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
553 >output &&
554 test_cmp expect output
555
556'
557
558cat > expect << EOF
559
560diff --git a/file b/file
561index 40f36c6..2dc5c23 100644
562--- a/file
563+++ b/file
564@@ -14,3 +14,19 @@ C
565 D
566 E
567 F
568+5
569EOF
570
571test_expect_success 'format-patch -p suppresses stat' '
572
573 git format-patch -p -2 &&
574 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
575 test_cmp expect output
576
577'
578
579test_expect_success 'format-patch from a subdirectory (1)' '
580 filename=$(
581 rm -rf sub &&
582 mkdir -p sub/dir &&
583 cd sub/dir &&
584 git format-patch -1
585 ) &&
586 case "$filename" in
587 0*)
588 ;; # ok
589 *)
590 echo "Oops? $filename"
591 false
592 ;;
593 esac &&
594 test -f "$filename"
595'
596
597test_expect_success 'format-patch from a subdirectory (2)' '
598 filename=$(
599 rm -rf sub &&
600 mkdir -p sub/dir &&
601 cd sub/dir &&
602 git format-patch -1 -o ..
603 ) &&
604 case "$filename" in
605 ../0*)
606 ;; # ok
607 *)
608 echo "Oops? $filename"
609 false
610 ;;
611 esac &&
612 basename=$(expr "$filename" : ".*/\(.*\)") &&
613 test -f "sub/$basename"
614'
615
616test_expect_success 'format-patch from a subdirectory (3)' '
617 rm -f 0* &&
618 filename=$(
619 rm -rf sub &&
620 mkdir -p sub/dir &&
621 cd sub/dir &&
622 git format-patch -1 -o "$TRASH_DIRECTORY"
623 ) &&
624 basename=$(expr "$filename" : ".*/\(.*\)") &&
625 test -f "$basename"
626'
627
628test_expect_success 'format-patch --in-reply-to' '
629 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
630 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
631 grep "^References: <baz@foo.bar>" patch8
632'
633
634test_expect_success 'format-patch --signoff' '
635 git format-patch -1 --signoff --stdout |
636 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
637'
638
639echo "fatal: --name-only does not make sense" > expect.name-only
640echo "fatal: --name-status does not make sense" > expect.name-status
641echo "fatal: --check does not make sense" > expect.check
642
643test_expect_success 'options no longer allowed for format-patch' '
644 test_must_fail git format-patch --name-only 2> output &&
645 test_i18ncmp expect.name-only output &&
646 test_must_fail git format-patch --name-status 2> output &&
647 test_i18ncmp expect.name-status output &&
648 test_must_fail git format-patch --check 2> output &&
649 test_i18ncmp expect.check output'
650
651test_expect_success 'format-patch --numstat should produce a patch' '
652 git format-patch --numstat --stdout master..side > output &&
653 test 6 = $(grep "^diff --git a/" output | wc -l)'
654
655test_expect_success 'format-patch -- <path>' '
656 git format-patch master..side -- file 2>error &&
657 ! grep "Use .--" error
658'
659
660test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
661 git format-patch --ignore-if-in-upstream HEAD
662'
663
664test_expect_success 'format-patch --signature' '
665 git format-patch --stdout --signature="my sig" -1 >output &&
666 grep "my sig" output
667'
668
669test_expect_success 'format-patch with format.signature config' '
670 git config format.signature "config sig" &&
671 git format-patch --stdout -1 >output &&
672 grep "config sig" output
673'
674
675test_expect_success 'format-patch --signature overrides format.signature' '
676 git config format.signature "config sig" &&
677 git format-patch --stdout --signature="overrides" -1 >output &&
678 ! grep "config sig" output &&
679 grep "overrides" output
680'
681
682test_expect_success 'format-patch --no-signature ignores format.signature' '
683 git config format.signature "config sig" &&
684 git format-patch --stdout --signature="my sig" --no-signature \
685 -1 >output &&
686 check_patch output &&
687 ! grep "config sig" output &&
688 ! grep "my sig" output &&
689 ! grep "^-- \$" output
690'
691
692test_expect_success 'format-patch --signature --cover-letter' '
693 git config --unset-all format.signature &&
694 git format-patch --stdout --signature="my sig" --cover-letter \
695 -1 >output &&
696 grep "my sig" output &&
697 test 2 = $(grep "my sig" output | wc -l)
698'
699
700test_expect_success 'format.signature="" supresses signatures' '
701 git config format.signature "" &&
702 git format-patch --stdout -1 >output &&
703 check_patch output &&
704 ! grep "^-- \$" output
705'
706
707test_expect_success 'format-patch --no-signature supresses signatures' '
708 git config --unset-all format.signature &&
709 git format-patch --stdout --no-signature -1 >output &&
710 check_patch output &&
711 ! grep "^-- \$" output
712'
713
714test_expect_success 'format-patch --signature="" supresses signatures' '
715 git format-patch --stdout --signature="" -1 >output &&
716 check_patch output &&
717 ! grep "^-- \$" output
718'
719
720test_expect_success TTY 'format-patch --stdout paginates' '
721 rm -f pager_used &&
722 (
723 GIT_PAGER="wc >pager_used" &&
724 export GIT_PAGER &&
725 test_terminal git format-patch --stdout --all
726 ) &&
727 test_path_is_file pager_used
728'
729
730 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
731 rm -f pager_used &&
732 (
733 GIT_PAGER="wc >pager_used" &&
734 export GIT_PAGER &&
735 test_terminal git --no-pager format-patch --stdout --all &&
736 test_terminal git -c "pager.format-patch=false" format-patch --stdout --all
737 ) &&
738 test_path_is_missing pager_used &&
739 test_path_is_missing .git/pager_used
740'
741
742test_expect_success 'format-patch handles multi-line subjects' '
743 rm -rf patches/ &&
744 echo content >>file &&
745 for i in one two three; do echo $i; done >msg &&
746 git add file &&
747 git commit -F msg &&
748 git format-patch -o patches -1 &&
749 grep ^Subject: patches/0001-one.patch >actual &&
750 echo "Subject: [PATCH] one two three" >expect &&
751 test_cmp expect actual
752'
753
754test_expect_success 'format-patch handles multi-line encoded subjects' '
755 rm -rf patches/ &&
756 echo content >>file &&
757 for i in en två tre; do echo $i; done >msg &&
758 git add file &&
759 git commit -F msg &&
760 git format-patch -o patches -1 &&
761 grep ^Subject: patches/0001-en.patch >actual &&
762 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
763 test_cmp expect actual
764'
765
766M8="foo bar "
767M64=$M8$M8$M8$M8$M8$M8$M8$M8
768M512=$M64$M64$M64$M64$M64$M64$M64$M64
769cat >expect <<'EOF'
770Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
771 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
772 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
773 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
774 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
775 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
776 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
777 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
778 foo bar foo bar foo bar foo bar
779EOF
780test_expect_success 'format-patch wraps extremely long headers (ascii)' '
781 echo content >>file &&
782 git add file &&
783 git commit -m "$M512" &&
784 git format-patch --stdout -1 >patch &&
785 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
786 test_cmp expect subject
787'
788
789M8="föö bar "
790M64=$M8$M8$M8$M8$M8$M8$M8$M8
791M512=$M64$M64$M64$M64$M64$M64$M64$M64
792cat >expect <<'EOF'
793Subject: [PATCH] =?UTF-8?q?f=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=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
810 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
811 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
812 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
813 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
814 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
815EOF
816test_expect_success 'format-patch wraps extremely long headers (rfc2047)' '
817 rm -rf patches/ &&
818 echo content >>file &&
819 git add file &&
820 git commit -m "$M512" &&
821 git format-patch --stdout -1 >patch &&
822 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
823 test_cmp expect subject
824'
825
826M8="foo_bar_"
827M64=$M8$M8$M8$M8$M8$M8$M8$M8
828cat >expect <<EOF
829From: $M64
830 <foobar@foo.bar>
831EOF
832test_expect_success 'format-patch wraps non-quotable headers' '
833 rm -rf patches/ &&
834 echo content >>file &&
835 git add file &&
836 git commit -mfoo --author "$M64 <foobar@foo.bar>" &&
837 git format-patch --stdout -1 >patch &&
838 sed -n "/^From: /p; /^ /p; /^$/q" <patch >from &&
839 test_cmp expect from
840'
841
842check_author() {
843 echo content >>file &&
844 git add file &&
845 GIT_AUTHOR_NAME=$1 git commit -m author-check &&
846 git format-patch --stdout -1 >patch &&
847 grep ^From: patch >actual &&
848 test_cmp expect actual
849}
850
851cat >expect <<'EOF'
852From: "Foo B. Bar" <author@example.com>
853EOF
854test_expect_success 'format-patch quotes dot in headers' '
855 check_author "Foo B. Bar"
856'
857
858cat >expect <<'EOF'
859From: "Foo \"The Baz\" Bar" <author@example.com>
860EOF
861test_expect_success 'format-patch quotes double-quote in headers' '
862 check_author "Foo \"The Baz\" Bar"
863'
864
865cat >expect <<'EOF'
866From: =?UTF-8?q?"F=C3=B6o=20B.=20Bar"?= <author@example.com>
867EOF
868test_expect_success 'rfc2047-encoded headers also double-quote 822 specials' '
869 check_author "Föo B. Bar"
870'
871
872cat >expect <<'EOF'
873Subject: header with . in it
874EOF
875test_expect_success 'subject lines do not have 822 atom-quoting' '
876 echo content >>file &&
877 git add file &&
878 git commit -m "header with . in it" &&
879 git format-patch -k -1 --stdout >patch &&
880 grep ^Subject: patch >actual &&
881 test_cmp expect actual
882'
883
884cat >expect <<'EOF'
885Subject: [PREFIX 1/1] header with . in it
886EOF
887test_expect_success 'subject prefixes have space prepended' '
888 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
889 grep ^Subject: patch >actual &&
890 test_cmp expect actual
891'
892
893cat >expect <<'EOF'
894Subject: [1/1] header with . in it
895EOF
896test_expect_success 'empty subject prefix does not have extra space' '
897 git format-patch -n -1 --stdout --subject-prefix= >patch &&
898 grep ^Subject: patch >actual &&
899 test_cmp expect actual
900'
901
902test_expect_success 'format patch ignores color.ui' '
903 test_unconfig color.ui &&
904 git format-patch --stdout -1 >expect &&
905 test_config color.ui always &&
906 git format-patch --stdout -1 >actual &&
907 test_cmp expect actual
908'
909
910test_done