Code

Merge branch 'zj/test-cred-helper-nicer-prove'
[git.git] / t / t4014-format-patch.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2006 Junio C Hamano
4 #
6 test_description='various format-patch tests'
8 . ./test-lib.sh
9 . "$TEST_DIRECTORY"/lib-terminal.sh
11 test_expect_success setup '
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 &&
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" &&
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 &&
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." &&
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"
41 '
43 test_expect_success "format-patch --ignore-if-in-upstream" '
45         git format-patch --stdout master..side >patch0 &&
46         cnt=`grep "^From " patch0 | wc -l` &&
47         test $cnt = 3
49 '
51 test_expect_success "format-patch --ignore-if-in-upstream" '
53         git format-patch --stdout \
54                 --ignore-if-in-upstream master..side >patch1 &&
55         cnt=`grep "^From " patch1 | wc -l` &&
56         test $cnt = 2
58 '
60 test_expect_success "format-patch doesn't consider merge commits" '
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 '
76 test_expect_success "format-patch result applies" '
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 '
84 test_expect_success "format-patch --ignore-if-in-upstream result applies" '
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 '
92 test_expect_success 'commit did not screw up the log message' '
94         git cat-file commit side | grep "^Side .* with .* backslash-n"
96 '
98 test_expect_success 'format-patch did not screw up the log message' '
100         grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
101         grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
105 test_expect_success 'replay did not screw up the log message' '
107         git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
111 test_expect_success 'extra headers' '
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
124 test_expect_success 'extra headers without newlines' '
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
135 test_expect_success 'extra headers with multiple To:s' '
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
145 test_expect_success 'additional command line cc' '
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
153 test_expect_success 'command line headers' '
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
160 test_expect_success 'configuration headers and command line headers' '
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
168 test_expect_success 'command line To: header' '
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
175 test_expect_success 'configuration To: header' '
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
182 # check_patch <patch>: Verify that <patch> looks like a half-sane
183 # patch email to avoid a false positive with !grep
184 check_patch () {
185         grep -e "^From:" "$1" &&
186         grep -e "^Date:" "$1" &&
187         grep -e "^Subject:" "$1"
190 test_expect_success '--no-to overrides config.to' '
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
200 test_expect_success '--no-to and --to replaces config.to' '
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
212 test_expect_success '--no-cc overrides config.cc' '
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
222 test_expect_success '--no-add-header overrides config.headers' '
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
232 test_expect_success 'multiple files' '
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
240 check_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
263 cat >> expect.no-threading <<EOF
264 ---
265 ---
266 ---
267 EOF
269 test_expect_success 'no threading' '
270         git checkout side &&
271         check_threading expect.no-threading master
274 cat > expect.thread <<EOF
275 ---
276 Message-Id: <0>
277 ---
278 Message-Id: <1>
279 In-Reply-To: <0>
280 References: <0>
281 ---
282 Message-Id: <2>
283 In-Reply-To: <0>
284 References: <0>
285 EOF
287 test_expect_success 'thread' '
288         check_threading expect.thread --thread master
291 cat > expect.in-reply-to <<EOF
292 ---
293 Message-Id: <0>
294 In-Reply-To: <1>
295 References: <1>
296 ---
297 Message-Id: <2>
298 In-Reply-To: <1>
299 References: <1>
300 ---
301 Message-Id: <3>
302 In-Reply-To: <1>
303 References: <1>
304 EOF
306 test_expect_success 'thread in-reply-to' '
307         check_threading expect.in-reply-to --in-reply-to="<test.message>" \
308                 --thread master
311 cat > expect.cover-letter <<EOF
312 ---
313 Message-Id: <0>
314 ---
315 Message-Id: <1>
316 In-Reply-To: <0>
317 References: <0>
318 ---
319 Message-Id: <2>
320 In-Reply-To: <0>
321 References: <0>
322 ---
323 Message-Id: <3>
324 In-Reply-To: <0>
325 References: <0>
326 EOF
328 test_expect_success 'thread cover-letter' '
329         check_threading expect.cover-letter --cover-letter --thread master
332 cat > expect.cl-irt <<EOF
333 ---
334 Message-Id: <0>
335 In-Reply-To: <1>
336 References: <1>
337 ---
338 Message-Id: <2>
339 In-Reply-To: <0>
340 References: <1>
341         <0>
342 ---
343 Message-Id: <3>
344 In-Reply-To: <0>
345 References: <1>
346         <0>
347 ---
348 Message-Id: <4>
349 In-Reply-To: <0>
350 References: <1>
351         <0>
352 EOF
354 test_expect_success 'thread cover-letter in-reply-to' '
355         check_threading expect.cl-irt --cover-letter \
356                 --in-reply-to="<test.message>" --thread master
359 test_expect_success 'thread explicit shallow' '
360         check_threading expect.cl-irt --cover-letter \
361                 --in-reply-to="<test.message>" --thread=shallow master
364 cat > expect.deep <<EOF
365 ---
366 Message-Id: <0>
367 ---
368 Message-Id: <1>
369 In-Reply-To: <0>
370 References: <0>
371 ---
372 Message-Id: <2>
373 In-Reply-To: <1>
374 References: <0>
375         <1>
376 EOF
378 test_expect_success 'thread deep' '
379         check_threading expect.deep --thread=deep master
382 cat > expect.deep-irt <<EOF
383 ---
384 Message-Id: <0>
385 In-Reply-To: <1>
386 References: <1>
387 ---
388 Message-Id: <2>
389 In-Reply-To: <0>
390 References: <1>
391         <0>
392 ---
393 Message-Id: <3>
394 In-Reply-To: <2>
395 References: <1>
396         <0>
397         <2>
398 EOF
400 test_expect_success 'thread deep in-reply-to' '
401         check_threading expect.deep-irt  --thread=deep \
402                 --in-reply-to="<test.message>" master
405 cat > expect.deep-cl <<EOF
406 ---
407 Message-Id: <0>
408 ---
409 Message-Id: <1>
410 In-Reply-To: <0>
411 References: <0>
412 ---
413 Message-Id: <2>
414 In-Reply-To: <1>
415 References: <0>
416         <1>
417 ---
418 Message-Id: <3>
419 In-Reply-To: <2>
420 References: <0>
421         <1>
422         <2>
423 EOF
425 test_expect_success 'thread deep cover-letter' '
426         check_threading expect.deep-cl --cover-letter --thread=deep master
429 cat > expect.deep-cl-irt <<EOF
430 ---
431 Message-Id: <0>
432 In-Reply-To: <1>
433 References: <1>
434 ---
435 Message-Id: <2>
436 In-Reply-To: <0>
437 References: <1>
438         <0>
439 ---
440 Message-Id: <3>
441 In-Reply-To: <2>
442 References: <1>
443         <0>
444         <2>
445 ---
446 Message-Id: <4>
447 In-Reply-To: <3>
448 References: <1>
449         <0>
450         <2>
451         <3>
452 EOF
454 test_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
459 test_expect_success 'thread via config' '
460         test_config format.thread true &&
461         check_threading expect.thread master
464 test_expect_success 'thread deep via config' '
465         test_config format.thread deep &&
466         check_threading expect.deep master
469 test_expect_success 'thread config + override' '
470         test_config format.thread deep &&
471         check_threading expect.thread --thread master
474 test_expect_success 'thread config + --no-thread' '
475         test_config format.thread deep &&
476         check_threading expect.no-threading --no-thread master
479 test_expect_success 'excessive subject' '
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
490 test_expect_success 'cover-letter inherits diff options' '
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
502 cat > 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
510 EOF
512 test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
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
520 cat > expect << EOF
521 index 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
530 EOF
532 test_expect_success 'format-patch respects -U' '
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
542 cat > expect << EOF
544 diff --git a/file b/file
545 index 40f36c6..2dc5c23 100644
546 --- a/file
547 +++ b/file
548 @@ -14,3 +14,19 @@ C
549  D
550  E
551  F
552 +5
553 EOF
555 test_expect_success 'format-patch -p suppresses stat' '
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
563 test_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"
581 test_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"
600 test_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"
612 test_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
618 test_expect_success 'format-patch --signoff' '
619         git format-patch -1 --signoff --stdout |
620         grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
623 echo "fatal: --name-only does not make sense" > expect.name-only
624 echo "fatal: --name-status does not make sense" > expect.name-status
625 echo "fatal: --check does not make sense" > expect.check
627 test_expect_success 'options no longer allowed for format-patch' '
628         test_must_fail git format-patch --name-only 2> output &&
629         test_i18ncmp expect.name-only output &&
630         test_must_fail git format-patch --name-status 2> output &&
631         test_i18ncmp expect.name-status output &&
632         test_must_fail git format-patch --check 2> output &&
633         test_i18ncmp expect.check output'
635 test_expect_success 'format-patch --numstat should produce a patch' '
636         git format-patch --numstat --stdout master..side > output &&
637         test 6 = $(grep "^diff --git a/" output | wc -l)'
639 test_expect_success 'format-patch -- <path>' '
640         git format-patch master..side -- file 2>error &&
641         ! grep "Use .--" error
644 test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
645         git format-patch --ignore-if-in-upstream HEAD
648 test_expect_success 'format-patch --signature' '
649         git format-patch --stdout --signature="my sig" -1 >output &&
650         grep "my sig" output
653 test_expect_success 'format-patch with format.signature config' '
654         git config format.signature "config sig" &&
655         git format-patch --stdout -1 >output &&
656         grep "config sig" output
659 test_expect_success 'format-patch --signature overrides format.signature' '
660         git config format.signature "config sig" &&
661         git format-patch --stdout --signature="overrides" -1 >output &&
662         ! grep "config sig" output &&
663         grep "overrides" output
666 test_expect_success 'format-patch --no-signature ignores format.signature' '
667         git config format.signature "config sig" &&
668         git format-patch --stdout --signature="my sig" --no-signature \
669                 -1 >output &&
670         check_patch output &&
671         ! grep "config sig" output &&
672         ! grep "my sig" output &&
673         ! grep "^-- \$" output
676 test_expect_success 'format-patch --signature --cover-letter' '
677         git config --unset-all format.signature &&
678         git format-patch --stdout --signature="my sig" --cover-letter \
679                 -1 >output &&
680         grep "my sig" output &&
681         test 2 = $(grep "my sig" output | wc -l)
684 test_expect_success 'format.signature="" supresses signatures' '
685         git config format.signature "" &&
686         git format-patch --stdout -1 >output &&
687         check_patch output &&
688         ! grep "^-- \$" output
691 test_expect_success 'format-patch --no-signature supresses signatures' '
692         git config --unset-all format.signature &&
693         git format-patch --stdout --no-signature -1 >output &&
694         check_patch output &&
695         ! grep "^-- \$" output
698 test_expect_success 'format-patch --signature="" supresses signatures' '
699         git format-patch --stdout --signature="" -1 >output &&
700         check_patch output &&
701         ! grep "^-- \$" output
704 test_expect_success TTY 'format-patch --stdout paginates' '
705         rm -f pager_used &&
706         (
707                 GIT_PAGER="wc >pager_used" &&
708                 export GIT_PAGER &&
709                 test_terminal git format-patch --stdout --all
710         ) &&
711         test_path_is_file pager_used
714  test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
715         rm -f pager_used &&
716         (
717                 GIT_PAGER="wc >pager_used" &&
718                 export GIT_PAGER &&
719                 test_terminal git --no-pager format-patch --stdout --all &&
720                 test_terminal git -c "pager.format-patch=false" format-patch --stdout --all
721         ) &&
722         test_path_is_missing pager_used &&
723         test_path_is_missing .git/pager_used
726 test_expect_success 'format-patch handles multi-line subjects' '
727         rm -rf patches/ &&
728         echo content >>file &&
729         for i in one two three; do echo $i; done >msg &&
730         git add file &&
731         git commit -F msg &&
732         git format-patch -o patches -1 &&
733         grep ^Subject: patches/0001-one.patch >actual &&
734         echo "Subject: [PATCH] one two three" >expect &&
735         test_cmp expect actual
738 test_expect_success 'format-patch handles multi-line encoded subjects' '
739         rm -rf patches/ &&
740         echo content >>file &&
741         for i in en två tre; do echo $i; done >msg &&
742         git add file &&
743         git commit -F msg &&
744         git format-patch -o patches -1 &&
745         grep ^Subject: patches/0001-en.patch >actual &&
746         echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
747         test_cmp expect actual
750 M8="foo bar "
751 M64=$M8$M8$M8$M8$M8$M8$M8$M8
752 M512=$M64$M64$M64$M64$M64$M64$M64$M64
753 cat >expect <<'EOF'
754 Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
755  bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
756  foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
757  bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
758  foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
759  bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
760  foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
761  bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
762  foo bar foo bar foo bar foo bar
763 EOF
764 test_expect_success 'format-patch wraps extremely long headers (ascii)' '
765         echo content >>file &&
766         git add file &&
767         git commit -m "$M512" &&
768         git format-patch --stdout -1 >patch &&
769         sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
770         test_cmp expect subject
773 M8="föö bar "
774 M64=$M8$M8$M8$M8$M8$M8$M8$M8
775 M512=$M64$M64$M64$M64$M64$M64$M64$M64
776 cat >expect <<'EOF'
777 Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
778  =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
779  =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
780  =?UTF-8?q?=C3=B6=20bar=20f=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?=
799 EOF
800 test_expect_success 'format-patch wraps extremely long headers (rfc2047)' '
801         rm -rf patches/ &&
802         echo content >>file &&
803         git add file &&
804         git commit -m "$M512" &&
805         git format-patch --stdout -1 >patch &&
806         sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
807         test_cmp expect subject
810 M8="foo_bar_"
811 M64=$M8$M8$M8$M8$M8$M8$M8$M8
812 cat >expect <<EOF
813 From: $M64
814  <foobar@foo.bar>
815 EOF
816 test_expect_success 'format-patch wraps non-quotable headers' '
817         rm -rf patches/ &&
818         echo content >>file &&
819         git add file &&
820         git commit -mfoo --author "$M64 <foobar@foo.bar>" &&
821         git format-patch --stdout -1 >patch &&
822         sed -n "/^From: /p; /^ /p; /^$/q" <patch >from &&
823         test_cmp expect from
826 check_author() {
827         echo content >>file &&
828         git add file &&
829         GIT_AUTHOR_NAME=$1 git commit -m author-check &&
830         git format-patch --stdout -1 >patch &&
831         grep ^From: patch >actual &&
832         test_cmp expect actual
835 cat >expect <<'EOF'
836 From: "Foo B. Bar" <author@example.com>
837 EOF
838 test_expect_success 'format-patch quotes dot in headers' '
839         check_author "Foo B. Bar"
842 cat >expect <<'EOF'
843 From: "Foo \"The Baz\" Bar" <author@example.com>
844 EOF
845 test_expect_success 'format-patch quotes double-quote in headers' '
846         check_author "Foo \"The Baz\" Bar"
849 cat >expect <<'EOF'
850 From: =?UTF-8?q?"F=C3=B6o=20B.=20Bar"?= <author@example.com>
851 EOF
852 test_expect_success 'rfc2047-encoded headers also double-quote 822 specials' '
853         check_author "Föo B. Bar"
856 cat >expect <<'EOF'
857 Subject: header with . in it
858 EOF
859 test_expect_success 'subject lines do not have 822 atom-quoting' '
860         echo content >>file &&
861         git add file &&
862         git commit -m "header with . in it" &&
863         git format-patch -k -1 --stdout >patch &&
864         grep ^Subject: patch >actual &&
865         test_cmp expect actual
868 cat >expect <<'EOF'
869 Subject: [PREFIX 1/1] header with . in it
870 EOF
871 test_expect_success 'subject prefixes have space prepended' '
872         git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
873         grep ^Subject: patch >actual &&
874         test_cmp expect actual
877 cat >expect <<'EOF'
878 Subject: [1/1] header with . in it
879 EOF
880 test_expect_success 'empty subject prefix does not have extra space' '
881         git format-patch -n -1 --stdout --subject-prefix= >patch &&
882         grep ^Subject: patch >actual &&
883         test_cmp expect actual
886 test_expect_success 'format patch ignores color.ui' '
887         test_unconfig color.ui &&
888         git format-patch --stdout -1 >expect &&
889         test_config color.ui always &&
890         git format-patch --stdout -1 >actual &&
891         test_cmp expect actual
894 test_done