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