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