]> git.ipfire.org Git - thirdparty/git.git/blame - t/t4014-format-patch.sh
builtin/log: downcase the beginning of error messages
[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 &&
bdee9cd6 581 before=$(git hash-object file) &&
582 before=$(git rev-parse --short $before) &&
7d812145 583 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
bdee9cd6 584 after=$(git hash-object file) &&
585 after=$(git rev-parse --short $after) &&
7d812145
DB
586 git update-index file &&
587 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." &&
588 git format-patch -o patches/ master..side &&
589 ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
590'
591
5d02294c 592test_expect_success 'cover-letter inherits diff options' '
5d02294c
JS
593 git mv file foo &&
594 git commit -m foo &&
5404c116 595 git format-patch --no-renames --cover-letter -1 &&
cc663d14 596 check_patch 0000-cover-letter.patch &&
9524cf29 597 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
5d02294c 598 git format-patch --cover-letter -1 -M &&
9524cf29 599 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
5d02294c
JS
600
601'
859c4fbe
JS
602
603cat > expect << EOF
604 This is an excessively long subject line for a message due to the
605 habit some projects have of not having a short, one-line subject at
606 the start of the commit message, but rather sticking a whole
607 paragraph right at the start as the only thing in the commit
608 message. It had better not become the filename for the patch.
609 foo
610
611EOF
612
613test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
614
615 git format-patch --cover-letter -2 &&
9524cf29 616 sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
3af82863 617 test_cmp expect output
859c4fbe
JS
618
619'
620
68daa64d 621cat > expect << EOF
bdee9cd6 622index $before..$after 100644
68daa64d
JK
623--- a/file
624+++ b/file
625@@ -13,4 +13,20 @@ C
626 10
627 D
628 E
629 F
630+5
631EOF
632
633test_expect_success 'format-patch respects -U' '
634
635 git format-patch -U4 -2 &&
6dd88832
JN
636 sed -e "1,/^diff/d" -e "/^+5/q" \
637 <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
638 >output &&
68daa64d
JK
639 test_cmp expect output
640
641'
642
1d46f2ea
JK
643cat > expect << EOF
644
645diff --git a/file b/file
bdee9cd6 646index $before..$after 100644
1d46f2ea
JK
647--- a/file
648+++ b/file
649@@ -14,3 +14,19 @@ C
650 D
651 E
652 F
653+5
654EOF
655
656test_expect_success 'format-patch -p suppresses stat' '
657
658 git format-patch -p -2 &&
9524cf29 659 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
1d46f2ea
JK
660 test_cmp expect output
661
662'
663
9800a754
JH
664test_expect_success 'format-patch from a subdirectory (1)' '
665 filename=$(
666 rm -rf sub &&
667 mkdir -p sub/dir &&
668 cd sub/dir &&
669 git format-patch -1
670 ) &&
671 case "$filename" in
672 0*)
673 ;; # ok
674 *)
675 echo "Oops? $filename"
676 false
677 ;;
678 esac &&
679 test -f "$filename"
680'
681
682test_expect_success 'format-patch from a subdirectory (2)' '
683 filename=$(
684 rm -rf sub &&
685 mkdir -p sub/dir &&
686 cd sub/dir &&
687 git format-patch -1 -o ..
688 ) &&
689 case "$filename" in
690 ../0*)
691 ;; # ok
692 *)
693 echo "Oops? $filename"
694 false
695 ;;
696 esac &&
697 basename=$(expr "$filename" : ".*/\(.*\)") &&
698 test -f "sub/$basename"
699'
700
701test_expect_success 'format-patch from a subdirectory (3)' '
9800a754
JH
702 rm -f 0* &&
703 filename=$(
704 rm -rf sub &&
705 mkdir -p sub/dir &&
706 cd sub/dir &&
91c8b825 707 git format-patch -1 -o "$TRASH_DIRECTORY"
9800a754
JH
708 ) &&
709 basename=$(expr "$filename" : ".*/\(.*\)") &&
710 test -f "$basename"
711'
712
f044fe2d
SB
713test_expect_success 'format-patch --in-reply-to' '
714 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
715 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
716 grep "^References: <baz@foo.bar>" patch8
717'
718
719test_expect_success 'format-patch --signoff' '
212620fe
JH
720 git format-patch -1 --signoff --stdout >out &&
721 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
722'
723
724test_expect_success 'format-patch --notes --signoff' '
725 git notes --ref test add -m "test message" HEAD &&
726 git format-patch -1 --signoff --stdout --notes=test >out &&
bd1470b8 727 # Three dashes must come after S-o-b
212620fe 728 ! sed "/^Signed-off-by: /q" out | grep "test message" &&
bd1470b8
JH
729 sed "1,/^Signed-off-by: /d" out | grep "test message" &&
730 # Notes message must come after three dashes
731 ! sed "/^---$/q" out | grep "test message" &&
732 sed "1,/^---$/d" out | grep "test message"
f044fe2d
SB
733'
734
02bc5b03
BG
735echo "fatal: --name-only does not make sense" > expect.name-only
736echo "fatal: --name-status does not make sense" > expect.name-status
737echo "fatal: --check does not make sense" > expect.check
738
68b2a005 739test_expect_success 'options no longer allowed for format-patch' '
02bc5b03 740 test_must_fail git format-patch --name-only 2> output &&
68b2a005 741 test_i18ncmp expect.name-only output &&
02bc5b03 742 test_must_fail git format-patch --name-status 2> output &&
68b2a005 743 test_i18ncmp expect.name-status output &&
02bc5b03 744 test_must_fail git format-patch --check 2> output &&
68b2a005 745 test_i18ncmp expect.check output'
02bc5b03
BG
746
747test_expect_success 'format-patch --numstat should produce a patch' '
4fa80cf0 748 git format-patch --numstat --stdout master..side > output &&
5404c116 749 test 5 = $(grep "^diff --git a/" output | wc -l)'
02bc5b03 750
7e93d3b9
FC
751test_expect_success 'format-patch -- <path>' '
752 git format-patch master..side -- file 2>error &&
753 ! grep "Use .--" error
754'
755
657ab61e
KB
756test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
757 git format-patch --ignore-if-in-upstream HEAD
758'
759
480871e0
JT
760git_version="$(git --version | sed "s/.* //")"
761
762signature() {
763 printf "%s\n%s\n\n" "-- " "${1:-$git_version}"
764}
765
766test_expect_success 'format-patch default signature' '
767 git format-patch --stdout -1 | tail -n 3 >output &&
768 signature >expect &&
769 test_cmp expect output
770'
771
6622d9c7 772test_expect_success 'format-patch --signature' '
480871e0
JT
773 git format-patch --stdout --signature="my sig" -1 | tail -n 3 >output &&
774 signature "my sig" >expect &&
775 test_cmp expect output
6622d9c7
SB
776'
777
778test_expect_success 'format-patch with format.signature config' '
779 git config format.signature "config sig" &&
780 git format-patch --stdout -1 >output &&
781 grep "config sig" output
782'
783
784test_expect_success 'format-patch --signature overrides format.signature' '
785 git config format.signature "config sig" &&
786 git format-patch --stdout --signature="overrides" -1 >output &&
787 ! grep "config sig" output &&
788 grep "overrides" output
789'
790
791test_expect_success 'format-patch --no-signature ignores format.signature' '
792 git config format.signature "config sig" &&
793 git format-patch --stdout --signature="my sig" --no-signature \
794 -1 >output &&
cc663d14 795 check_patch output &&
6622d9c7
SB
796 ! grep "config sig" output &&
797 ! grep "my sig" output &&
798 ! grep "^-- \$" output
799'
800
801test_expect_success 'format-patch --signature --cover-letter' '
802 git config --unset-all format.signature &&
803 git format-patch --stdout --signature="my sig" --cover-letter \
804 -1 >output &&
805 grep "my sig" output &&
806 test 2 = $(grep "my sig" output | wc -l)
807'
808
41ccfdd9 809test_expect_success 'format.signature="" suppresses signatures' '
6622d9c7
SB
810 git config format.signature "" &&
811 git format-patch --stdout -1 >output &&
cc663d14 812 check_patch output &&
6622d9c7
SB
813 ! grep "^-- \$" output
814'
815
41ccfdd9 816test_expect_success 'format-patch --no-signature suppresses signatures' '
6622d9c7
SB
817 git config --unset-all format.signature &&
818 git format-patch --stdout --no-signature -1 >output &&
cc663d14 819 check_patch output &&
6622d9c7
SB
820 ! grep "^-- \$" output
821'
822
41ccfdd9 823test_expect_success 'format-patch --signature="" suppresses signatures' '
2fdb5c62 824 git format-patch --stdout --signature="" -1 >output &&
cc663d14 825 check_patch output &&
6622d9c7
SB
826 ! grep "^-- \$" output
827'
828
7022650f
JM
829test_expect_success 'prepare mail-signature input' '
830 cat >mail-signature <<-\EOF
831
832 Test User <test.email@kernel.org>
833 http://git.kernel.org/cgit/git/git.git
834
835 git.kernel.org/?p=git/git.git;a=summary
836
837 EOF
838'
839
840test_expect_success '--signature-file=file works' '
841 git format-patch --stdout --signature-file=mail-signature -1 >output &&
842 check_patch output &&
843 sed -e "1,/^-- \$/d" <output >actual &&
844 {
845 cat mail-signature && echo
846 } >expect &&
847 test_cmp expect actual
848'
849
850test_expect_success 'format.signaturefile works' '
851 test_config format.signaturefile mail-signature &&
852 git format-patch --stdout -1 >output &&
853 check_patch output &&
854 sed -e "1,/^-- \$/d" <output >actual &&
855 {
856 cat mail-signature && echo
857 } >expect &&
858 test_cmp expect actual
859'
860
861test_expect_success '--no-signature suppresses format.signaturefile ' '
862 test_config format.signaturefile mail-signature &&
863 git format-patch --stdout --no-signature -1 >output &&
864 check_patch output &&
865 ! grep "^-- \$" output
866'
867
868test_expect_success '--signature-file overrides format.signaturefile' '
99094a7a 869 cat >other-mail-signature <<-\EOF &&
7022650f
JM
870 Use this other signature instead of mail-signature.
871 EOF
872 test_config format.signaturefile mail-signature &&
873 git format-patch --stdout \
874 --signature-file=other-mail-signature -1 >output &&
875 check_patch output &&
876 sed -e "1,/^-- \$/d" <output >actual &&
877 {
878 cat other-mail-signature && echo
879 } >expect &&
880 test_cmp expect actual
881'
882
883test_expect_success '--signature overrides format.signaturefile' '
884 test_config format.signaturefile mail-signature &&
885 git format-patch --stdout --signature="my sig" -1 >output &&
886 check_patch output &&
887 grep "my sig" output
888'
889
38a94bb6
TRC
890test_expect_success TTY 'format-patch --stdout paginates' '
891 rm -f pager_used &&
512477b1 892 test_terminal env GIT_PAGER="wc >pager_used" git format-patch --stdout --all &&
38a94bb6
TRC
893 test_path_is_file pager_used
894'
895
896 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
897 rm -f pager_used &&
512477b1
DT
898 test_terminal env GIT_PAGER="wc >pager_used" git --no-pager format-patch --stdout --all &&
899 test_terminal env GIT_PAGER="wc >pager_used" git -c "pager.format-patch=false" format-patch --stdout --all &&
38a94bb6
TRC
900 test_path_is_missing pager_used &&
901 test_path_is_missing .git/pager_used
902'
903
a1f6baa5
JK
904test_expect_success 'format-patch handles multi-line subjects' '
905 rm -rf patches/ &&
906 echo content >>file &&
907 for i in one two three; do echo $i; done >msg &&
908 git add file &&
909 git commit -F msg &&
910 git format-patch -o patches -1 &&
911 grep ^Subject: patches/0001-one.patch >actual &&
912 echo "Subject: [PATCH] one two three" >expect &&
913 test_cmp expect actual
914'
915
916test_expect_success 'format-patch handles multi-line encoded subjects' '
917 rm -rf patches/ &&
918 echo content >>file &&
919 for i in en två tre; do echo $i; done >msg &&
920 git add file &&
921 git commit -F msg &&
922 git format-patch -o patches -1 &&
923 grep ^Subject: patches/0001-en.patch >actual &&
924 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
925 test_cmp expect actual
926'
927
928M8="foo bar "
929M64=$M8$M8$M8$M8$M8$M8$M8$M8
930M512=$M64$M64$M64$M64$M64$M64$M64$M64
931cat >expect <<'EOF'
932Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
7a76e68a
JS
933 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
934 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
935 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
936 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
937 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
938 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
a1f6baa5 939EOF
7a76e68a 940test_expect_success 'format-patch wraps extremely long subject (ascii)' '
a1f6baa5
JK
941 echo content >>file &&
942 git add file &&
943 git commit -m "$M512" &&
944 git format-patch --stdout -1 >patch &&
945 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
946 test_cmp expect subject
947'
948
949M8="föö bar "
950M64=$M8$M8$M8$M8$M8$M8$M8$M8
951M512=$M64$M64$M64$M64$M64$M64$M64$M64
952cat >expect <<'EOF'
94f6cdf6
JS
953Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
954 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
955 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
956 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
6cd3c053
KS
957 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
958 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
94f6cdf6
JS
959 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
960 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
961 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
6cd3c053
KS
962 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
963 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
94f6cdf6
JS
964 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
965 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
966 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
6cd3c053
KS
967 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
968 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
969 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
970 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
971 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
972 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
973 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
974 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
975 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
976 =?UTF-8?q?bar?=
a1f6baa5 977EOF
94f6cdf6 978test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
a1f6baa5
JK
979 rm -rf patches/ &&
980 echo content >>file &&
981 git add file &&
982 git commit -m "$M512" &&
983 git format-patch --stdout -1 >patch &&
984 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
985 test_cmp expect subject
986'
987
4d03c18a
JK
988check_author() {
989 echo content >>file &&
990 git add file &&
991 GIT_AUTHOR_NAME=$1 git commit -m author-check &&
992 git format-patch --stdout -1 >patch &&
7a76e68a 993 sed -n "/^From: /p; /^ /p; /^$/q" <patch >actual &&
4d03c18a
JK
994 test_cmp expect actual
995}
996
997cat >expect <<'EOF'
998From: "Foo B. Bar" <author@example.com>
999EOF
0fcec2ce 1000test_expect_success 'format-patch quotes dot in from-headers' '
4d03c18a
JK
1001 check_author "Foo B. Bar"
1002'
1003
1004cat >expect <<'EOF'
1005From: "Foo \"The Baz\" Bar" <author@example.com>
1006EOF
0fcec2ce 1007test_expect_success 'format-patch quotes double-quote in from-headers' '
4d03c18a
JK
1008 check_author "Foo \"The Baz\" Bar"
1009'
1010
1011cat >expect <<'EOF'
0fcec2ce 1012From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
4d03c18a 1013EOF
0fcec2ce
JS
1014test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
1015 check_author "Föo Bar"
1016'
1017
1018cat >expect <<'EOF'
1019From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
1020EOF
41dd00ba 1021test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
4d03c18a
JK
1022 check_author "Föo B. Bar"
1023'
1024
7a76e68a
JS
1025cat >expect <<EOF
1026From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
1027 <author@example.com>
1028EOF
1029test_expect_success 'format-patch wraps moderately long from-header (ascii)' '
1030 check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
1031'
1032
1033cat >expect <<'EOF'
1034From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1035 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1036 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
1037EOF
1038test_expect_success 'format-patch wraps extremely long from-header (ascii)' '
1039 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"
1040'
1041
1042cat >expect <<'EOF'
1043From: "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1044 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1045 Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
1046EOF
1047test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
1048 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"
1049'
1050
4d03c18a 1051cat >expect <<'EOF'
94f6cdf6
JS
1052From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
1053 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
1054 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
1055 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
1056 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
1057EOF
1058test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
1059 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"
1060'
1061
1062cat >expect <<'EOF'
4d03c18a
JK
1063Subject: header with . in it
1064EOF
1065test_expect_success 'subject lines do not have 822 atom-quoting' '
1066 echo content >>file &&
1067 git add file &&
1068 git commit -m "header with . in it" &&
1069 git format-patch -k -1 --stdout >patch &&
1070 grep ^Subject: patch >actual &&
1071 test_cmp expect actual
1072'
1073
e7af8e49
JK
1074cat >expect <<'EOF'
1075Subject: [PREFIX 1/1] header with . in it
1076EOF
1077test_expect_success 'subject prefixes have space prepended' '
1078 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
1079 grep ^Subject: patch >actual &&
1080 test_cmp expect actual
1081'
1082
1083cat >expect <<'EOF'
1084Subject: [1/1] header with . in it
1085EOF
1086test_expect_success 'empty subject prefix does not have extra space' '
1087 git format-patch -n -1 --stdout --subject-prefix= >patch &&
1088 grep ^Subject: patch >actual &&
1089 test_cmp expect actual
1090'
1091
68e83a5b
JT
1092test_expect_success '--rfc' '
1093 cat >expect <<-\EOF &&
1094 Subject: [RFC PATCH 1/1] header with . in it
1095 EOF
1096 git format-patch -n -1 --stdout --rfc >patch &&
1097 grep ^Subject: patch >actual &&
1098 test_cmp expect actual
1099'
1100
a9080475
JK
1101test_expect_success '--from=ident notices bogus ident' '
1102 test_must_fail git format-patch -1 --stdout --from=foo >patch
1103'
1104
1105test_expect_success '--from=ident replaces author' '
1106 git format-patch -1 --stdout --from="Me <me@example.com>" >patch &&
1107 cat >expect <<-\EOF &&
1108 From: Me <me@example.com>
1109
1110 From: A U Thor <author@example.com>
1111
1112 EOF
1113 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1114 test_cmp expect patch.head
1115'
1116
1117test_expect_success '--from uses committer ident' '
1118 git format-patch -1 --stdout --from >patch &&
1119 cat >expect <<-\EOF &&
1120 From: C O Mitter <committer@example.com>
1121
1122 From: A U Thor <author@example.com>
1123
1124 EOF
1125 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1126 test_cmp expect patch.head
1127'
1128
662cc30c
JK
1129test_expect_success '--from omits redundant in-body header' '
1130 git format-patch -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1131 cat >expect <<-\EOF &&
1132 From: A U Thor <author@example.com>
1133
1134 EOF
1135 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1136 test_cmp expect patch.head
1137'
1138
a9080475 1139test_expect_success 'in-body headers trigger content encoding' '
d2554c72 1140 test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
a9080475
JK
1141 test_when_finished "git reset --hard HEAD^" &&
1142 git format-patch -1 --stdout --from >patch &&
1143 cat >expect <<-\EOF &&
1144 From: C O Mitter <committer@example.com>
1145 Content-Type: text/plain; charset=UTF-8
1146
1147 From: éxötìc <author@example.com>
1148
1149 EOF
1150 sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" <patch >patch.head &&
1151 test_cmp expect patch.head
1152'
1153
79133a66
NTND
1154append_signoff()
1155{
1156 C=$(git commit-tree HEAD^^{tree} -p HEAD) &&
1157 git format-patch --stdout --signoff $C^..$C >append_signoff.patch &&
1158 sed -n -e "1,/^---$/p" append_signoff.patch |
1159 egrep -n "^Subject|Sign|^$"
1160}
1161
1162test_expect_success 'signoff: commit with no body' '
1163 append_signoff </dev/null >actual &&
1164 cat <<\EOF | sed "s/EOL$//" >expected &&
11654:Subject: [PATCH] EOL
11668:
11679:Signed-off-by: C O Mitter <committer@example.com>
1168EOF
1169 test_cmp expected actual
1170'
1171
1172test_expect_success 'signoff: commit with only subject' '
1173 echo subject | append_signoff >actual &&
1174 cat >expected <<\EOF &&
11754:Subject: [PATCH] subject
11768:
11779:Signed-off-by: C O Mitter <committer@example.com>
1178EOF
1179 test_cmp expected actual
1180'
1181
1182test_expect_success 'signoff: commit with only subject that does not end with NL' '
1183 printf subject | append_signoff >actual &&
1184 cat >expected <<\EOF &&
11854:Subject: [PATCH] subject
11868:
11879:Signed-off-by: C O Mitter <committer@example.com>
1188EOF
1189 test_cmp expected actual
1190'
1191
1192test_expect_success 'signoff: no existing signoffs' '
1193 append_signoff <<\EOF >actual &&
1194subject
1195
1196body
1197EOF
1198 cat >expected <<\EOF &&
11994:Subject: [PATCH] subject
12008:
120110:
120211:Signed-off-by: C O Mitter <committer@example.com>
1203EOF
1204 test_cmp expected actual
1205'
1206
1207test_expect_success 'signoff: no existing signoffs and no trailing NL' '
1208 printf "subject\n\nbody" | append_signoff >actual &&
1209 cat >expected <<\EOF &&
12104:Subject: [PATCH] subject
12118:
121210:
121311:Signed-off-by: C O Mitter <committer@example.com>
1214EOF
1215 test_cmp expected actual
1216'
1217
1218test_expect_success 'signoff: some random signoff' '
1219 append_signoff <<\EOF >actual &&
1220subject
1221
1222body
1223
1224Signed-off-by: my@house
1225EOF
1226 cat >expected <<\EOF &&
12274:Subject: [PATCH] subject
12288:
122910:
123011:Signed-off-by: my@house
123112:Signed-off-by: C O Mitter <committer@example.com>
1232EOF
1233 test_cmp expected actual
1234'
1235
959a2623
BC
1236test_expect_success 'signoff: misc conforming footer elements' '
1237 append_signoff <<\EOF >actual &&
1238subject
1239
1240body
1241
1242Signed-off-by: my@house
1243(cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1244Tested-by: Some One <someone@example.com>
1245Bug: 1234
1246EOF
1247 cat >expected <<\EOF &&
12484:Subject: [PATCH] subject
12498:
125010:
125111:Signed-off-by: my@house
125215:Signed-off-by: C O Mitter <committer@example.com>
1253EOF
1254 test_cmp expected actual
1255'
1256
1257test_expect_success 'signoff: some random signoff-alike' '
79133a66
NTND
1258 append_signoff <<\EOF >actual &&
1259subject
1260
1261body
1262Fooled-by-me: my@house
1263EOF
1264 cat >expected <<\EOF &&
12654:Subject: [PATCH] subject
12668:
126711:
126812:Signed-off-by: C O Mitter <committer@example.com>
1269EOF
1270 test_cmp expected actual
1271'
1272
959a2623 1273test_expect_success 'signoff: not really a signoff' '
79133a66
NTND
1274 append_signoff <<\EOF >actual &&
1275subject
1276
1277I want to mention about Signed-off-by: here.
1278EOF
1279 cat >expected <<\EOF &&
12804:Subject: [PATCH] subject
12818:
12829:I want to mention about Signed-off-by: here.
128310:
128411:Signed-off-by: C O Mitter <committer@example.com>
1285EOF
1286 test_cmp expected actual
1287'
1288
959a2623 1289test_expect_success 'signoff: not really a signoff (2)' '
79133a66
NTND
1290 append_signoff <<\EOF >actual &&
1291subject
1292
1293My unfortunate
1294Signed-off-by: example happens to be wrapped here.
1295EOF
1296 cat >expected <<\EOF &&
12974:Subject: [PATCH] subject
12988:
129910:Signed-off-by: example happens to be wrapped here.
967dfd4d 130011:Signed-off-by: C O Mitter <committer@example.com>
79133a66
NTND
1301EOF
1302 test_cmp expected actual
1303'
1304
959a2623 1305test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
79133a66
NTND
1306 append_signoff <<\EOF >actual &&
1307subject
1308
1309Signed-off-by: my@house
1310Signed-off-by: your@house
1311
1312A lot of houses.
1313EOF
1314 cat >expected <<\EOF &&
13154:Subject: [PATCH] subject
13168:
13179:Signed-off-by: my@house
131810:Signed-off-by: your@house
131911:
132013:
132114:Signed-off-by: C O Mitter <committer@example.com>
1322EOF
1323 test_cmp expected actual
1324'
1325
1326test_expect_success 'signoff: the same signoff at the end' '
1327 append_signoff <<\EOF >actual &&
1328subject
1329
1330body
1331
1332Signed-off-by: C O Mitter <committer@example.com>
1333EOF
1334 cat >expected <<\EOF &&
13354:Subject: [PATCH] subject
13368:
133710:
133811:Signed-off-by: C O Mitter <committer@example.com>
1339EOF
1340 test_cmp expected actual
1341'
1342
1343test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
1344 printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
1345 append_signoff >actual &&
1346 cat >expected <<\EOF &&
13474:Subject: [PATCH] subject
13488:
13499:Signed-off-by: C O Mitter <committer@example.com>
1350EOF
1351 test_cmp expected actual
1352'
1353
1354test_expect_success 'signoff: the same signoff NOT at the end' '
1355 append_signoff <<\EOF >actual &&
1356subject
1357
1358body
1359
1360Signed-off-by: C O Mitter <committer@example.com>
1361Signed-off-by: my@house
1362EOF
1363 cat >expected <<\EOF &&
13644:Subject: [PATCH] subject
13658:
136610:
136711:Signed-off-by: C O Mitter <committer@example.com>
136812:Signed-off-by: my@house
1369EOF
1370 test_cmp expected actual
1371'
1372
967dfd4d 1373test_expect_success 'signoff: tolerate garbage in conforming footer' '
79133a66
NTND
1374 append_signoff <<\EOF >actual &&
1375subject
1376
1377body
1378
1379Tested-by: my@house
1380Some Trash
1381Signed-off-by: C O Mitter <committer@example.com>
1382EOF
1383 cat >expected <<\EOF &&
13844:Subject: [PATCH] subject
13858:
138610:
138713:Signed-off-by: C O Mitter <committer@example.com>
967dfd4d
JT
1388EOF
1389 test_cmp expected actual
1390'
1391
1392test_expect_success 'signoff: respect trailer config' '
1393 append_signoff <<\EOF >actual &&
1394subject
1395
1396Myfooter: x
1397Some Trash
1398EOF
1399 cat >expected <<\EOF &&
14004:Subject: [PATCH] subject
14018:
140211:
140312:Signed-off-by: C O Mitter <committer@example.com>
1404EOF
1405 test_cmp expected actual &&
1406
1407 test_config trailer.Myfooter.ifexists add &&
1408 append_signoff <<\EOF >actual &&
1409subject
1410
1411Myfooter: x
1412Some Trash
1413EOF
1414 cat >expected <<\EOF &&
14154:Subject: [PATCH] subject
14168:
141711:Signed-off-by: C O Mitter <committer@example.com>
79133a66
NTND
1418EOF
1419 test_cmp expected actual
1420'
1421
1422test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
1423 append_signoff <<\EOF >actual &&
1424subject
1425
1426body
1427
1428Reviewed-id: Noone
1429Tested-by: my@house
1430Change-id: Ideadbeef
1431Signed-off-by: C O Mitter <committer@example.com>
1432Bug: 1234
1433EOF
1434 cat >expected <<\EOF &&
14354:Subject: [PATCH] subject
14368:
143710:
143814:Signed-off-by: C O Mitter <committer@example.com>
1439EOF
1440 test_cmp expected actual
1441'
1442
787570c7
PYH
1443test_expect_success 'format patch ignores color.ui' '
1444 test_unconfig color.ui &&
1445 git format-patch --stdout -1 >expect &&
1446 test_config color.ui always &&
1447 git format-patch --stdout -1 >actual &&
1448 test_cmp expect actual
1449'
1450
e216cc48
NTND
1451test_expect_success 'cover letter using branch description (1)' '
1452 git checkout rebuild-1 &&
1453 test_config branch.rebuild-1.description hello &&
1454 git format-patch --stdout --cover-letter master >actual &&
1455 grep hello actual >/dev/null
1456'
1457
1458test_expect_success 'cover letter using branch description (2)' '
1459 git checkout rebuild-1 &&
1460 test_config branch.rebuild-1.description hello &&
1461 git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
1462 grep hello actual >/dev/null
1463'
1464
1465test_expect_success 'cover letter using branch description (3)' '
1466 git checkout rebuild-1 &&
1467 test_config branch.rebuild-1.description hello &&
1468 git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
1469 grep hello actual >/dev/null
1470'
1471
20b630aa
NTND
1472test_expect_success 'cover letter using branch description (4)' '
1473 git checkout rebuild-1 &&
1474 test_config branch.rebuild-1.description hello &&
1475 git format-patch --stdout --cover-letter master.. >actual &&
1476 grep hello actual >/dev/null
1477'
1478
1479test_expect_success 'cover letter using branch description (5)' '
1480 git checkout rebuild-1 &&
1481 test_config branch.rebuild-1.description hello &&
1482 git format-patch --stdout --cover-letter -2 HEAD >actual &&
1483 grep hello actual >/dev/null
1484'
1485
5ee29aef
NTND
1486test_expect_success 'cover letter using branch description (6)' '
1487 git checkout rebuild-1 &&
1488 test_config branch.rebuild-1.description hello &&
1489 git format-patch --stdout --cover-letter -2 >actual &&
1490 grep hello actual >/dev/null
1491'
1492
80d35ca0
FC
1493test_expect_success 'cover letter with nothing' '
1494 git format-patch --stdout --cover-letter >actual &&
1495 test_line_count = 0 actual
1496'
1497
2a4c2607
FC
1498test_expect_success 'cover letter auto' '
1499 mkdir -p tmp &&
1500 test_when_finished "rm -rf tmp;
1501 git config --unset format.coverletter" &&
1502
1503 git config format.coverletter auto &&
1504 git format-patch -o tmp -1 >list &&
1505 test_line_count = 1 list &&
1506 git format-patch -o tmp -2 >list &&
1507 test_line_count = 3 list
1508'
1509
1510test_expect_success 'cover letter auto user override' '
1511 mkdir -p tmp &&
1512 test_when_finished "rm -rf tmp;
1513 git config --unset format.coverletter" &&
1514
1515 git config format.coverletter auto &&
1516 git format-patch -o tmp --cover-letter -1 >list &&
1517 test_line_count = 2 list &&
1518 git format-patch -o tmp --cover-letter -2 >list &&
1519 test_line_count = 3 list &&
1520 git format-patch -o tmp --no-cover-letter -1 >list &&
1521 test_line_count = 1 list &&
1522 git format-patch -o tmp --no-cover-letter -2 >list &&
1523 test_line_count = 2 list
1524'
1525
3a30aa17 1526test_expect_success 'format-patch --zero-commit' '
1527 git format-patch --zero-commit --stdout v2..v1 >patch2 &&
1528 grep "^From " patch2 | sort | uniq >actual &&
8125a58b 1529 echo "From $ZERO_OID Mon Sep 17 00:00:00 2001" >expect &&
3a30aa17 1530 test_cmp expect actual
1531'
1532
06dfc9eb 1533test_expect_success 'From line has expected format' '
1534 git format-patch --stdout v2..v1 >patch2 &&
1535 grep "^From " patch2 >from &&
2ece6ad2 1536 grep "^From $OID_REGEX Mon Sep 17 00:00:00 2001$" patch2 >filtered &&
06dfc9eb 1537 test_cmp from filtered
1538'
1539
bc6bf2d7
AK
1540test_expect_success 'format-patch format.outputDirectory option' '
1541 test_config format.outputDirectory patches &&
1542 rm -fr patches &&
1543 git format-patch master..side &&
1544 test $(git rev-list master..side | wc -l) -eq $(ls patches | wc -l)
1545'
1546
1547test_expect_success 'format-patch -o overrides format.outputDirectory' '
1548 test_config format.outputDirectory patches &&
1549 rm -fr patches patchset &&
1550 git format-patch master..side -o patchset &&
1551 test_path_is_missing patches &&
1552 test_path_is_dir patchset
1553'
1554
fa2ab86d
XY
1555test_expect_success 'format-patch --base' '
1556 git checkout side &&
15b76c1f
XY
1557 git format-patch --stdout --base=HEAD~3 -1 | tail -n 7 >actual1 &&
1558 git format-patch --stdout --base=HEAD~3 HEAD~.. | tail -n 7 >actual2 &&
480871e0
JT
1559 echo >expected &&
1560 echo "base-commit: $(git rev-parse HEAD~3)" >>expected &&
fa2ab86d
XY
1561 echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1562 echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected &&
480871e0 1563 signature >> expected &&
15b76c1f
XY
1564 test_cmp expected actual1 &&
1565 test_cmp expected actual2
fa2ab86d
XY
1566'
1567
1568test_expect_success 'format-patch --base errors out when base commit is in revision list' '
1569 test_must_fail git format-patch --base=HEAD -2 &&
1570 test_must_fail git format-patch --base=HEAD~1 -2 &&
1571 git format-patch --stdout --base=HEAD~2 -2 >patch &&
1572 grep "^base-commit:" patch >actual &&
1573 echo "base-commit: $(git rev-parse HEAD~2)" >expected &&
1574 test_cmp expected actual
1575'
1576
1577test_expect_success 'format-patch --base errors out when base commit is not ancestor of revision list' '
1578 # For history as below:
1579 #
1580 # ---Q---P---Z---Y---*---X
1581 # \ /
1582 # ------------W
1583 #
1584 # If "format-patch Z..X" is given, P and Z can not be specified as the base commit
1585 git checkout -b topic1 master &&
1586 git rev-parse HEAD >commit-id-base &&
1587 test_commit P &&
1588 git rev-parse HEAD >commit-id-P &&
1589 test_commit Z &&
1590 git rev-parse HEAD >commit-id-Z &&
1591 test_commit Y &&
1592 git checkout -b topic2 master &&
1593 test_commit W &&
1594 git merge topic1 &&
1595 test_commit X &&
1596 test_must_fail git format-patch --base=$(cat commit-id-P) -3 &&
1597 test_must_fail git format-patch --base=$(cat commit-id-Z) -3 &&
1598 git format-patch --stdout --base=$(cat commit-id-base) -3 >patch &&
1599 grep "^base-commit:" patch >actual &&
1600 echo "base-commit: $(cat commit-id-base)" >expected &&
1601 test_cmp expected actual
1602'
1603
3de66517
XY
1604test_expect_success 'format-patch --base=auto' '
1605 git checkout -b upstream master &&
1606 git checkout -b local upstream &&
1607 git branch --set-upstream-to=upstream &&
1608 test_commit N1 &&
1609 test_commit N2 &&
1610 git format-patch --stdout --base=auto -2 >patch &&
1611 grep "^base-commit:" patch >actual &&
1612 echo "base-commit: $(git rev-parse upstream)" >expected &&
1613 test_cmp expected actual
1614'
1615
1616test_expect_success 'format-patch errors out when history involves criss-cross' '
1617 # setup criss-cross history
1618 #
1619 # B---M1---D
1620 # / \ /
1621 # A X
1622 # \ / \
1623 # C---M2---E
1624 #
1625 git checkout master &&
1626 test_commit A &&
1627 git checkout -b xb master &&
1628 test_commit B &&
1629 git checkout -b xc master &&
1630 test_commit C &&
1631 git checkout -b xbc xb -- &&
1632 git merge xc &&
1633 git checkout -b xcb xc -- &&
1634 git branch --set-upstream-to=xbc &&
1635 git merge xb &&
1636 git checkout xbc &&
1637 test_commit D &&
1638 git checkout xcb &&
1639 test_commit E &&
1640 test_must_fail git format-patch --base=auto -1
1641'
1642
bb52995f
XY
1643test_expect_success 'format-patch format.useAutoBaseoption' '
1644 test_when_finished "git config --unset format.useAutoBase" &&
1645 git checkout local &&
1646 git config format.useAutoBase true &&
1647 git format-patch --stdout -1 >patch &&
1648 grep "^base-commit:" patch >actual &&
1649 echo "base-commit: $(git rev-parse upstream)" >expected &&
1650 test_cmp expected actual
1651'
1652
1653test_expect_success 'format-patch --base overrides format.useAutoBase' '
1654 test_when_finished "git config --unset format.useAutoBase" &&
1655 git config format.useAutoBase true &&
1656 git format-patch --stdout --base=HEAD~1 -1 >patch &&
1657 grep "^base-commit:" patch >actual &&
1658 echo "base-commit: $(git rev-parse HEAD~1)" >expected &&
1659 test_cmp expected actual
1660'
1661
480871e0
JT
1662test_expect_success 'format-patch --base with --attach' '
1663 git format-patch --attach=mimemime --stdout --base=HEAD~ -1 >patch &&
1664 sed -n -e "/^base-commit:/s/.*/1/p" -e "/^---*mimemime--$/s/.*/2/p" \
1665 patch >actual &&
1666 test_write_lines 1 2 >expect &&
1667 test_cmp expect actual
1668'
50cd54ef 1669test_expect_success 'format-patch --attach cover-letter only is non-multipart' '
1670 test_when_finished "rm -fr patches" &&
1671 git format-patch -o patches --cover-letter --attach=mimemime --base=HEAD~ -1 &&
1672 ! egrep "^--+mimemime" patches/0000*.patch &&
1673 egrep "^--+mimemime$" patches/0001*.patch >output &&
1674 test_line_count = 2 output &&
1675 egrep "^--+mimemime--$" patches/0001*.patch >output &&
1676 test_line_count = 1 output
1677'
480871e0 1678
9f23e040
EW
1679test_expect_success 'format-patch --pretty=mboxrd' '
1680 sp=" " &&
1681 cat >msg <<-INPUT_END &&
1682 mboxrd should escape the body
1683
1684 From could trip up a loose mbox parser
1685 >From extra escape for reversibility
1686 >>From extra escape for reversibility 2
1687 from lower case not escaped
1688 Fromm bad speling not escaped
1689 From with leading space not escaped
1690
1691 F
1692 From
1693 From$sp
1694 From $sp
1695 From $sp
1696 INPUT_END
1697
1698 cat >expect <<-INPUT_END &&
1699 >From could trip up a loose mbox parser
1700 >>From extra escape for reversibility
1701 >>>From extra escape for reversibility 2
1702 from lower case not escaped
1703 Fromm bad speling not escaped
1704 From with leading space not escaped
1705
1706 F
1707 From
1708 From
1709 From
1710 From
1711 INPUT_END
1712
1713 C=$(git commit-tree HEAD^^{tree} -p HEAD <msg) &&
1714 git format-patch --pretty=mboxrd --stdout -1 $C~1..$C >patch &&
1715 git grep -h --no-index -A11 \
1716 "^>From could trip up a loose mbox parser" patch >actual &&
1717 test_cmp expect actual
1718'
1719
126facf8
ES
1720test_expect_success 'interdiff: setup' '
1721 git checkout -b boop master &&
1722 test_commit fnorp blorp &&
1723 test_commit fleep blorp
1724'
1725
1726test_expect_success 'interdiff: cover-letter' '
1727 sed "y/q/ /" >expect <<-\EOF &&
1728 +fleep
1729 --q
1730 EOF
1731 git format-patch --cover-letter --interdiff=boop~2 -1 boop &&
1732 test_i18ngrep "^Interdiff:$" 0000-cover-letter.patch &&
ee6cbf71 1733 test_i18ngrep ! "^Interdiff:$" 0001-fleep.patch &&
126facf8
ES
1734 sed "1,/^@@ /d; /^-- $/q" <0000-cover-letter.patch >actual &&
1735 test_cmp expect actual
1736'
1737
5ac290f9
ES
1738test_expect_success 'interdiff: reroll-count' '
1739 git format-patch --cover-letter --interdiff=boop~2 -v2 -1 boop &&
1740 test_i18ngrep "^Interdiff ..* v1:$" v2-0000-cover-letter.patch
1741'
1742
ee6cbf71
ES
1743test_expect_success 'interdiff: solo-patch' '
1744 cat >expect <<-\EOF &&
1745 +fleep
1746
1747 EOF
1748 git format-patch --interdiff=boop~2 -1 boop &&
1749 test_i18ngrep "^Interdiff:$" 0001-fleep.patch &&
1750 sed "1,/^ @@ /d; /^$/q" <0001-fleep.patch >actual &&
1751 test_cmp expect actual
1752'
1753
ece3c67f 1754test_done