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