Merge branch 'jc/maint-test-portability' into maint
[git/git.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 >out &&
654 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
655 '
656
657 test_expect_success 'format-patch --notes --signoff' '
658 git notes --ref test add -m "test message" HEAD &&
659 git format-patch -1 --signoff --stdout --notes=test >out &&
660 # Three dashes must come after S-o-b
661 ! sed "/^Signed-off-by: /q" out | grep "test message" &&
662 sed "1,/^Signed-off-by: /d" out | grep "test message" &&
663 # Notes message must come after three dashes
664 ! sed "/^---$/q" out | grep "test message" &&
665 sed "1,/^---$/d" out | grep "test message"
666 '
667
668 echo "fatal: --name-only does not make sense" > expect.name-only
669 echo "fatal: --name-status does not make sense" > expect.name-status
670 echo "fatal: --check does not make sense" > expect.check
671
672 test_expect_success 'options no longer allowed for format-patch' '
673 test_must_fail git format-patch --name-only 2> output &&
674 test_i18ncmp expect.name-only output &&
675 test_must_fail git format-patch --name-status 2> output &&
676 test_i18ncmp expect.name-status output &&
677 test_must_fail git format-patch --check 2> output &&
678 test_i18ncmp expect.check output'
679
680 test_expect_success 'format-patch --numstat should produce a patch' '
681 git format-patch --numstat --stdout master..side > output &&
682 test 6 = $(grep "^diff --git a/" output | wc -l)'
683
684 test_expect_success 'format-patch -- <path>' '
685 git format-patch master..side -- file 2>error &&
686 ! grep "Use .--" error
687 '
688
689 test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
690 git format-patch --ignore-if-in-upstream HEAD
691 '
692
693 test_expect_success 'format-patch --signature' '
694 git format-patch --stdout --signature="my sig" -1 >output &&
695 grep "my sig" output
696 '
697
698 test_expect_success 'format-patch with format.signature config' '
699 git config format.signature "config sig" &&
700 git format-patch --stdout -1 >output &&
701 grep "config sig" output
702 '
703
704 test_expect_success 'format-patch --signature overrides format.signature' '
705 git config format.signature "config sig" &&
706 git format-patch --stdout --signature="overrides" -1 >output &&
707 ! grep "config sig" output &&
708 grep "overrides" output
709 '
710
711 test_expect_success 'format-patch --no-signature ignores format.signature' '
712 git config format.signature "config sig" &&
713 git format-patch --stdout --signature="my sig" --no-signature \
714 -1 >output &&
715 check_patch output &&
716 ! grep "config sig" output &&
717 ! grep "my sig" output &&
718 ! grep "^-- \$" output
719 '
720
721 test_expect_success 'format-patch --signature --cover-letter' '
722 git config --unset-all format.signature &&
723 git format-patch --stdout --signature="my sig" --cover-letter \
724 -1 >output &&
725 grep "my sig" output &&
726 test 2 = $(grep "my sig" output | wc -l)
727 '
728
729 test_expect_success 'format.signature="" supresses signatures' '
730 git config format.signature "" &&
731 git format-patch --stdout -1 >output &&
732 check_patch output &&
733 ! grep "^-- \$" output
734 '
735
736 test_expect_success 'format-patch --no-signature supresses signatures' '
737 git config --unset-all format.signature &&
738 git format-patch --stdout --no-signature -1 >output &&
739 check_patch output &&
740 ! grep "^-- \$" output
741 '
742
743 test_expect_success 'format-patch --signature="" supresses signatures' '
744 git format-patch --stdout --signature="" -1 >output &&
745 check_patch output &&
746 ! grep "^-- \$" output
747 '
748
749 test_expect_success TTY 'format-patch --stdout paginates' '
750 rm -f pager_used &&
751 (
752 GIT_PAGER="wc >pager_used" &&
753 export GIT_PAGER &&
754 test_terminal git format-patch --stdout --all
755 ) &&
756 test_path_is_file pager_used
757 '
758
759 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
760 rm -f pager_used &&
761 (
762 GIT_PAGER="wc >pager_used" &&
763 export GIT_PAGER &&
764 test_terminal git --no-pager format-patch --stdout --all &&
765 test_terminal git -c "pager.format-patch=false" format-patch --stdout --all
766 ) &&
767 test_path_is_missing pager_used &&
768 test_path_is_missing .git/pager_used
769 '
770
771 test_expect_success 'format-patch handles multi-line subjects' '
772 rm -rf patches/ &&
773 echo content >>file &&
774 for i in one two three; do echo $i; done >msg &&
775 git add file &&
776 git commit -F msg &&
777 git format-patch -o patches -1 &&
778 grep ^Subject: patches/0001-one.patch >actual &&
779 echo "Subject: [PATCH] one two three" >expect &&
780 test_cmp expect actual
781 '
782
783 test_expect_success 'format-patch handles multi-line encoded subjects' '
784 rm -rf patches/ &&
785 echo content >>file &&
786 for i in en två tre; do echo $i; done >msg &&
787 git add file &&
788 git commit -F msg &&
789 git format-patch -o patches -1 &&
790 grep ^Subject: patches/0001-en.patch >actual &&
791 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
792 test_cmp expect actual
793 '
794
795 M8="foo bar "
796 M64=$M8$M8$M8$M8$M8$M8$M8$M8
797 M512=$M64$M64$M64$M64$M64$M64$M64$M64
798 cat >expect <<'EOF'
799 Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
800 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
801 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
802 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
803 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
804 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
805 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
806 EOF
807 test_expect_success 'format-patch wraps extremely long subject (ascii)' '
808 echo content >>file &&
809 git add file &&
810 git commit -m "$M512" &&
811 git format-patch --stdout -1 >patch &&
812 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
813 test_cmp expect subject
814 '
815
816 M8="föö bar "
817 M64=$M8$M8$M8$M8$M8$M8$M8$M8
818 M512=$M64$M64$M64$M64$M64$M64$M64$M64
819 cat >expect <<'EOF'
820 Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
821 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
822 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
823 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
824 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3?=
825 =?UTF-8?q?=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
826 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3?=
827 =?UTF-8?q?=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
828 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
829 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
830 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
831 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3?=
832 =?UTF-8?q?=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
833 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3?=
834 =?UTF-8?q?=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
835 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
836 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
837 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
838 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3?=
839 =?UTF-8?q?=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
840 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3?=
841 =?UTF-8?q?=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
842 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
843 EOF
844 test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
845 rm -rf patches/ &&
846 echo content >>file &&
847 git add file &&
848 git commit -m "$M512" &&
849 git format-patch --stdout -1 >patch &&
850 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
851 test_cmp expect subject
852 '
853
854 check_author() {
855 echo content >>file &&
856 git add file &&
857 GIT_AUTHOR_NAME=$1 git commit -m author-check &&
858 git format-patch --stdout -1 >patch &&
859 sed -n "/^From: /p; /^ /p; /^$/q" <patch >actual &&
860 test_cmp expect actual
861 }
862
863 cat >expect <<'EOF'
864 From: "Foo B. Bar" <author@example.com>
865 EOF
866 test_expect_success 'format-patch quotes dot in from-headers' '
867 check_author "Foo B. Bar"
868 '
869
870 cat >expect <<'EOF'
871 From: "Foo \"The Baz\" Bar" <author@example.com>
872 EOF
873 test_expect_success 'format-patch quotes double-quote in from-headers' '
874 check_author "Foo \"The Baz\" Bar"
875 '
876
877 cat >expect <<'EOF'
878 From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
879 EOF
880 test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
881 check_author "Föo Bar"
882 '
883
884 cat >expect <<'EOF'
885 From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
886 EOF
887 test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
888 check_author "Föo B. Bar"
889 '
890
891 cat >expect <<EOF
892 From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
893 <author@example.com>
894 EOF
895 test_expect_success 'format-patch wraps moderately long from-header (ascii)' '
896 check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
897 '
898
899 cat >expect <<'EOF'
900 From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
901 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
902 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
903 EOF
904 test_expect_success 'format-patch wraps extremely long from-header (ascii)' '
905 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"
906 '
907
908 cat >expect <<'EOF'
909 From: "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
910 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
911 Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
912 EOF
913 test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
914 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"
915 '
916
917 cat >expect <<'EOF'
918 From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
919 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
920 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
921 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
922 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
923 EOF
924 test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
925 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"
926 '
927
928 cat >expect <<'EOF'
929 Subject: header with . in it
930 EOF
931 test_expect_success 'subject lines do not have 822 atom-quoting' '
932 echo content >>file &&
933 git add file &&
934 git commit -m "header with . in it" &&
935 git format-patch -k -1 --stdout >patch &&
936 grep ^Subject: patch >actual &&
937 test_cmp expect actual
938 '
939
940 cat >expect <<'EOF'
941 Subject: [PREFIX 1/1] header with . in it
942 EOF
943 test_expect_success 'subject prefixes have space prepended' '
944 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
945 grep ^Subject: patch >actual &&
946 test_cmp expect actual
947 '
948
949 cat >expect <<'EOF'
950 Subject: [1/1] header with . in it
951 EOF
952 test_expect_success 'empty subject prefix does not have extra space' '
953 git format-patch -n -1 --stdout --subject-prefix= >patch &&
954 grep ^Subject: patch >actual &&
955 test_cmp expect actual
956 '
957
958 test_expect_success 'format patch ignores color.ui' '
959 test_unconfig color.ui &&
960 git format-patch --stdout -1 >expect &&
961 test_config color.ui always &&
962 git format-patch --stdout -1 >actual &&
963 test_cmp expect actual
964 '
965
966 test_done