]> git.ipfire.org Git - thirdparty/git.git/blame - t/t4014-format-patch.sh
sequencer.c: teach append_signoff to avoid adding a duplicate newline
[thirdparty/git.git] / t / t4014-format-patch.sh
CommitLineData
ece3c67f
JH
1#!/bin/sh
2#
3# Copyright (c) 2006 Junio C Hamano
4#
5
9800a754 6test_description='various format-patch tests'
ece3c67f
JH
7
8. ./test-lib.sh
38a94bb6 9. "$TEST_DIRECTORY"/lib-terminal.sh
ece3c67f
JH
10
11test_expect_success setup '
12
13 for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i"; done >file &&
cd894ee9
JH
14 cat file >elif &&
15 git add file elif &&
6426f2d2 16 test_tick &&
ece3c67f
JH
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 &&
1f553918 21 test_chmod +x elif &&
6426f2d2 22 test_tick &&
816366e2 23 git commit -m "Side changes #1" &&
ece3c67f
JH
24
25 for i in D E F; do echo "$i"; done >>file &&
26 git update-index file &&
6426f2d2 27 test_tick &&
816366e2 28 git commit -m "Side changes #2" &&
982b64e4 29 git tag C2 &&
ece3c67f
JH
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 &&
6426f2d2 33 test_tick &&
816366e2 34 git commit -m "Side changes #3 with \\n backslash-n in it." &&
ece3c67f
JH
35
36 git checkout master &&
982b64e4 37 git diff-tree -p C2 | git apply --index &&
6426f2d2 38 test_tick &&
982b64e4 39 git commit -m "Master accepts moral equivalent of #2"
ece3c67f
JH
40
41'
42
43test_expect_success "format-patch --ignore-if-in-upstream" '
44
45 git format-patch --stdout master..side >patch0 &&
46 cnt=`grep "^From " patch0 | wc -l` &&
8780bd8f 47 test $cnt = 3
ece3c67f
JH
48
49'
50
51test_expect_success "format-patch --ignore-if-in-upstream" '
52
53 git format-patch --stdout \
54 --ignore-if-in-upstream master..side >patch1 &&
55 cnt=`grep "^From " patch1 | wc -l` &&
8780bd8f 56 test $cnt = 2
ece3c67f
JH
57
58'
59
2c642ed8
RR
60test_expect_success "format-patch doesn't consider merge commits" '
61
62 git checkout -b slave master &&
63 echo "Another line" >>file &&
64 test_tick &&
65 git commit -am "Slave change #1" &&
66 echo "Yet another line" >>file &&
67 test_tick &&
68 git commit -am "Slave change #2" &&
69 git checkout -b merger master &&
70 test_tick &&
71 git merge --no-ff slave &&
72 cnt=`git format-patch -3 --stdout | grep "^From " | wc -l` &&
73 test $cnt = 3
74'
75
ece3c67f
JH
76test_expect_success "format-patch result applies" '
77
78 git checkout -b rebuild-0 master &&
79 git am -3 patch0 &&
80 cnt=`git rev-list master.. | wc -l` &&
8780bd8f 81 test $cnt = 2
ece3c67f
JH
82'
83
84test_expect_success "format-patch --ignore-if-in-upstream result applies" '
85
86 git checkout -b rebuild-1 master &&
87 git am -3 patch1 &&
88 cnt=`git rev-list master.. | wc -l` &&
8780bd8f 89 test $cnt = 2
ece3c67f
JH
90'
91
816366e2
JH
92test_expect_success 'commit did not screw up the log message' '
93
94 git cat-file commit side | grep "^Side .* with .* backslash-n"
95
96'
97
98test_expect_success 'format-patch did not screw up the log message' '
99
100 grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
101 grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
102
103'
104
105test_expect_success 'replay did not screw up the log message' '
106
107 git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
108
109'
110
a8d8173e
DB
111test_expect_success 'extra headers' '
112
25dc8dad 113 git config format.headers "To: R E Cipient <rcipient@example.com>
a8d8173e 114" &&
25dc8dad 115 git config --add format.headers "Cc: S E Cipient <scipient@example.com>
a8d8173e
DB
116" &&
117 git format-patch --stdout master..side > patch2 &&
9524cf29 118 sed -e "/^\$/q" patch2 > hdrs2 &&
25dc8dad
JS
119 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs2 &&
120 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs2
3b2eb186 121
a8d8173e
DB
122'
123
7d22708b 124test_expect_success 'extra headers without newlines' '
a8d8173e 125
25dc8dad
JS
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>" &&
a8d8173e 128 git format-patch --stdout master..side >patch3 &&
9524cf29 129 sed -e "/^\$/q" patch3 > hdrs3 &&
25dc8dad
JS
130 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs3 &&
131 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs3
3b2eb186 132
a8d8173e
DB
133'
134
3ee79d9f 135test_expect_success 'extra headers with multiple To:s' '
a8d8173e 136
25dc8dad
JS
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>" &&
a8d8173e 139 git format-patch --stdout master..side > patch4 &&
9524cf29 140 sed -e "/^\$/q" patch4 > hdrs4 &&
25dc8dad
JS
141 grep "^To: R E Cipient <rcipient@example.com>,\$" hdrs4 &&
142 grep "^ *S E Cipient <scipient@example.com>\$" hdrs4
a8d8173e
DB
143'
144
25dc8dad 145test_expect_success 'additional command line cc (ascii)' '
736cc67d 146
25dc8dad
JS
147 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
148 git format-patch --cc="S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
149 grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
150 grep "^ *S E Cipient <scipient@example.com>\$" patch5
151'
152
153test_expect_failure 'additional command line cc (rfc822)' '
154
155 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
9524cf29 156 git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
25dc8dad
JS
157 grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
158 grep "^ *"S. E. Cipient" <scipient@example.com>\$" patch5
736cc67d
DB
159'
160
d7d9c2d0
MH
161test_expect_success 'command line headers' '
162
163 git config --unset-all format.headers &&
25dc8dad
JS
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
d7d9c2d0
MH
166'
167
168test_expect_success 'configuration headers and command line headers' '
169
25dc8dad
JS
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
d7d9c2d0
MH
174'
175
25dc8dad 176test_expect_success 'command line To: header (ascii)' '
ae6c098f
SD
177
178 git config --unset-all format.headers &&
25dc8dad
JS
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
183test_expect_failure 'command line To: header (rfc822)' '
184
ae6c098f 185 git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
25dc8dad
JS
186 grep "^To: "R. E. Cipient" <rcipient@example.com>\$" patch8
187'
188
189test_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
ae6c098f
SD
193'
194
25dc8dad
JS
195test_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
202test_expect_failure 'configuration To: header (rfc822)' '
ae6c098f
SD
203
204 git config format.to "R. E. Cipient <rcipient@example.com>" &&
205 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
25dc8dad
JS
206 grep "^To: "R. E. Cipient" <rcipient@example.com>\$" patch9
207'
208
209test_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
ae6c098f
SD
214'
215
cc663d14
TR
216# check_patch <patch>: Verify that <patch> looks like a half-sane
217# patch email to avoid a false positive with !grep
218check_patch () {
219 grep -e "^From:" "$1" &&
220 grep -e "^Date:" "$1" &&
221 grep -e "^Subject:" "$1"
222}
223
c4260034
SB
224test_expect_success '--no-to overrides config.to' '
225
226 git config --replace-all format.to \
25dc8dad 227 "R E Cipient <rcipient@example.com>" &&
c4260034
SB
228 git format-patch --no-to --stdout master..side |
229 sed -e "/^\$/q" >patch10 &&
cc663d14 230 check_patch patch10 &&
25dc8dad 231 ! grep "^To: R E Cipient <rcipient@example.com>\$" patch10
c4260034
SB
232'
233
234test_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 &&
cc663d14 241 check_patch patch11 &&
c4260034
SB
242 ! grep "^To: Someone <someone@out.there>\$" patch11 &&
243 grep "^To: Someone Else <else@out.there>\$" patch11
244'
245
246test_expect_success '--no-cc overrides config.cc' '
247
248 git config --replace-all format.cc \
25dc8dad 249 "C E Cipient <rcipient@example.com>" &&
c4260034
SB
250 git format-patch --no-cc --stdout master..side |
251 sed -e "/^\$/q" >patch12 &&
cc663d14 252 check_patch patch12 &&
25dc8dad 253 ! grep "^Cc: C E Cipient <rcipient@example.com>\$" patch12
c4260034
SB
254'
255
688f4f2f 256test_expect_success '--no-add-header overrides config.headers' '
c4260034
SB
257
258 git config --replace-all format.headers \
25dc8dad 259 "Header1: B E Cipient <rcipient@example.com>" &&
688f4f2f 260 git format-patch --no-add-header --stdout master..side |
c4260034 261 sed -e "/^\$/q" >patch13 &&
cc663d14 262 check_patch patch13 &&
25dc8dad 263 ! grep "^Header1: B E Cipient <rcipient@example.com>\$" patch13
c4260034
SB
264'
265
7d812145
DB
266test_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
484cf6c3
TR
274check_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
7096b648 280 "$PERL_PATH" -ne '
484cf6c3
TR
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
297cat >> expect.no-threading <<EOF
298---
299---
300---
301EOF
302
303test_expect_success 'no threading' '
7d812145 304 git checkout side &&
484cf6c3 305 check_threading expect.no-threading master
7d812145
DB
306'
307
484cf6c3
TR
308cat > expect.thread <<EOF
309---
310Message-Id: <0>
311---
312Message-Id: <1>
313In-Reply-To: <0>
314References: <0>
315---
316Message-Id: <2>
317In-Reply-To: <0>
318References: <0>
319EOF
7d812145 320
484cf6c3
TR
321test_expect_success 'thread' '
322 check_threading expect.thread --thread master
7d812145
DB
323'
324
484cf6c3
TR
325cat > expect.in-reply-to <<EOF
326---
327Message-Id: <0>
328In-Reply-To: <1>
329References: <1>
330---
331Message-Id: <2>
332In-Reply-To: <1>
333References: <1>
334---
335Message-Id: <3>
336In-Reply-To: <1>
337References: <1>
338EOF
a5a27c79 339
484cf6c3
TR
340test_expect_success 'thread in-reply-to' '
341 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
342 --thread master
a5a27c79
DB
343'
344
484cf6c3
TR
345cat > expect.cover-letter <<EOF
346---
347Message-Id: <0>
348---
349Message-Id: <1>
350In-Reply-To: <0>
351References: <0>
352---
353Message-Id: <2>
354In-Reply-To: <0>
355References: <0>
356---
357Message-Id: <3>
358In-Reply-To: <0>
359References: <0>
360EOF
a5a27c79 361
484cf6c3
TR
362test_expect_success 'thread cover-letter' '
363 check_threading expect.cover-letter --cover-letter --thread master
364'
365
366cat > expect.cl-irt <<EOF
367---
368Message-Id: <0>
369In-Reply-To: <1>
370References: <1>
371---
372Message-Id: <2>
2175c10d 373In-Reply-To: <0>
484cf6c3 374References: <1>
2175c10d 375 <0>
484cf6c3
TR
376---
377Message-Id: <3>
2175c10d 378In-Reply-To: <0>
484cf6c3 379References: <1>
2175c10d 380 <0>
484cf6c3
TR
381---
382Message-Id: <4>
2175c10d 383In-Reply-To: <0>
484cf6c3 384References: <1>
2175c10d 385 <0>
484cf6c3
TR
386EOF
387
388test_expect_success 'thread cover-letter in-reply-to' '
389 check_threading expect.cl-irt --cover-letter \
390 --in-reply-to="<test.message>" --thread master
a5a27c79
DB
391'
392
30984ed2
TR
393test_expect_success 'thread explicit shallow' '
394 check_threading expect.cl-irt --cover-letter \
395 --in-reply-to="<test.message>" --thread=shallow master
396'
397
398cat > expect.deep <<EOF
399---
400Message-Id: <0>
401---
402Message-Id: <1>
403In-Reply-To: <0>
404References: <0>
405---
406Message-Id: <2>
407In-Reply-To: <1>
408References: <0>
409 <1>
410EOF
411
412test_expect_success 'thread deep' '
413 check_threading expect.deep --thread=deep master
414'
415
416cat > expect.deep-irt <<EOF
417---
418Message-Id: <0>
419In-Reply-To: <1>
420References: <1>
421---
422Message-Id: <2>
423In-Reply-To: <0>
424References: <1>
425 <0>
426---
427Message-Id: <3>
428In-Reply-To: <2>
429References: <1>
430 <0>
431 <2>
432EOF
433
434test_expect_success 'thread deep in-reply-to' '
435 check_threading expect.deep-irt --thread=deep \
436 --in-reply-to="<test.message>" master
437'
438
439cat > expect.deep-cl <<EOF
440---
441Message-Id: <0>
442---
443Message-Id: <1>
444In-Reply-To: <0>
445References: <0>
446---
447Message-Id: <2>
448In-Reply-To: <1>
449References: <0>
450 <1>
451---
452Message-Id: <3>
453In-Reply-To: <2>
454References: <0>
455 <1>
456 <2>
457EOF
458
459test_expect_success 'thread deep cover-letter' '
460 check_threading expect.deep-cl --cover-letter --thread=deep master
461'
462
463cat > expect.deep-cl-irt <<EOF
464---
465Message-Id: <0>
466In-Reply-To: <1>
467References: <1>
468---
469Message-Id: <2>
470In-Reply-To: <0>
471References: <1>
472 <0>
473---
474Message-Id: <3>
475In-Reply-To: <2>
476References: <1>
477 <0>
478 <2>
479---
480Message-Id: <4>
481In-Reply-To: <3>
482References: <1>
483 <0>
484 <2>
485 <3>
486EOF
487
488test_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
493test_expect_success 'thread via config' '
e8107155 494 test_config format.thread true &&
30984ed2
TR
495 check_threading expect.thread master
496'
497
498test_expect_success 'thread deep via config' '
e8107155 499 test_config format.thread deep &&
30984ed2
TR
500 check_threading expect.deep master
501'
502
503test_expect_success 'thread config + override' '
e8107155 504 test_config format.thread deep &&
30984ed2
TR
505 check_threading expect.thread --thread master
506'
507
508test_expect_success 'thread config + --no-thread' '
e8107155 509 test_config format.thread deep &&
30984ed2
TR
510 check_threading expect.no-threading --no-thread master
511'
512
7d812145
DB
513test_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
5d02294c
JS
524test_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 &&
cc663d14 529 check_patch 0000-cover-letter.patch &&
9524cf29 530 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
5d02294c 531 git format-patch --cover-letter -1 -M &&
9524cf29 532 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
5d02294c
JS
533
534'
859c4fbe
JS
535
536cat > 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
544EOF
545
546test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
547
548 git format-patch --cover-letter -2 &&
9524cf29 549 sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
3af82863 550 test_cmp expect output
859c4fbe
JS
551
552'
553
68daa64d 554cat > expect << EOF
68daa64d
JK
555index 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
564EOF
565
566test_expect_success 'format-patch respects -U' '
567
568 git format-patch -U4 -2 &&
6dd88832
JN
569 sed -e "1,/^diff/d" -e "/^+5/q" \
570 <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
571 >output &&
68daa64d
JK
572 test_cmp expect output
573
574'
575
1d46f2ea
JK
576cat > expect << EOF
577
578diff --git a/file b/file
579index 40f36c6..2dc5c23 100644
580--- a/file
581+++ b/file
582@@ -14,3 +14,19 @@ C
583 D
584 E
585 F
586+5
587EOF
588
589test_expect_success 'format-patch -p suppresses stat' '
590
591 git format-patch -p -2 &&
9524cf29 592 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
1d46f2ea
JK
593 test_cmp expect output
594
595'
596
9800a754
JH
597test_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
615test_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
634test_expect_success 'format-patch from a subdirectory (3)' '
9800a754
JH
635 rm -f 0* &&
636 filename=$(
637 rm -rf sub &&
638 mkdir -p sub/dir &&
639 cd sub/dir &&
91c8b825 640 git format-patch -1 -o "$TRASH_DIRECTORY"
9800a754
JH
641 ) &&
642 basename=$(expr "$filename" : ".*/\(.*\)") &&
643 test -f "$basename"
644'
645
f044fe2d
SB
646test_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
652test_expect_success 'format-patch --signoff' '
212620fe
JH
653 git format-patch -1 --signoff --stdout >out &&
654 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
655'
656
657test_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 &&
bd1470b8 660 # Three dashes must come after S-o-b
212620fe 661 ! sed "/^Signed-off-by: /q" out | grep "test message" &&
bd1470b8
JH
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"
f044fe2d
SB
666'
667
02bc5b03
BG
668echo "fatal: --name-only does not make sense" > expect.name-only
669echo "fatal: --name-status does not make sense" > expect.name-status
670echo "fatal: --check does not make sense" > expect.check
671
68b2a005 672test_expect_success 'options no longer allowed for format-patch' '
02bc5b03 673 test_must_fail git format-patch --name-only 2> output &&
68b2a005 674 test_i18ncmp expect.name-only output &&
02bc5b03 675 test_must_fail git format-patch --name-status 2> output &&
68b2a005 676 test_i18ncmp expect.name-status output &&
02bc5b03 677 test_must_fail git format-patch --check 2> output &&
68b2a005 678 test_i18ncmp expect.check output'
02bc5b03
BG
679
680test_expect_success 'format-patch --numstat should produce a patch' '
4fa80cf0
JS
681 git format-patch --numstat --stdout master..side > output &&
682 test 6 = $(grep "^diff --git a/" output | wc -l)'
02bc5b03 683
7e93d3b9
FC
684test_expect_success 'format-patch -- <path>' '
685 git format-patch master..side -- file 2>error &&
686 ! grep "Use .--" error
687'
688
657ab61e
KB
689test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
690 git format-patch --ignore-if-in-upstream HEAD
691'
692
6622d9c7
SB
693test_expect_success 'format-patch --signature' '
694 git format-patch --stdout --signature="my sig" -1 >output &&
695 grep "my sig" output
696'
697
698test_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
704test_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
711test_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 &&
cc663d14 715 check_patch output &&
6622d9c7
SB
716 ! grep "config sig" output &&
717 ! grep "my sig" output &&
718 ! grep "^-- \$" output
719'
720
721test_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
729test_expect_success 'format.signature="" supresses signatures' '
730 git config format.signature "" &&
731 git format-patch --stdout -1 >output &&
cc663d14 732 check_patch output &&
6622d9c7
SB
733 ! grep "^-- \$" output
734'
735
736test_expect_success 'format-patch --no-signature supresses signatures' '
737 git config --unset-all format.signature &&
738 git format-patch --stdout --no-signature -1 >output &&
cc663d14 739 check_patch output &&
6622d9c7
SB
740 ! grep "^-- \$" output
741'
742
2fdb5c62
TR
743test_expect_success 'format-patch --signature="" supresses signatures' '
744 git format-patch --stdout --signature="" -1 >output &&
cc663d14 745 check_patch output &&
6622d9c7
SB
746 ! grep "^-- \$" output
747'
748
38a94bb6
TRC
749test_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
a1f6baa5
JK
771test_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
783test_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
795M8="foo bar "
796M64=$M8$M8$M8$M8$M8$M8$M8$M8
797M512=$M64$M64$M64$M64$M64$M64$M64$M64
798cat >expect <<'EOF'
799Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
7a76e68a
JS
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
a1f6baa5 806EOF
7a76e68a 807test_expect_success 'format-patch wraps extremely long subject (ascii)' '
a1f6baa5
JK
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
816M8="föö bar "
817M64=$M8$M8$M8$M8$M8$M8$M8$M8
818M512=$M64$M64$M64$M64$M64$M64$M64$M64
819cat >expect <<'EOF'
94f6cdf6
JS
820Subject: [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?=
a1f6baa5 843EOF
94f6cdf6 844test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
a1f6baa5
JK
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
4d03c18a
JK
854check_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 &&
7a76e68a 859 sed -n "/^From: /p; /^ /p; /^$/q" <patch >actual &&
4d03c18a
JK
860 test_cmp expect actual
861}
862
863cat >expect <<'EOF'
864From: "Foo B. Bar" <author@example.com>
865EOF
0fcec2ce 866test_expect_success 'format-patch quotes dot in from-headers' '
4d03c18a
JK
867 check_author "Foo B. Bar"
868'
869
870cat >expect <<'EOF'
871From: "Foo \"The Baz\" Bar" <author@example.com>
872EOF
0fcec2ce 873test_expect_success 'format-patch quotes double-quote in from-headers' '
4d03c18a
JK
874 check_author "Foo \"The Baz\" Bar"
875'
876
877cat >expect <<'EOF'
0fcec2ce 878From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
4d03c18a 879EOF
0fcec2ce
JS
880test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
881 check_author "Föo Bar"
882'
883
884cat >expect <<'EOF'
885From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
886EOF
41dd00ba 887test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
4d03c18a
JK
888 check_author "Föo B. Bar"
889'
890
7a76e68a
JS
891cat >expect <<EOF
892From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
893 <author@example.com>
894EOF
895test_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
899cat >expect <<'EOF'
900From: 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>
903EOF
904test_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
908cat >expect <<'EOF'
909From: "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>
912EOF
913test_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
4d03c18a 917cat >expect <<'EOF'
94f6cdf6
JS
918From: =?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>
923EOF
924test_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
928cat >expect <<'EOF'
4d03c18a
JK
929Subject: header with . in it
930EOF
931test_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
e7af8e49
JK
940cat >expect <<'EOF'
941Subject: [PREFIX 1/1] header with . in it
942EOF
943test_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
949cat >expect <<'EOF'
950Subject: [1/1] header with . in it
951EOF
952test_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
787570c7
PYH
958test_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
ece3c67f 966test_done