]> git.ipfire.org Git - thirdparty/git.git/blob - t/t4014-format-patch.sh
Merge branch 'nd/index-errno' into maint-1.7.11
[thirdparty/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' '
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_success 'command line headers' '
154
155 git config --unset-all format.headers &&
156 git format-patch --add-header="Cc: R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 &&
157 grep "^Cc: R. E. Cipient <rcipient@example.com>\$" patch6
158 '
159
160 test_expect_success 'configuration headers and command line headers' '
161
162 git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" &&
163 git format-patch --add-header="Cc: S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 &&
164 grep "^Cc: R. E. Cipient <rcipient@example.com>,\$" patch7 &&
165 grep "^ *S. E. Cipient <scipient@example.com>\$" patch7
166 '
167
168 test_expect_success 'command line To: header' '
169
170 git config --unset-all format.headers &&
171 git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
172 grep "^To: R. E. Cipient <rcipient@example.com>\$" patch8
173 '
174
175 test_expect_success 'configuration To: header' '
176
177 git config format.to "R. E. Cipient <rcipient@example.com>" &&
178 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
179 grep "^To: R. E. Cipient <rcipient@example.com>\$" patch9
180 '
181
182 # check_patch <patch>: Verify that <patch> looks like a half-sane
183 # patch email to avoid a false positive with !grep
184 check_patch () {
185 grep -e "^From:" "$1" &&
186 grep -e "^Date:" "$1" &&
187 grep -e "^Subject:" "$1"
188 }
189
190 test_expect_success '--no-to overrides config.to' '
191
192 git config --replace-all format.to \
193 "R. E. Cipient <rcipient@example.com>" &&
194 git format-patch --no-to --stdout master..side |
195 sed -e "/^\$/q" >patch10 &&
196 check_patch patch10 &&
197 ! grep "^To: R. E. Cipient <rcipient@example.com>\$" patch10
198 '
199
200 test_expect_success '--no-to and --to replaces config.to' '
201
202 git config --replace-all format.to \
203 "Someone <someone@out.there>" &&
204 git format-patch --no-to --to="Someone Else <else@out.there>" \
205 --stdout master..side |
206 sed -e "/^\$/q" >patch11 &&
207 check_patch patch11 &&
208 ! grep "^To: Someone <someone@out.there>\$" patch11 &&
209 grep "^To: Someone Else <else@out.there>\$" patch11
210 '
211
212 test_expect_success '--no-cc overrides config.cc' '
213
214 git config --replace-all format.cc \
215 "C. E. Cipient <rcipient@example.com>" &&
216 git format-patch --no-cc --stdout master..side |
217 sed -e "/^\$/q" >patch12 &&
218 check_patch patch12 &&
219 ! grep "^Cc: C. E. Cipient <rcipient@example.com>\$" patch12
220 '
221
222 test_expect_success '--no-add-header overrides config.headers' '
223
224 git config --replace-all format.headers \
225 "Header1: B. E. Cipient <rcipient@example.com>" &&
226 git format-patch --no-add-header --stdout master..side |
227 sed -e "/^\$/q" >patch13 &&
228 check_patch patch13 &&
229 ! grep "^Header1: B. E. Cipient <rcipient@example.com>\$" patch13
230 '
231
232 test_expect_success 'multiple files' '
233
234 rm -rf patches/ &&
235 git checkout side &&
236 git format-patch -o patches/ master &&
237 ls patches/0001-Side-changes-1.patch patches/0002-Side-changes-2.patch patches/0003-Side-changes-3-with-n-backslash-n-in-it.patch
238 '
239
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_PATH" -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
261 }
262
263 cat >> expect.no-threading <<EOF
264 ---
265 ---
266 ---
267 EOF
268
269 test_expect_success 'no threading' '
270 git checkout side &&
271 check_threading expect.no-threading master
272 '
273
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
286
287 test_expect_success 'thread' '
288 check_threading expect.thread --thread master
289 '
290
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
305
306 test_expect_success 'thread in-reply-to' '
307 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
308 --thread master
309 '
310
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
327
328 test_expect_success 'thread cover-letter' '
329 check_threading expect.cover-letter --cover-letter --thread master
330 '
331
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
353
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
357 '
358
359 test_expect_success 'thread explicit shallow' '
360 check_threading expect.cl-irt --cover-letter \
361 --in-reply-to="<test.message>" --thread=shallow master
362 '
363
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
377
378 test_expect_success 'thread deep' '
379 check_threading expect.deep --thread=deep master
380 '
381
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
399
400 test_expect_success 'thread deep in-reply-to' '
401 check_threading expect.deep-irt --thread=deep \
402 --in-reply-to="<test.message>" master
403 '
404
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
424
425 test_expect_success 'thread deep cover-letter' '
426 check_threading expect.deep-cl --cover-letter --thread=deep master
427 '
428
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
453
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
457 '
458
459 test_expect_success 'thread via config' '
460 test_config format.thread true &&
461 check_threading expect.thread master
462 '
463
464 test_expect_success 'thread deep via config' '
465 test_config format.thread deep &&
466 check_threading expect.deep master
467 '
468
469 test_expect_success 'thread config + override' '
470 test_config format.thread deep &&
471 check_threading expect.thread --thread master
472 '
473
474 test_expect_success 'thread config + --no-thread' '
475 test_config format.thread deep &&
476 check_threading expect.no-threading --no-thread master
477 '
478
479 test_expect_success 'excessive subject' '
480
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
488 '
489
490 test_expect_success 'cover-letter inherits diff options' '
491
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
499
500 '
501
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
509
510 EOF
511
512 test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
513
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
517
518 '
519
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
531
532 test_expect_success 'format-patch respects -U' '
533
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
539
540 '
541
542 cat > expect << EOF
543
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
554
555 test_expect_success 'format-patch -p suppresses stat' '
556
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
560
561 '
562
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"
579 '
580
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"
598 '
599
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"
610 '
611
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
616 '
617
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>"
621 '
622
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
626
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'
634
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)'
638
639 test_expect_success 'format-patch -- <path>' '
640 git format-patch master..side -- file 2>error &&
641 ! grep "Use .--" error
642 '
643
644 test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
645 git format-patch --ignore-if-in-upstream HEAD
646 '
647
648 test_expect_success 'format-patch --signature' '
649 git format-patch --stdout --signature="my sig" -1 >output &&
650 grep "my sig" output
651 '
652
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
657 '
658
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
664 '
665
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
674 '
675
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)
682 '
683
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
689 '
690
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
696 '
697
698 test_expect_success 'format-patch --signature="" supresses signatures' '
699 git format-patch --stdout --signature="" -1 >output &&
700 check_patch output &&
701 ! grep "^-- \$" output
702 '
703
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
712 '
713
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
724 '
725
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
736 '
737
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
748 '
749
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
771 '
772
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
808 '
809
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
824 '
825
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
833 }
834
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"
840 '
841
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"
847 '
848
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"
854 '
855
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
866 '
867
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
875 '
876
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
884 '
885
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
892 '
893
894 test_done