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