t4014: move closing sq onto its own line
[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
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
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
9b7a61d7
JH
74test_expect_success "format-patch --ignore-if-in-upstream handles tags" '
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
ece3c67f 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
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
DB
128" &&
129 git format-patch --stdout master..side > patch2 &&
9524cf29 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 &&
9524cf29 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>" &&
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)' '
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 &&
321 (git format-patch --stdout "$@"; echo $? > status.out) |
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;
336 ' > actual &&
337 test 0 = "$(cat status.out)" &&
338 test_cmp "$expect" actual
339}
340
341cat >> expect.no-threading <<EOF
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
484cf6c3
TR
352cat > expect.thread <<EOF
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
484cf6c3
TR
369cat > expect.in-reply-to <<EOF
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
484cf6c3
TR
389cat > expect.cover-letter <<EOF
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
410cat > expect.cl-irt <<EOF
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
442cat > expect.deep <<EOF
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
460cat > expect.deep-irt <<EOF
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
483cat > expect.deep-cl <<EOF
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
507cat > expect.deep-cl-irt <<EOF
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
JS
586
587cat > expect << EOF
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 &&
9524cf29 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
68daa64d 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
1d46f2ea
JK
623cat > expect << EOF
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 &&
9524cf29 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
SB
691test_expect_success 'format-patch --in-reply-to' '
692 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
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
02bc5b03
BG
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
786
68b2a005 787test_expect_success 'options no longer allowed for format-patch' '
02bc5b03 788 test_must_fail git format-patch --name-only 2> output &&
68b2a005 789 test_i18ncmp expect.name-only output &&
02bc5b03 790 test_must_fail git format-patch --name-status 2> output &&
68b2a005 791 test_i18ncmp expect.name-status output &&
02bc5b03 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' '
4fa80cf0 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 &&
b562a54c 1214 cat <<\EOF | sed "s/EOL$//" >expect &&
79133a66
NTND
12154:Subject: [PATCH] EOL
12168:
12179:Signed-off-by: C O Mitter <committer@example.com>
1218EOF
b562a54c 1219 test_cmp expect actual
79133a66
NTND
1220'
1221
1222test_expect_success 'signoff: commit with only subject' '
1223 echo subject | append_signoff >actual &&
b562a54c 1224 cat >expect <<\EOF &&
79133a66
NTND
12254:Subject: [PATCH] subject
12268:
12279:Signed-off-by: C O Mitter <committer@example.com>
1228EOF
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 &&
b562a54c 1234 cat >expect <<\EOF &&
79133a66
NTND
12354:Subject: [PATCH] subject
12368:
12379:Signed-off-by: C O Mitter <committer@example.com>
1238EOF
b562a54c 1239 test_cmp expect actual
79133a66
NTND
1240'
1241
1242test_expect_success 'signoff: no existing signoffs' '
1243 append_signoff <<\EOF >actual &&
1244subject
1245
1246body
1247EOF
b562a54c 1248 cat >expect <<\EOF &&
79133a66
NTND
12494:Subject: [PATCH] subject
12508:
125110:
125211:Signed-off-by: C O Mitter <committer@example.com>
1253EOF
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 &&
b562a54c 1259 cat >expect <<\EOF &&
79133a66
NTND
12604:Subject: [PATCH] subject
12618:
126210:
126311:Signed-off-by: C O Mitter <committer@example.com>
1264EOF
b562a54c 1265 test_cmp expect actual
79133a66
NTND
1266'
1267
1268test_expect_success 'signoff: some random signoff' '
1269 append_signoff <<\EOF >actual &&
1270subject
1271
1272body
1273
1274Signed-off-by: my@house
1275EOF
b562a54c 1276 cat >expect <<\EOF &&
79133a66
NTND
12774:Subject: [PATCH] subject
12788:
127910:
128011:Signed-off-by: my@house
128112:Signed-off-by: C O Mitter <committer@example.com>
1282EOF
b562a54c 1283 test_cmp expect actual
79133a66
NTND
1284'
1285
959a2623
BC
1286test_expect_success 'signoff: misc conforming footer elements' '
1287 append_signoff <<\EOF >actual &&
1288subject
1289
1290body
1291
1292Signed-off-by: my@house
1293(cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1294Tested-by: Some One <someone@example.com>
1295Bug: 1234
1296EOF
b562a54c 1297 cat >expect <<\EOF &&
959a2623
BC
12984:Subject: [PATCH] subject
12998:
130010:
130111:Signed-off-by: my@house
130215:Signed-off-by: C O Mitter <committer@example.com>
1303EOF
b562a54c 1304 test_cmp expect actual
959a2623
BC
1305'
1306
1307test_expect_success 'signoff: some random signoff-alike' '
79133a66
NTND
1308 append_signoff <<\EOF >actual &&
1309subject
1310
1311body
1312Fooled-by-me: my@house
1313EOF
b562a54c 1314 cat >expect <<\EOF &&
79133a66
NTND
13154:Subject: [PATCH] subject
13168:
131711:
131812:Signed-off-by: C O Mitter <committer@example.com>
1319EOF
b562a54c 1320 test_cmp expect actual
79133a66
NTND
1321'
1322
959a2623 1323test_expect_success 'signoff: not really a signoff' '
79133a66
NTND
1324 append_signoff <<\EOF >actual &&
1325subject
1326
1327I want to mention about Signed-off-by: here.
1328EOF
b562a54c 1329 cat >expect <<\EOF &&
79133a66
NTND
13304:Subject: [PATCH] subject
13318:
13329:I want to mention about Signed-off-by: here.
133310:
133411:Signed-off-by: C O Mitter <committer@example.com>
1335EOF
b562a54c 1336 test_cmp expect actual
79133a66
NTND
1337'
1338
959a2623 1339test_expect_success 'signoff: not really a signoff (2)' '
79133a66
NTND
1340 append_signoff <<\EOF >actual &&
1341subject
1342
1343My unfortunate
1344Signed-off-by: example happens to be wrapped here.
1345EOF
b562a54c 1346 cat >expect <<\EOF &&
79133a66
NTND
13474:Subject: [PATCH] subject
13488:
134910:Signed-off-by: example happens to be wrapped here.
967dfd4d 135011:Signed-off-by: C O Mitter <committer@example.com>
79133a66 1351EOF
b562a54c 1352 test_cmp expect actual
79133a66
NTND
1353'
1354
959a2623 1355test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
79133a66
NTND
1356 append_signoff <<\EOF >actual &&
1357subject
1358
1359Signed-off-by: my@house
1360Signed-off-by: your@house
1361
1362A lot of houses.
1363EOF
b562a54c 1364 cat >expect <<\EOF &&
79133a66
NTND
13654:Subject: [PATCH] subject
13668:
13679:Signed-off-by: my@house
136810:Signed-off-by: your@house
136911:
137013:
137114:Signed-off-by: C O Mitter <committer@example.com>
1372EOF
b562a54c 1373 test_cmp expect actual
79133a66
NTND
1374'
1375
1376test_expect_success 'signoff: the same signoff at the end' '
1377 append_signoff <<\EOF >actual &&
1378subject
1379
1380body
1381
1382Signed-off-by: C O Mitter <committer@example.com>
1383EOF
b562a54c 1384 cat >expect <<\EOF &&
79133a66
NTND
13854:Subject: [PATCH] subject
13868:
138710:
138811:Signed-off-by: C O Mitter <committer@example.com>
1389EOF
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 &&
b562a54c 1396 cat >expect <<\EOF &&
79133a66
NTND
13974:Subject: [PATCH] subject
13988:
13999:Signed-off-by: C O Mitter <committer@example.com>
1400EOF
b562a54c 1401 test_cmp expect actual
79133a66
NTND
1402'
1403
1404test_expect_success 'signoff: the same signoff NOT at the end' '
1405 append_signoff <<\EOF >actual &&
1406subject
1407
1408body
1409
1410Signed-off-by: C O Mitter <committer@example.com>
1411Signed-off-by: my@house
1412EOF
b562a54c 1413 cat >expect <<\EOF &&
79133a66
NTND
14144:Subject: [PATCH] subject
14158:
141610:
141711:Signed-off-by: C O Mitter <committer@example.com>
141812:Signed-off-by: my@house
1419EOF
b562a54c 1420 test_cmp expect actual
79133a66
NTND
1421'
1422
967dfd4d 1423test_expect_success 'signoff: tolerate garbage in conforming footer' '
79133a66
NTND
1424 append_signoff <<\EOF >actual &&
1425subject
1426
1427body
1428
1429Tested-by: my@house
1430Some Trash
1431Signed-off-by: C O Mitter <committer@example.com>
1432EOF
b562a54c 1433 cat >expect <<\EOF &&
79133a66
NTND
14344:Subject: [PATCH] subject
14358:
143610:
143713:Signed-off-by: C O Mitter <committer@example.com>
967dfd4d 1438EOF
b562a54c 1439 test_cmp expect actual
967dfd4d
JT
1440'
1441
1442test_expect_success 'signoff: respect trailer config' '
1443 append_signoff <<\EOF >actual &&
1444subject
1445
1446Myfooter: x
1447Some Trash
1448EOF
b562a54c 1449 cat >expect <<\EOF &&
967dfd4d
JT
14504:Subject: [PATCH] subject
14518:
145211:
145312:Signed-off-by: C O Mitter <committer@example.com>
1454EOF
b562a54c 1455 test_cmp expect actual &&
967dfd4d
JT
1456
1457 test_config trailer.Myfooter.ifexists add &&
1458 append_signoff <<\EOF >actual &&
1459subject
1460
1461Myfooter: x
1462Some Trash
1463EOF
b562a54c 1464 cat >expect <<\EOF &&
967dfd4d
JT
14654:Subject: [PATCH] subject
14668:
146711:Signed-off-by: C O Mitter <committer@example.com>
79133a66 1468EOF
b562a54c 1469 test_cmp expect actual
79133a66
NTND
1470'
1471
1472test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
1473 append_signoff <<\EOF >actual &&
1474subject
1475
1476body
1477
1478Reviewed-id: Noone
1479Tested-by: my@house
1480Change-id: Ideadbeef
1481Signed-off-by: C O Mitter <committer@example.com>
1482Bug: 1234
1483EOF
b562a54c 1484 cat >expect <<\EOF &&
79133a66
NTND
14854:Subject: [PATCH] subject
14868:
148710:
148814:Signed-off-by: C O Mitter <committer@example.com>
1489EOF
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 &&
1505 grep hello actual >/dev/null
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 &&
1512 grep hello actual >/dev/null
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 &&
1519 grep hello actual >/dev/null
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 &&
1526 grep hello actual >/dev/null
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 &&
1533 grep hello actual >/dev/null
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 &&
1540 grep hello actual >/dev/null
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 &&
1613 signature >> expect &&
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 &&
6f93d261
SB
1620 signature >> fail &&
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