]> git.ipfire.org Git - thirdparty/git.git/blame - t/t4014-format-patch.sh
Git 2.17
[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 &&
54835fc5 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 &&
54835fc5 55 cnt=$(grep "^From " patch1 | wc -l) &&
8780bd8f 56 test $cnt = 2
ece3c67f
JH
57
58'
59
9b7a61d7
JH
60test_expect_success "format-patch --ignore-if-in-upstream handles tags" '
61 git tag -a v1 -m tag side &&
62 git tag -a v2 -m tag master &&
63 git format-patch --stdout --ignore-if-in-upstream v2..v1 >patch1 &&
64 cnt=$(grep "^From " patch1 | wc -l) &&
65 test $cnt = 2
66'
67
2c642ed8
RR
68test_expect_success "format-patch doesn't consider merge commits" '
69
70 git checkout -b slave master &&
71 echo "Another line" >>file &&
72 test_tick &&
73 git commit -am "Slave change #1" &&
74 echo "Yet another line" >>file &&
75 test_tick &&
76 git commit -am "Slave change #2" &&
77 git checkout -b merger master &&
78 test_tick &&
79 git merge --no-ff slave &&
54835fc5 80 cnt=$(git format-patch -3 --stdout | grep "^From " | wc -l) &&
2c642ed8
RR
81 test $cnt = 3
82'
83
ece3c67f
JH
84test_expect_success "format-patch result applies" '
85
86 git checkout -b rebuild-0 master &&
87 git am -3 patch0 &&
54835fc5 88 cnt=$(git rev-list master.. | wc -l) &&
8780bd8f 89 test $cnt = 2
ece3c67f
JH
90'
91
92test_expect_success "format-patch --ignore-if-in-upstream result applies" '
93
94 git checkout -b rebuild-1 master &&
95 git am -3 patch1 &&
54835fc5 96 cnt=$(git rev-list master.. | wc -l) &&
8780bd8f 97 test $cnt = 2
ece3c67f
JH
98'
99
816366e2
JH
100test_expect_success 'commit did not screw up the log message' '
101
102 git cat-file commit side | grep "^Side .* with .* backslash-n"
103
104'
105
106test_expect_success 'format-patch did not screw up the log message' '
107
108 grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
109 grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
110
111'
112
113test_expect_success 'replay did not screw up the log message' '
114
115 git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
116
117'
118
a8d8173e
DB
119test_expect_success 'extra headers' '
120
25dc8dad 121 git config format.headers "To: R E Cipient <rcipient@example.com>
a8d8173e 122" &&
25dc8dad 123 git config --add format.headers "Cc: S E Cipient <scipient@example.com>
a8d8173e
DB
124" &&
125 git format-patch --stdout master..side > patch2 &&
9524cf29 126 sed -e "/^\$/q" patch2 > hdrs2 &&
25dc8dad
JS
127 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs2 &&
128 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs2
3b2eb186 129
a8d8173e
DB
130'
131
7d22708b 132test_expect_success 'extra headers without newlines' '
a8d8173e 133
25dc8dad
JS
134 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
135 git config --add format.headers "Cc: S E Cipient <scipient@example.com>" &&
a8d8173e 136 git format-patch --stdout master..side >patch3 &&
9524cf29 137 sed -e "/^\$/q" patch3 > hdrs3 &&
25dc8dad
JS
138 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs3 &&
139 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs3
3b2eb186 140
a8d8173e
DB
141'
142
3ee79d9f 143test_expect_success 'extra headers with multiple To:s' '
a8d8173e 144
25dc8dad
JS
145 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
146 git config --add format.headers "To: S E Cipient <scipient@example.com>" &&
a8d8173e 147 git format-patch --stdout master..side > patch4 &&
9524cf29 148 sed -e "/^\$/q" patch4 > hdrs4 &&
25dc8dad
JS
149 grep "^To: R E Cipient <rcipient@example.com>,\$" hdrs4 &&
150 grep "^ *S E Cipient <scipient@example.com>\$" hdrs4
a8d8173e
DB
151'
152
25dc8dad 153test_expect_success 'additional command line cc (ascii)' '
736cc67d 154
25dc8dad
JS
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
161test_expect_failure 'additional command line cc (rfc822)' '
162
163 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
9524cf29 164 git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
25dc8dad 165 grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
27f6342f 166 grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" patch5
736cc67d
DB
167'
168
d7d9c2d0
MH
169test_expect_success 'command line headers' '
170
171 git config --unset-all format.headers &&
25dc8dad
JS
172 git format-patch --add-header="Cc: R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 &&
173 grep "^Cc: R E Cipient <rcipient@example.com>\$" patch6
d7d9c2d0
MH
174'
175
176test_expect_success 'configuration headers and command line headers' '
177
25dc8dad
JS
178 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
179 git format-patch --add-header="Cc: S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 &&
180 grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch7 &&
181 grep "^ *S E Cipient <scipient@example.com>\$" patch7
d7d9c2d0
MH
182'
183
25dc8dad 184test_expect_success 'command line To: header (ascii)' '
ae6c098f
SD
185
186 git config --unset-all format.headers &&
25dc8dad
JS
187 git format-patch --to="R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
188 grep "^To: R E Cipient <rcipient@example.com>\$" patch8
189'
190
191test_expect_failure 'command line To: header (rfc822)' '
192
ae6c098f 193 git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
27f6342f 194 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch8
25dc8dad
JS
195'
196
197test_expect_failure 'command line To: header (rfc2047)' '
198
199 git format-patch --to="R Ä Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
200 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch8
ae6c098f
SD
201'
202
25dc8dad
JS
203test_expect_success 'configuration To: header (ascii)' '
204
205 git config format.to "R E Cipient <rcipient@example.com>" &&
206 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
207 grep "^To: R E Cipient <rcipient@example.com>\$" patch9
208'
209
210test_expect_failure 'configuration To: header (rfc822)' '
ae6c098f
SD
211
212 git config format.to "R. E. Cipient <rcipient@example.com>" &&
213 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
27f6342f 214 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch9
25dc8dad
JS
215'
216
217test_expect_failure 'configuration To: header (rfc2047)' '
218
219 git config format.to "R Ä Cipient <rcipient@example.com>" &&
220 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
221 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch9
ae6c098f
SD
222'
223
cc663d14
TR
224# check_patch <patch>: Verify that <patch> looks like a half-sane
225# patch email to avoid a false positive with !grep
226check_patch () {
227 grep -e "^From:" "$1" &&
228 grep -e "^Date:" "$1" &&
229 grep -e "^Subject:" "$1"
230}
231
6bc6b6c0
JT
232test_expect_success 'format.from=false' '
233
234 git -c format.from=false format-patch --stdout master..side |
235 sed -e "/^\$/q" >patch &&
236 check_patch patch &&
237 ! grep "^From: C O Mitter <committer@example.com>\$" patch
238'
239
240test_expect_success 'format.from=true' '
241
242 git -c format.from=true format-patch --stdout master..side |
243 sed -e "/^\$/q" >patch &&
244 check_patch patch &&
245 grep "^From: C O Mitter <committer@example.com>\$" patch
246'
247
248test_expect_success 'format.from with address' '
249
250 git -c format.from="F R Om <from@example.com>" format-patch --stdout master..side |
251 sed -e "/^\$/q" >patch &&
252 check_patch patch &&
253 grep "^From: F R Om <from@example.com>\$" patch
254'
255
256test_expect_success '--no-from overrides format.from' '
257
258 git -c format.from="F R Om <from@example.com>" format-patch --no-from --stdout master..side |
259 sed -e "/^\$/q" >patch &&
260 check_patch patch &&
261 ! grep "^From: F R Om <from@example.com>\$" patch
262'
263
264test_expect_success '--from overrides format.from' '
265
266 git -c format.from="F R Om <from@example.com>" format-patch --from --stdout master..side |
267 sed -e "/^\$/q" >patch &&
268 check_patch patch &&
269 ! grep "^From: F R Om <from@example.com>\$" patch
270'
271
c4260034
SB
272test_expect_success '--no-to overrides config.to' '
273
274 git config --replace-all format.to \
25dc8dad 275 "R E Cipient <rcipient@example.com>" &&
c4260034
SB
276 git format-patch --no-to --stdout master..side |
277 sed -e "/^\$/q" >patch10 &&
cc663d14 278 check_patch patch10 &&
25dc8dad 279 ! grep "^To: R E Cipient <rcipient@example.com>\$" patch10
c4260034
SB
280'
281
282test_expect_success '--no-to and --to replaces config.to' '
283
284 git config --replace-all format.to \
285 "Someone <someone@out.there>" &&
286 git format-patch --no-to --to="Someone Else <else@out.there>" \
287 --stdout master..side |
288 sed -e "/^\$/q" >patch11 &&
cc663d14 289 check_patch patch11 &&
c4260034
SB
290 ! grep "^To: Someone <someone@out.there>\$" patch11 &&
291 grep "^To: Someone Else <else@out.there>\$" patch11
292'
293
294test_expect_success '--no-cc overrides config.cc' '
295
296 git config --replace-all format.cc \
25dc8dad 297 "C E Cipient <rcipient@example.com>" &&
c4260034
SB
298 git format-patch --no-cc --stdout master..side |
299 sed -e "/^\$/q" >patch12 &&
cc663d14 300 check_patch patch12 &&
25dc8dad 301 ! grep "^Cc: C E Cipient <rcipient@example.com>\$" patch12
c4260034
SB
302'
303
688f4f2f 304test_expect_success '--no-add-header overrides config.headers' '
c4260034
SB
305
306 git config --replace-all format.headers \
25dc8dad 307 "Header1: B E Cipient <rcipient@example.com>" &&
688f4f2f 308 git format-patch --no-add-header --stdout master..side |
c4260034 309 sed -e "/^\$/q" >patch13 &&
cc663d14 310 check_patch patch13 &&
25dc8dad 311 ! grep "^Header1: B E Cipient <rcipient@example.com>\$" patch13
c4260034
SB
312'
313
7d812145
DB
314test_expect_success 'multiple files' '
315
316 rm -rf patches/ &&
317 git checkout side &&
318 git format-patch -o patches/ master &&
319 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
320'
321
4aad08e0
JH
322test_expect_success 'reroll count' '
323 rm -fr patches &&
324 git format-patch -o patches --cover-letter --reroll-count 4 master..side >list &&
325 ! grep -v "^patches/v4-000[0-3]-" list &&
326 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
327 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
328'
329
7952ea66
JH
330test_expect_success 'reroll count (-v)' '
331 rm -fr patches &&
332 git format-patch -o patches --cover-letter -v4 master..side >list &&
333 ! grep -v "^patches/v4-000[0-3]-" list &&
334 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
335 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
336'
337
484cf6c3
TR
338check_threading () {
339 expect="$1" &&
340 shift &&
341 (git format-patch --stdout "$@"; echo $? > status.out) |
342 # Prints everything between the Message-ID and In-Reply-To,
343 # and replaces all Message-ID-lookalikes by a sequence number
94221d22 344 perl -ne '
484cf6c3
TR
345 if (/^(message-id|references|in-reply-to)/i) {
346 $printing = 1;
347 } elsif (/^\S/) {
348 $printing = 0;
349 }
350 if ($printing) {
351 $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
352 for $k (keys %h) {s/$k/$h{$k}/};
353 print;
354 }
355 print "---\n" if /^From /i;
356 ' > actual &&
357 test 0 = "$(cat status.out)" &&
358 test_cmp "$expect" actual
359}
360
361cat >> expect.no-threading <<EOF
362---
363---
364---
365EOF
366
367test_expect_success 'no threading' '
7d812145 368 git checkout side &&
484cf6c3 369 check_threading expect.no-threading master
7d812145
DB
370'
371
484cf6c3
TR
372cat > expect.thread <<EOF
373---
374Message-Id: <0>
375---
376Message-Id: <1>
377In-Reply-To: <0>
378References: <0>
379---
380Message-Id: <2>
381In-Reply-To: <0>
382References: <0>
383EOF
7d812145 384
484cf6c3
TR
385test_expect_success 'thread' '
386 check_threading expect.thread --thread master
7d812145
DB
387'
388
484cf6c3
TR
389cat > expect.in-reply-to <<EOF
390---
391Message-Id: <0>
392In-Reply-To: <1>
393References: <1>
394---
395Message-Id: <2>
396In-Reply-To: <1>
397References: <1>
398---
399Message-Id: <3>
400In-Reply-To: <1>
401References: <1>
402EOF
a5a27c79 403
484cf6c3
TR
404test_expect_success 'thread in-reply-to' '
405 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
406 --thread master
a5a27c79
DB
407'
408
484cf6c3
TR
409cat > expect.cover-letter <<EOF
410---
411Message-Id: <0>
412---
413Message-Id: <1>
414In-Reply-To: <0>
415References: <0>
416---
417Message-Id: <2>
418In-Reply-To: <0>
419References: <0>
420---
421Message-Id: <3>
422In-Reply-To: <0>
423References: <0>
424EOF
a5a27c79 425
484cf6c3
TR
426test_expect_success 'thread cover-letter' '
427 check_threading expect.cover-letter --cover-letter --thread master
428'
429
430cat > expect.cl-irt <<EOF
431---
432Message-Id: <0>
433In-Reply-To: <1>
434References: <1>
435---
436Message-Id: <2>
2175c10d 437In-Reply-To: <0>
484cf6c3 438References: <1>
2175c10d 439 <0>
484cf6c3
TR
440---
441Message-Id: <3>
2175c10d 442In-Reply-To: <0>
484cf6c3 443References: <1>
2175c10d 444 <0>
484cf6c3
TR
445---
446Message-Id: <4>
2175c10d 447In-Reply-To: <0>
484cf6c3 448References: <1>
2175c10d 449 <0>
484cf6c3
TR
450EOF
451
452test_expect_success 'thread cover-letter in-reply-to' '
453 check_threading expect.cl-irt --cover-letter \
454 --in-reply-to="<test.message>" --thread master
a5a27c79
DB
455'
456
30984ed2
TR
457test_expect_success 'thread explicit shallow' '
458 check_threading expect.cl-irt --cover-letter \
459 --in-reply-to="<test.message>" --thread=shallow master
460'
461
462cat > expect.deep <<EOF
463---
464Message-Id: <0>
465---
466Message-Id: <1>
467In-Reply-To: <0>
468References: <0>
469---
470Message-Id: <2>
471In-Reply-To: <1>
472References: <0>
473 <1>
474EOF
475
476test_expect_success 'thread deep' '
477 check_threading expect.deep --thread=deep master
478'
479
480cat > expect.deep-irt <<EOF
481---
482Message-Id: <0>
483In-Reply-To: <1>
484References: <1>
485---
486Message-Id: <2>
487In-Reply-To: <0>
488References: <1>
489 <0>
490---
491Message-Id: <3>
492In-Reply-To: <2>
493References: <1>
494 <0>
495 <2>
496EOF
497
498test_expect_success 'thread deep in-reply-to' '
499 check_threading expect.deep-irt --thread=deep \
500 --in-reply-to="<test.message>" master
501'
502
503cat > expect.deep-cl <<EOF
504---
505Message-Id: <0>
506---
507Message-Id: <1>
508In-Reply-To: <0>
509References: <0>
510---
511Message-Id: <2>
512In-Reply-To: <1>
513References: <0>
514 <1>
515---
516Message-Id: <3>
517In-Reply-To: <2>
518References: <0>
519 <1>
520 <2>
521EOF
522
523test_expect_success 'thread deep cover-letter' '
524 check_threading expect.deep-cl --cover-letter --thread=deep master
525'
526
527cat > expect.deep-cl-irt <<EOF
528---
529Message-Id: <0>
530In-Reply-To: <1>
531References: <1>
532---
533Message-Id: <2>
534In-Reply-To: <0>
535References: <1>
536 <0>
537---
538Message-Id: <3>
539In-Reply-To: <2>
540References: <1>
541 <0>
542 <2>
543---
544Message-Id: <4>
545In-Reply-To: <3>
546References: <1>
547 <0>
548 <2>
549 <3>
550EOF
551
552test_expect_success 'thread deep cover-letter in-reply-to' '
553 check_threading expect.deep-cl-irt --cover-letter \
554 --in-reply-to="<test.message>" --thread=deep master
555'
556
557test_expect_success 'thread via config' '
e8107155 558 test_config format.thread true &&
30984ed2
TR
559 check_threading expect.thread master
560'
561
562test_expect_success 'thread deep via config' '
e8107155 563 test_config format.thread deep &&
30984ed2
TR
564 check_threading expect.deep master
565'
566
567test_expect_success 'thread config + override' '
e8107155 568 test_config format.thread deep &&
30984ed2
TR
569 check_threading expect.thread --thread master
570'
571
572test_expect_success 'thread config + --no-thread' '
e8107155 573 test_config format.thread deep &&
30984ed2
TR
574 check_threading expect.no-threading --no-thread master
575'
576
7d812145
DB
577test_expect_success 'excessive subject' '
578
579 rm -rf patches/ &&
580 git checkout side &&
581 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
582 git update-index file &&
583 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." &&
584 git format-patch -o patches/ master..side &&
585 ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
586'
587
5d02294c
JS
588test_expect_success 'cover-letter inherits diff options' '
589
590 git mv file foo &&
591 git commit -m foo &&
5404c116 592 git format-patch --no-renames --cover-letter -1 &&
cc663d14 593 check_patch 0000-cover-letter.patch &&
9524cf29 594 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
5d02294c 595 git format-patch --cover-letter -1 -M &&
9524cf29 596 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
5d02294c
JS
597
598'
859c4fbe
JS
599
600cat > expect << EOF
601 This is an excessively long subject line for a message due to the
602 habit some projects have of not having a short, one-line subject at
603 the start of the commit message, but rather sticking a whole
604 paragraph right at the start as the only thing in the commit
605 message. It had better not become the filename for the patch.
606 foo
607
608EOF
609
610test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
611
612 git format-patch --cover-letter -2 &&
9524cf29 613 sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
3af82863 614 test_cmp expect output
859c4fbe
JS
615
616'
617
68daa64d 618cat > expect << EOF
68daa64d
JK
619index 40f36c6..2dc5c23 100644
620--- a/file
621+++ b/file
622@@ -13,4 +13,20 @@ C
623 10
624 D
625 E
626 F
627+5
628EOF
629
630test_expect_success 'format-patch respects -U' '
631
632 git format-patch -U4 -2 &&
6dd88832
JN
633 sed -e "1,/^diff/d" -e "/^+5/q" \
634 <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
635 >output &&
68daa64d
JK
636 test_cmp expect output
637
638'
639
1d46f2ea
JK
640cat > expect << EOF
641
642diff --git a/file b/file
643index 40f36c6..2dc5c23 100644
644--- a/file
645+++ b/file
646@@ -14,3 +14,19 @@ C
647 D
648 E
649 F
650+5
651EOF
652
653test_expect_success 'format-patch -p suppresses stat' '
654
655 git format-patch -p -2 &&
9524cf29 656 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
1d46f2ea
JK
657 test_cmp expect output
658
659'
660
9800a754
JH
661test_expect_success 'format-patch from a subdirectory (1)' '
662 filename=$(
663 rm -rf sub &&
664 mkdir -p sub/dir &&
665 cd sub/dir &&
666 git format-patch -1
667 ) &&
668 case "$filename" in
669 0*)
670 ;; # ok
671 *)
672 echo "Oops? $filename"
673 false
674 ;;
675 esac &&
676 test -f "$filename"
677'
678
679test_expect_success 'format-patch from a subdirectory (2)' '
680 filename=$(
681 rm -rf sub &&
682 mkdir -p sub/dir &&
683 cd sub/dir &&
684 git format-patch -1 -o ..
685 ) &&
686 case "$filename" in
687 ../0*)
688 ;; # ok
689 *)
690 echo "Oops? $filename"
691 false
692 ;;
693 esac &&
694 basename=$(expr "$filename" : ".*/\(.*\)") &&
695 test -f "sub/$basename"
696'
697
698test_expect_success 'format-patch from a subdirectory (3)' '
9800a754
JH
699 rm -f 0* &&
700 filename=$(
701 rm -rf sub &&
702 mkdir -p sub/dir &&
703 cd sub/dir &&
91c8b825 704 git format-patch -1 -o "$TRASH_DIRECTORY"
9800a754
JH
705 ) &&
706 basename=$(expr "$filename" : ".*/\(.*\)") &&
707 test -f "$basename"
708'
709
f044fe2d
SB
710test_expect_success 'format-patch --in-reply-to' '
711 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
712 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
713 grep "^References: <baz@foo.bar>" patch8
714'
715
716test_expect_success 'format-patch --signoff' '
212620fe
JH
717 git format-patch -1 --signoff --stdout >out &&
718 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
719'
720
721test_expect_success 'format-patch --notes --signoff' '
722 git notes --ref test add -m "test message" HEAD &&
723 git format-patch -1 --signoff --stdout --notes=test >out &&
bd1470b8 724 # Three dashes must come after S-o-b
212620fe 725 ! sed "/^Signed-off-by: /q" out | grep "test message" &&
bd1470b8
JH
726 sed "1,/^Signed-off-by: /d" out | grep "test message" &&
727 # Notes message must come after three dashes
728 ! sed "/^---$/q" out | grep "test message" &&
729 sed "1,/^---$/d" out | grep "test message"
f044fe2d
SB
730'
731
02bc5b03
BG
732echo "fatal: --name-only does not make sense" > expect.name-only
733echo "fatal: --name-status does not make sense" > expect.name-status
734echo "fatal: --check does not make sense" > expect.check
735
68b2a005 736test_expect_success 'options no longer allowed for format-patch' '
02bc5b03 737 test_must_fail git format-patch --name-only 2> output &&
68b2a005 738 test_i18ncmp expect.name-only output &&
02bc5b03 739 test_must_fail git format-patch --name-status 2> output &&
68b2a005 740 test_i18ncmp expect.name-status output &&
02bc5b03 741 test_must_fail git format-patch --check 2> output &&
68b2a005 742 test_i18ncmp expect.check output'
02bc5b03
BG
743
744test_expect_success 'format-patch --numstat should produce a patch' '
4fa80cf0 745 git format-patch --numstat --stdout master..side > output &&
5404c116 746 test 5 = $(grep "^diff --git a/" output | wc -l)'
02bc5b03 747
7e93d3b9
FC
748test_expect_success 'format-patch -- <path>' '
749 git format-patch master..side -- file 2>error &&
750 ! grep "Use .--" error
751'
752
657ab61e
KB
753test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
754 git format-patch --ignore-if-in-upstream HEAD
755'
756
480871e0
JT
757git_version="$(git --version | sed "s/.* //")"
758
759signature() {
760 printf "%s\n%s\n\n" "-- " "${1:-$git_version}"
761}
762
763test_expect_success 'format-patch default signature' '
764 git format-patch --stdout -1 | tail -n 3 >output &&
765 signature >expect &&
766 test_cmp expect output
767'
768
6622d9c7 769test_expect_success 'format-patch --signature' '
480871e0
JT
770 git format-patch --stdout --signature="my sig" -1 | tail -n 3 >output &&
771 signature "my sig" >expect &&
772 test_cmp expect output
6622d9c7
SB
773'
774
775test_expect_success 'format-patch with format.signature config' '
776 git config format.signature "config sig" &&
777 git format-patch --stdout -1 >output &&
778 grep "config sig" output
779'
780
781test_expect_success 'format-patch --signature overrides format.signature' '
782 git config format.signature "config sig" &&
783 git format-patch --stdout --signature="overrides" -1 >output &&
784 ! grep "config sig" output &&
785 grep "overrides" output
786'
787
788test_expect_success 'format-patch --no-signature ignores format.signature' '
789 git config format.signature "config sig" &&
790 git format-patch --stdout --signature="my sig" --no-signature \
791 -1 >output &&
cc663d14 792 check_patch output &&
6622d9c7
SB
793 ! grep "config sig" output &&
794 ! grep "my sig" output &&
795 ! grep "^-- \$" output
796'
797
798test_expect_success 'format-patch --signature --cover-letter' '
799 git config --unset-all format.signature &&
800 git format-patch --stdout --signature="my sig" --cover-letter \
801 -1 >output &&
802 grep "my sig" output &&
803 test 2 = $(grep "my sig" output | wc -l)
804'
805
41ccfdd9 806test_expect_success 'format.signature="" suppresses signatures' '
6622d9c7
SB
807 git config format.signature "" &&
808 git format-patch --stdout -1 >output &&
cc663d14 809 check_patch output &&
6622d9c7
SB
810 ! grep "^-- \$" output
811'
812
41ccfdd9 813test_expect_success 'format-patch --no-signature suppresses signatures' '
6622d9c7
SB
814 git config --unset-all format.signature &&
815 git format-patch --stdout --no-signature -1 >output &&
cc663d14 816 check_patch output &&
6622d9c7
SB
817 ! grep "^-- \$" output
818'
819
41ccfdd9 820test_expect_success 'format-patch --signature="" suppresses signatures' '
2fdb5c62 821 git format-patch --stdout --signature="" -1 >output &&
cc663d14 822 check_patch output &&
6622d9c7
SB
823 ! grep "^-- \$" output
824'
825
7022650f
JM
826test_expect_success 'prepare mail-signature input' '
827 cat >mail-signature <<-\EOF
828
829 Test User <test.email@kernel.org>
830 http://git.kernel.org/cgit/git/git.git
831
832 git.kernel.org/?p=git/git.git;a=summary
833
834 EOF
835'
836
837test_expect_success '--signature-file=file works' '
838 git format-patch --stdout --signature-file=mail-signature -1 >output &&
839 check_patch output &&
840 sed -e "1,/^-- \$/d" <output >actual &&
841 {
842 cat mail-signature && echo
843 } >expect &&
844 test_cmp expect actual
845'
846
847test_expect_success 'format.signaturefile works' '
848 test_config format.signaturefile mail-signature &&
849 git format-patch --stdout -1 >output &&
850 check_patch output &&
851 sed -e "1,/^-- \$/d" <output >actual &&
852 {
853 cat mail-signature && echo
854 } >expect &&
855 test_cmp expect actual
856'
857
858test_expect_success '--no-signature suppresses format.signaturefile ' '
859 test_config format.signaturefile mail-signature &&
860 git format-patch --stdout --no-signature -1 >output &&
861 check_patch output &&
862 ! grep "^-- \$" output
863'
864
865test_expect_success '--signature-file overrides format.signaturefile' '
99094a7a 866 cat >other-mail-signature <<-\EOF &&
7022650f
JM
867 Use this other signature instead of mail-signature.
868 EOF
869 test_config format.signaturefile mail-signature &&
870 git format-patch --stdout \
871 --signature-file=other-mail-signature -1 >output &&
872 check_patch output &&
873 sed -e "1,/^-- \$/d" <output >actual &&
874 {
875 cat other-mail-signature && echo
876 } >expect &&
877 test_cmp expect actual
878'
879
880test_expect_success '--signature overrides format.signaturefile' '
881 test_config format.signaturefile mail-signature &&
882 git format-patch --stdout --signature="my sig" -1 >output &&
883 check_patch output &&
884 grep "my sig" output
885'
886
38a94bb6
TRC
887test_expect_success TTY 'format-patch --stdout paginates' '
888 rm -f pager_used &&
512477b1 889 test_terminal env GIT_PAGER="wc >pager_used" git format-patch --stdout --all &&
38a94bb6
TRC
890 test_path_is_file pager_used
891'
892
893 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
894 rm -f pager_used &&
512477b1
DT
895 test_terminal env GIT_PAGER="wc >pager_used" git --no-pager format-patch --stdout --all &&
896 test_terminal env GIT_PAGER="wc >pager_used" git -c "pager.format-patch=false" format-patch --stdout --all &&
38a94bb6
TRC
897 test_path_is_missing pager_used &&
898 test_path_is_missing .git/pager_used
899'
900
a1f6baa5
JK
901test_expect_success 'format-patch handles multi-line subjects' '
902 rm -rf patches/ &&
903 echo content >>file &&
904 for i in one two three; do echo $i; done >msg &&
905 git add file &&
906 git commit -F msg &&
907 git format-patch -o patches -1 &&
908 grep ^Subject: patches/0001-one.patch >actual &&
909 echo "Subject: [PATCH] one two three" >expect &&
910 test_cmp expect actual
911'
912
913test_expect_success 'format-patch handles multi-line encoded subjects' '
914 rm -rf patches/ &&
915 echo content >>file &&
916 for i in en två tre; do echo $i; done >msg &&
917 git add file &&
918 git commit -F msg &&
919 git format-patch -o patches -1 &&
920 grep ^Subject: patches/0001-en.patch >actual &&
921 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
922 test_cmp expect actual
923'
924
925M8="foo bar "
926M64=$M8$M8$M8$M8$M8$M8$M8$M8
927M512=$M64$M64$M64$M64$M64$M64$M64$M64
928cat >expect <<'EOF'
929Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
7a76e68a
JS
930 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
931 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
932 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
933 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
934 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
935 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
a1f6baa5 936EOF
7a76e68a 937test_expect_success 'format-patch wraps extremely long subject (ascii)' '
a1f6baa5
JK
938 echo content >>file &&
939 git add file &&
940 git commit -m "$M512" &&
941 git format-patch --stdout -1 >patch &&
942 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
943 test_cmp expect subject
944'
945
946M8="föö bar "
947M64=$M8$M8$M8$M8$M8$M8$M8$M8
948M512=$M64$M64$M64$M64$M64$M64$M64$M64
949cat >expect <<'EOF'
94f6cdf6
JS
950Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
951 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
952 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
953 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
6cd3c053
KS
954 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
955 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
94f6cdf6
JS
956 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
957 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
958 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
6cd3c053
KS
959 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
960 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
94f6cdf6
JS
961 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
962 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
963 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
6cd3c053
KS
964 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
965 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
966 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
967 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
968 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
969 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
970 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
971 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
972 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
973 =?UTF-8?q?bar?=
a1f6baa5 974EOF
94f6cdf6 975test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
a1f6baa5
JK
976 rm -rf patches/ &&
977 echo content >>file &&
978 git add file &&
979 git commit -m "$M512" &&
980 git format-patch --stdout -1 >patch &&
981 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
982 test_cmp expect subject
983'
984
4d03c18a
JK
985check_author() {
986 echo content >>file &&
987 git add file &&
988 GIT_AUTHOR_NAME=$1 git commit -m author-check &&
989 git format-patch --stdout -1 >patch &&
7a76e68a 990 sed -n "/^From: /p; /^ /p; /^$/q" <patch >actual &&
4d03c18a
JK
991 test_cmp expect actual
992}
993
994cat >expect <<'EOF'
995From: "Foo B. Bar" <author@example.com>
996EOF
0fcec2ce 997test_expect_success 'format-patch quotes dot in from-headers' '
4d03c18a
JK
998 check_author "Foo B. Bar"
999'
1000
1001cat >expect <<'EOF'
1002From: "Foo \"The Baz\" Bar" <author@example.com>
1003EOF
0fcec2ce 1004test_expect_success 'format-patch quotes double-quote in from-headers' '
4d03c18a
JK
1005 check_author "Foo \"The Baz\" Bar"
1006'
1007
1008cat >expect <<'EOF'
0fcec2ce 1009From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
4d03c18a 1010EOF
0fcec2ce
JS
1011test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
1012 check_author "Föo Bar"
1013'
1014
1015cat >expect <<'EOF'
1016From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
1017EOF
41dd00ba 1018test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
4d03c18a
JK
1019 check_author "Föo B. Bar"
1020'
1021
7a76e68a
JS
1022cat >expect <<EOF
1023From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
1024 <author@example.com>
1025EOF
1026test_expect_success 'format-patch wraps moderately long from-header (ascii)' '
1027 check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
1028'
1029
1030cat >expect <<'EOF'
1031From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1032 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1033 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
1034EOF
1035test_expect_success 'format-patch wraps extremely long from-header (ascii)' '
1036 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"
1037'
1038
1039cat >expect <<'EOF'
1040From: "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1041 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1042 Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
1043EOF
1044test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
1045 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"
1046'
1047
4d03c18a 1048cat >expect <<'EOF'
94f6cdf6
JS
1049From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
1050 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
1051 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
1052 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
1053 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
1054EOF
1055test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
1056 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"
1057'
1058
1059cat >expect <<'EOF'
4d03c18a
JK
1060Subject: header with . in it
1061EOF
1062test_expect_success 'subject lines do not have 822 atom-quoting' '
1063 echo content >>file &&
1064 git add file &&
1065 git commit -m "header with . in it" &&
1066 git format-patch -k -1 --stdout >patch &&
1067 grep ^Subject: patch >actual &&
1068 test_cmp expect actual
1069'
1070
e7af8e49
JK
1071cat >expect <<'EOF'
1072Subject: [PREFIX 1/1] header with . in it
1073EOF
1074test_expect_success 'subject prefixes have space prepended' '
1075 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
1076 grep ^Subject: patch >actual &&
1077 test_cmp expect actual
1078'
1079
1080cat >expect <<'EOF'
1081Subject: [1/1] header with . in it
1082EOF
1083test_expect_success 'empty subject prefix does not have extra space' '
1084 git format-patch -n -1 --stdout --subject-prefix= >patch &&
1085 grep ^Subject: patch >actual &&
1086 test_cmp expect actual
1087'
1088
68e83a5b
JT
1089test_expect_success '--rfc' '
1090 cat >expect <<-\EOF &&
1091 Subject: [RFC PATCH 1/1] header with . in it
1092 EOF
1093 git format-patch -n -1 --stdout --rfc >patch &&
1094 grep ^Subject: patch >actual &&
1095 test_cmp expect actual
1096'
1097
a9080475
JK
1098test_expect_success '--from=ident notices bogus ident' '
1099 test_must_fail git format-patch -1 --stdout --from=foo >patch
1100'
1101
1102test_expect_success '--from=ident replaces author' '
1103 git format-patch -1 --stdout --from="Me <me@example.com>" >patch &&
1104 cat >expect <<-\EOF &&
1105 From: Me <me@example.com>
1106
1107 From: A U Thor <author@example.com>
1108
1109 EOF
1110 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1111 test_cmp expect patch.head
1112'
1113
1114test_expect_success '--from uses committer ident' '
1115 git format-patch -1 --stdout --from >patch &&
1116 cat >expect <<-\EOF &&
1117 From: C O Mitter <committer@example.com>
1118
1119 From: A U Thor <author@example.com>
1120
1121 EOF
1122 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1123 test_cmp expect patch.head
1124'
1125
662cc30c
JK
1126test_expect_success '--from omits redundant in-body header' '
1127 git format-patch -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1128 cat >expect <<-\EOF &&
1129 From: A U Thor <author@example.com>
1130
1131 EOF
1132 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1133 test_cmp expect patch.head
1134'
1135
a9080475 1136test_expect_success 'in-body headers trigger content encoding' '
d2554c72 1137 test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
a9080475
JK
1138 test_when_finished "git reset --hard HEAD^" &&
1139 git format-patch -1 --stdout --from >patch &&
1140 cat >expect <<-\EOF &&
1141 From: C O Mitter <committer@example.com>
1142 Content-Type: text/plain; charset=UTF-8
1143
1144 From: éxötìc <author@example.com>
1145
1146 EOF
1147 sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" <patch >patch.head &&
1148 test_cmp expect patch.head
1149'
1150
79133a66
NTND
1151append_signoff()
1152{
1153 C=$(git commit-tree HEAD^^{tree} -p HEAD) &&
1154 git format-patch --stdout --signoff $C^..$C >append_signoff.patch &&
1155 sed -n -e "1,/^---$/p" append_signoff.patch |
1156 egrep -n "^Subject|Sign|^$"
1157}
1158
1159test_expect_success 'signoff: commit with no body' '
1160 append_signoff </dev/null >actual &&
1161 cat <<\EOF | sed "s/EOL$//" >expected &&
11624:Subject: [PATCH] EOL
11638:
11649:Signed-off-by: C O Mitter <committer@example.com>
1165EOF
1166 test_cmp expected actual
1167'
1168
1169test_expect_success 'signoff: commit with only subject' '
1170 echo subject | append_signoff >actual &&
1171 cat >expected <<\EOF &&
11724:Subject: [PATCH] subject
11738:
11749:Signed-off-by: C O Mitter <committer@example.com>
1175EOF
1176 test_cmp expected actual
1177'
1178
1179test_expect_success 'signoff: commit with only subject that does not end with NL' '
1180 printf subject | append_signoff >actual &&
1181 cat >expected <<\EOF &&
11824:Subject: [PATCH] subject
11838:
11849:Signed-off-by: C O Mitter <committer@example.com>
1185EOF
1186 test_cmp expected actual
1187'
1188
1189test_expect_success 'signoff: no existing signoffs' '
1190 append_signoff <<\EOF >actual &&
1191subject
1192
1193body
1194EOF
1195 cat >expected <<\EOF &&
11964:Subject: [PATCH] subject
11978:
119810:
119911:Signed-off-by: C O Mitter <committer@example.com>
1200EOF
1201 test_cmp expected actual
1202'
1203
1204test_expect_success 'signoff: no existing signoffs and no trailing NL' '
1205 printf "subject\n\nbody" | append_signoff >actual &&
1206 cat >expected <<\EOF &&
12074:Subject: [PATCH] subject
12088:
120910:
121011:Signed-off-by: C O Mitter <committer@example.com>
1211EOF
1212 test_cmp expected actual
1213'
1214
1215test_expect_success 'signoff: some random signoff' '
1216 append_signoff <<\EOF >actual &&
1217subject
1218
1219body
1220
1221Signed-off-by: my@house
1222EOF
1223 cat >expected <<\EOF &&
12244:Subject: [PATCH] subject
12258:
122610:
122711:Signed-off-by: my@house
122812:Signed-off-by: C O Mitter <committer@example.com>
1229EOF
1230 test_cmp expected actual
1231'
1232
959a2623
BC
1233test_expect_success 'signoff: misc conforming footer elements' '
1234 append_signoff <<\EOF >actual &&
1235subject
1236
1237body
1238
1239Signed-off-by: my@house
1240(cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1241Tested-by: Some One <someone@example.com>
1242Bug: 1234
1243EOF
1244 cat >expected <<\EOF &&
12454:Subject: [PATCH] subject
12468:
124710:
124811:Signed-off-by: my@house
124915:Signed-off-by: C O Mitter <committer@example.com>
1250EOF
1251 test_cmp expected actual
1252'
1253
1254test_expect_success 'signoff: some random signoff-alike' '
79133a66
NTND
1255 append_signoff <<\EOF >actual &&
1256subject
1257
1258body
1259Fooled-by-me: my@house
1260EOF
1261 cat >expected <<\EOF &&
12624:Subject: [PATCH] subject
12638:
126411:
126512:Signed-off-by: C O Mitter <committer@example.com>
1266EOF
1267 test_cmp expected actual
1268'
1269
959a2623 1270test_expect_success 'signoff: not really a signoff' '
79133a66
NTND
1271 append_signoff <<\EOF >actual &&
1272subject
1273
1274I want to mention about Signed-off-by: here.
1275EOF
1276 cat >expected <<\EOF &&
12774:Subject: [PATCH] subject
12788:
12799:I want to mention about Signed-off-by: here.
128010:
128111:Signed-off-by: C O Mitter <committer@example.com>
1282EOF
1283 test_cmp expected actual
1284'
1285
959a2623 1286test_expect_success 'signoff: not really a signoff (2)' '
79133a66
NTND
1287 append_signoff <<\EOF >actual &&
1288subject
1289
1290My unfortunate
1291Signed-off-by: example happens to be wrapped here.
1292EOF
1293 cat >expected <<\EOF &&
12944:Subject: [PATCH] subject
12958:
129610:Signed-off-by: example happens to be wrapped here.
967dfd4d 129711:Signed-off-by: C O Mitter <committer@example.com>
79133a66
NTND
1298EOF
1299 test_cmp expected actual
1300'
1301
959a2623 1302test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
79133a66
NTND
1303 append_signoff <<\EOF >actual &&
1304subject
1305
1306Signed-off-by: my@house
1307Signed-off-by: your@house
1308
1309A lot of houses.
1310EOF
1311 cat >expected <<\EOF &&
13124:Subject: [PATCH] subject
13138:
13149:Signed-off-by: my@house
131510:Signed-off-by: your@house
131611:
131713:
131814:Signed-off-by: C O Mitter <committer@example.com>
1319EOF
1320 test_cmp expected actual
1321'
1322
1323test_expect_success 'signoff: the same signoff at the end' '
1324 append_signoff <<\EOF >actual &&
1325subject
1326
1327body
1328
1329Signed-off-by: C O Mitter <committer@example.com>
1330EOF
1331 cat >expected <<\EOF &&
13324:Subject: [PATCH] subject
13338:
133410:
133511:Signed-off-by: C O Mitter <committer@example.com>
1336EOF
1337 test_cmp expected actual
1338'
1339
1340test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
1341 printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
1342 append_signoff >actual &&
1343 cat >expected <<\EOF &&
13444:Subject: [PATCH] subject
13458:
13469:Signed-off-by: C O Mitter <committer@example.com>
1347EOF
1348 test_cmp expected actual
1349'
1350
1351test_expect_success 'signoff: the same signoff NOT at the end' '
1352 append_signoff <<\EOF >actual &&
1353subject
1354
1355body
1356
1357Signed-off-by: C O Mitter <committer@example.com>
1358Signed-off-by: my@house
1359EOF
1360 cat >expected <<\EOF &&
13614:Subject: [PATCH] subject
13628:
136310:
136411:Signed-off-by: C O Mitter <committer@example.com>
136512:Signed-off-by: my@house
1366EOF
1367 test_cmp expected actual
1368'
1369
967dfd4d 1370test_expect_success 'signoff: tolerate garbage in conforming footer' '
79133a66
NTND
1371 append_signoff <<\EOF >actual &&
1372subject
1373
1374body
1375
1376Tested-by: my@house
1377Some Trash
1378Signed-off-by: C O Mitter <committer@example.com>
1379EOF
1380 cat >expected <<\EOF &&
13814:Subject: [PATCH] subject
13828:
138310:
138413:Signed-off-by: C O Mitter <committer@example.com>
967dfd4d
JT
1385EOF
1386 test_cmp expected actual
1387'
1388
1389test_expect_success 'signoff: respect trailer config' '
1390 append_signoff <<\EOF >actual &&
1391subject
1392
1393Myfooter: x
1394Some Trash
1395EOF
1396 cat >expected <<\EOF &&
13974:Subject: [PATCH] subject
13988:
139911:
140012:Signed-off-by: C O Mitter <committer@example.com>
1401EOF
1402 test_cmp expected actual &&
1403
1404 test_config trailer.Myfooter.ifexists add &&
1405 append_signoff <<\EOF >actual &&
1406subject
1407
1408Myfooter: x
1409Some Trash
1410EOF
1411 cat >expected <<\EOF &&
14124:Subject: [PATCH] subject
14138:
141411:Signed-off-by: C O Mitter <committer@example.com>
79133a66
NTND
1415EOF
1416 test_cmp expected actual
1417'
1418
1419test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
1420 append_signoff <<\EOF >actual &&
1421subject
1422
1423body
1424
1425Reviewed-id: Noone
1426Tested-by: my@house
1427Change-id: Ideadbeef
1428Signed-off-by: C O Mitter <committer@example.com>
1429Bug: 1234
1430EOF
1431 cat >expected <<\EOF &&
14324:Subject: [PATCH] subject
14338:
143410:
143514:Signed-off-by: C O Mitter <committer@example.com>
1436EOF
1437 test_cmp expected actual
1438'
1439
787570c7
PYH
1440test_expect_success 'format patch ignores color.ui' '
1441 test_unconfig color.ui &&
1442 git format-patch --stdout -1 >expect &&
1443 test_config color.ui always &&
1444 git format-patch --stdout -1 >actual &&
1445 test_cmp expect actual
1446'
1447
e216cc48
NTND
1448test_expect_success 'cover letter using branch description (1)' '
1449 git checkout rebuild-1 &&
1450 test_config branch.rebuild-1.description hello &&
1451 git format-patch --stdout --cover-letter master >actual &&
1452 grep hello actual >/dev/null
1453'
1454
1455test_expect_success 'cover letter using branch description (2)' '
1456 git checkout rebuild-1 &&
1457 test_config branch.rebuild-1.description hello &&
1458 git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
1459 grep hello actual >/dev/null
1460'
1461
1462test_expect_success 'cover letter using branch description (3)' '
1463 git checkout rebuild-1 &&
1464 test_config branch.rebuild-1.description hello &&
1465 git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
1466 grep hello actual >/dev/null
1467'
1468
20b630aa
NTND
1469test_expect_success 'cover letter using branch description (4)' '
1470 git checkout rebuild-1 &&
1471 test_config branch.rebuild-1.description hello &&
1472 git format-patch --stdout --cover-letter master.. >actual &&
1473 grep hello actual >/dev/null
1474'
1475
1476test_expect_success 'cover letter using branch description (5)' '
1477 git checkout rebuild-1 &&
1478 test_config branch.rebuild-1.description hello &&
1479 git format-patch --stdout --cover-letter -2 HEAD >actual &&
1480 grep hello actual >/dev/null
1481'
1482
5ee29aef
NTND
1483test_expect_success 'cover letter using branch description (6)' '
1484 git checkout rebuild-1 &&
1485 test_config branch.rebuild-1.description hello &&
1486 git format-patch --stdout --cover-letter -2 >actual &&
1487 grep hello actual >/dev/null
1488'
1489
80d35ca0
FC
1490test_expect_success 'cover letter with nothing' '
1491 git format-patch --stdout --cover-letter >actual &&
1492 test_line_count = 0 actual
1493'
1494
2a4c2607
FC
1495test_expect_success 'cover letter auto' '
1496 mkdir -p tmp &&
1497 test_when_finished "rm -rf tmp;
1498 git config --unset format.coverletter" &&
1499
1500 git config format.coverletter auto &&
1501 git format-patch -o tmp -1 >list &&
1502 test_line_count = 1 list &&
1503 git format-patch -o tmp -2 >list &&
1504 test_line_count = 3 list
1505'
1506
1507test_expect_success 'cover letter auto user override' '
1508 mkdir -p tmp &&
1509 test_when_finished "rm -rf tmp;
1510 git config --unset format.coverletter" &&
1511
1512 git config format.coverletter auto &&
1513 git format-patch -o tmp --cover-letter -1 >list &&
1514 test_line_count = 2 list &&
1515 git format-patch -o tmp --cover-letter -2 >list &&
1516 test_line_count = 3 list &&
1517 git format-patch -o tmp --no-cover-letter -1 >list &&
1518 test_line_count = 1 list &&
1519 git format-patch -o tmp --no-cover-letter -2 >list &&
1520 test_line_count = 2 list
1521'
1522
3a30aa17 1523test_expect_success 'format-patch --zero-commit' '
1524 git format-patch --zero-commit --stdout v2..v1 >patch2 &&
1525 grep "^From " patch2 | sort | uniq >actual &&
1526 echo "From $_z40 Mon Sep 17 00:00:00 2001" >expect &&
1527 test_cmp expect actual
1528'
1529
06dfc9eb 1530test_expect_success 'From line has expected format' '
1531 git format-patch --stdout v2..v1 >patch2 &&
1532 grep "^From " patch2 >from &&
1533 grep "^From $_x40 Mon Sep 17 00:00:00 2001$" patch2 >filtered &&
1534 test_cmp from filtered
1535'
1536
bc6bf2d7
AK
1537test_expect_success 'format-patch format.outputDirectory option' '
1538 test_config format.outputDirectory patches &&
1539 rm -fr patches &&
1540 git format-patch master..side &&
1541 test $(git rev-list master..side | wc -l) -eq $(ls patches | wc -l)
1542'
1543
1544test_expect_success 'format-patch -o overrides format.outputDirectory' '
1545 test_config format.outputDirectory patches &&
1546 rm -fr patches patchset &&
1547 git format-patch master..side -o patchset &&
1548 test_path_is_missing patches &&
1549 test_path_is_dir patchset
1550'
1551
fa2ab86d
XY
1552test_expect_success 'format-patch --base' '
1553 git checkout side &&
480871e0
JT
1554 git format-patch --stdout --base=HEAD~3 -1 | tail -n 7 >actual &&
1555 echo >expected &&
1556 echo "base-commit: $(git rev-parse HEAD~3)" >>expected &&
fa2ab86d
XY
1557 echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1558 echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected &&
480871e0 1559 signature >> expected &&
fa2ab86d
XY
1560 test_cmp expected actual
1561'
1562
1563test_expect_success 'format-patch --base errors out when base commit is in revision list' '
1564 test_must_fail git format-patch --base=HEAD -2 &&
1565 test_must_fail git format-patch --base=HEAD~1 -2 &&
1566 git format-patch --stdout --base=HEAD~2 -2 >patch &&
1567 grep "^base-commit:" patch >actual &&
1568 echo "base-commit: $(git rev-parse HEAD~2)" >expected &&
1569 test_cmp expected actual
1570'
1571
1572test_expect_success 'format-patch --base errors out when base commit is not ancestor of revision list' '
1573 # For history as below:
1574 #
1575 # ---Q---P---Z---Y---*---X
1576 # \ /
1577 # ------------W
1578 #
1579 # If "format-patch Z..X" is given, P and Z can not be specified as the base commit
1580 git checkout -b topic1 master &&
1581 git rev-parse HEAD >commit-id-base &&
1582 test_commit P &&
1583 git rev-parse HEAD >commit-id-P &&
1584 test_commit Z &&
1585 git rev-parse HEAD >commit-id-Z &&
1586 test_commit Y &&
1587 git checkout -b topic2 master &&
1588 test_commit W &&
1589 git merge topic1 &&
1590 test_commit X &&
1591 test_must_fail git format-patch --base=$(cat commit-id-P) -3 &&
1592 test_must_fail git format-patch --base=$(cat commit-id-Z) -3 &&
1593 git format-patch --stdout --base=$(cat commit-id-base) -3 >patch &&
1594 grep "^base-commit:" patch >actual &&
1595 echo "base-commit: $(cat commit-id-base)" >expected &&
1596 test_cmp expected actual
1597'
1598
3de66517
XY
1599test_expect_success 'format-patch --base=auto' '
1600 git checkout -b upstream master &&
1601 git checkout -b local upstream &&
1602 git branch --set-upstream-to=upstream &&
1603 test_commit N1 &&
1604 test_commit N2 &&
1605 git format-patch --stdout --base=auto -2 >patch &&
1606 grep "^base-commit:" patch >actual &&
1607 echo "base-commit: $(git rev-parse upstream)" >expected &&
1608 test_cmp expected actual
1609'
1610
1611test_expect_success 'format-patch errors out when history involves criss-cross' '
1612 # setup criss-cross history
1613 #
1614 # B---M1---D
1615 # / \ /
1616 # A X
1617 # \ / \
1618 # C---M2---E
1619 #
1620 git checkout master &&
1621 test_commit A &&
1622 git checkout -b xb master &&
1623 test_commit B &&
1624 git checkout -b xc master &&
1625 test_commit C &&
1626 git checkout -b xbc xb -- &&
1627 git merge xc &&
1628 git checkout -b xcb xc -- &&
1629 git branch --set-upstream-to=xbc &&
1630 git merge xb &&
1631 git checkout xbc &&
1632 test_commit D &&
1633 git checkout xcb &&
1634 test_commit E &&
1635 test_must_fail git format-patch --base=auto -1
1636'
1637
bb52995f
XY
1638test_expect_success 'format-patch format.useAutoBaseoption' '
1639 test_when_finished "git config --unset format.useAutoBase" &&
1640 git checkout local &&
1641 git config format.useAutoBase true &&
1642 git format-patch --stdout -1 >patch &&
1643 grep "^base-commit:" patch >actual &&
1644 echo "base-commit: $(git rev-parse upstream)" >expected &&
1645 test_cmp expected actual
1646'
1647
1648test_expect_success 'format-patch --base overrides format.useAutoBase' '
1649 test_when_finished "git config --unset format.useAutoBase" &&
1650 git config format.useAutoBase true &&
1651 git format-patch --stdout --base=HEAD~1 -1 >patch &&
1652 grep "^base-commit:" patch >actual &&
1653 echo "base-commit: $(git rev-parse HEAD~1)" >expected &&
1654 test_cmp expected actual
1655'
1656
480871e0
JT
1657test_expect_success 'format-patch --base with --attach' '
1658 git format-patch --attach=mimemime --stdout --base=HEAD~ -1 >patch &&
1659 sed -n -e "/^base-commit:/s/.*/1/p" -e "/^---*mimemime--$/s/.*/2/p" \
1660 patch >actual &&
1661 test_write_lines 1 2 >expect &&
1662 test_cmp expect actual
1663'
1664
9f23e040
EW
1665test_expect_success 'format-patch --pretty=mboxrd' '
1666 sp=" " &&
1667 cat >msg <<-INPUT_END &&
1668 mboxrd should escape the body
1669
1670 From could trip up a loose mbox parser
1671 >From extra escape for reversibility
1672 >>From extra escape for reversibility 2
1673 from lower case not escaped
1674 Fromm bad speling not escaped
1675 From with leading space not escaped
1676
1677 F
1678 From
1679 From$sp
1680 From $sp
1681 From $sp
1682 INPUT_END
1683
1684 cat >expect <<-INPUT_END &&
1685 >From could trip up a loose mbox parser
1686 >>From extra escape for reversibility
1687 >>>From extra escape for reversibility 2
1688 from lower case not escaped
1689 Fromm bad speling not escaped
1690 From with leading space not escaped
1691
1692 F
1693 From
1694 From
1695 From
1696 From
1697 INPUT_END
1698
1699 C=$(git commit-tree HEAD^^{tree} -p HEAD <msg) &&
1700 git format-patch --pretty=mboxrd --stdout -1 $C~1..$C >patch &&
1701 git grep -h --no-index -A11 \
1702 "^>From could trip up a loose mbox parser" patch >actual &&
1703 test_cmp expect actual
1704'
1705
ece3c67f 1706test_done