Merge branch 'jk/shell-portability'
[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 '
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
c4260034
SB
232test_expect_success '--no-to overrides config.to' '
233
234 git config --replace-all format.to \
25dc8dad 235 "R E Cipient <rcipient@example.com>" &&
c4260034
SB
236 git format-patch --no-to --stdout master..side |
237 sed -e "/^\$/q" >patch10 &&
cc663d14 238 check_patch patch10 &&
25dc8dad 239 ! grep "^To: R E Cipient <rcipient@example.com>\$" patch10
c4260034
SB
240'
241
242test_expect_success '--no-to and --to replaces config.to' '
243
244 git config --replace-all format.to \
245 "Someone <someone@out.there>" &&
246 git format-patch --no-to --to="Someone Else <else@out.there>" \
247 --stdout master..side |
248 sed -e "/^\$/q" >patch11 &&
cc663d14 249 check_patch patch11 &&
c4260034
SB
250 ! grep "^To: Someone <someone@out.there>\$" patch11 &&
251 grep "^To: Someone Else <else@out.there>\$" patch11
252'
253
254test_expect_success '--no-cc overrides config.cc' '
255
256 git config --replace-all format.cc \
25dc8dad 257 "C E Cipient <rcipient@example.com>" &&
c4260034
SB
258 git format-patch --no-cc --stdout master..side |
259 sed -e "/^\$/q" >patch12 &&
cc663d14 260 check_patch patch12 &&
25dc8dad 261 ! grep "^Cc: C E Cipient <rcipient@example.com>\$" patch12
c4260034
SB
262'
263
688f4f2f 264test_expect_success '--no-add-header overrides config.headers' '
c4260034
SB
265
266 git config --replace-all format.headers \
25dc8dad 267 "Header1: B E Cipient <rcipient@example.com>" &&
688f4f2f 268 git format-patch --no-add-header --stdout master..side |
c4260034 269 sed -e "/^\$/q" >patch13 &&
cc663d14 270 check_patch patch13 &&
25dc8dad 271 ! grep "^Header1: B E Cipient <rcipient@example.com>\$" patch13
c4260034
SB
272'
273
7d812145
DB
274test_expect_success 'multiple files' '
275
276 rm -rf patches/ &&
277 git checkout side &&
278 git format-patch -o patches/ master &&
279 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
280'
281
4aad08e0
JH
282test_expect_success 'reroll count' '
283 rm -fr patches &&
284 git format-patch -o patches --cover-letter --reroll-count 4 master..side >list &&
285 ! grep -v "^patches/v4-000[0-3]-" list &&
286 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
287 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
288'
289
7952ea66
JH
290test_expect_success 'reroll count (-v)' '
291 rm -fr patches &&
292 git format-patch -o patches --cover-letter -v4 master..side >list &&
293 ! grep -v "^patches/v4-000[0-3]-" list &&
294 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
295 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
296'
297
484cf6c3
TR
298check_threading () {
299 expect="$1" &&
300 shift &&
301 (git format-patch --stdout "$@"; echo $? > status.out) |
302 # Prints everything between the Message-ID and In-Reply-To,
303 # and replaces all Message-ID-lookalikes by a sequence number
94221d22 304 perl -ne '
484cf6c3
TR
305 if (/^(message-id|references|in-reply-to)/i) {
306 $printing = 1;
307 } elsif (/^\S/) {
308 $printing = 0;
309 }
310 if ($printing) {
311 $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
312 for $k (keys %h) {s/$k/$h{$k}/};
313 print;
314 }
315 print "---\n" if /^From /i;
316 ' > actual &&
317 test 0 = "$(cat status.out)" &&
318 test_cmp "$expect" actual
319}
320
321cat >> expect.no-threading <<EOF
322---
323---
324---
325EOF
326
327test_expect_success 'no threading' '
7d812145 328 git checkout side &&
484cf6c3 329 check_threading expect.no-threading master
7d812145
DB
330'
331
484cf6c3
TR
332cat > expect.thread <<EOF
333---
334Message-Id: <0>
335---
336Message-Id: <1>
337In-Reply-To: <0>
338References: <0>
339---
340Message-Id: <2>
341In-Reply-To: <0>
342References: <0>
343EOF
7d812145 344
484cf6c3
TR
345test_expect_success 'thread' '
346 check_threading expect.thread --thread master
7d812145
DB
347'
348
484cf6c3
TR
349cat > expect.in-reply-to <<EOF
350---
351Message-Id: <0>
352In-Reply-To: <1>
353References: <1>
354---
355Message-Id: <2>
356In-Reply-To: <1>
357References: <1>
358---
359Message-Id: <3>
360In-Reply-To: <1>
361References: <1>
362EOF
a5a27c79 363
484cf6c3
TR
364test_expect_success 'thread in-reply-to' '
365 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
366 --thread master
a5a27c79
DB
367'
368
484cf6c3
TR
369cat > expect.cover-letter <<EOF
370---
371Message-Id: <0>
372---
373Message-Id: <1>
374In-Reply-To: <0>
375References: <0>
376---
377Message-Id: <2>
378In-Reply-To: <0>
379References: <0>
380---
381Message-Id: <3>
382In-Reply-To: <0>
383References: <0>
384EOF
a5a27c79 385
484cf6c3
TR
386test_expect_success 'thread cover-letter' '
387 check_threading expect.cover-letter --cover-letter --thread master
388'
389
390cat > expect.cl-irt <<EOF
391---
392Message-Id: <0>
393In-Reply-To: <1>
394References: <1>
395---
396Message-Id: <2>
2175c10d 397In-Reply-To: <0>
484cf6c3 398References: <1>
2175c10d 399 <0>
484cf6c3
TR
400---
401Message-Id: <3>
2175c10d 402In-Reply-To: <0>
484cf6c3 403References: <1>
2175c10d 404 <0>
484cf6c3
TR
405---
406Message-Id: <4>
2175c10d 407In-Reply-To: <0>
484cf6c3 408References: <1>
2175c10d 409 <0>
484cf6c3
TR
410EOF
411
412test_expect_success 'thread cover-letter in-reply-to' '
413 check_threading expect.cl-irt --cover-letter \
414 --in-reply-to="<test.message>" --thread master
a5a27c79
DB
415'
416
30984ed2
TR
417test_expect_success 'thread explicit shallow' '
418 check_threading expect.cl-irt --cover-letter \
419 --in-reply-to="<test.message>" --thread=shallow master
420'
421
422cat > expect.deep <<EOF
423---
424Message-Id: <0>
425---
426Message-Id: <1>
427In-Reply-To: <0>
428References: <0>
429---
430Message-Id: <2>
431In-Reply-To: <1>
432References: <0>
433 <1>
434EOF
435
436test_expect_success 'thread deep' '
437 check_threading expect.deep --thread=deep master
438'
439
440cat > expect.deep-irt <<EOF
441---
442Message-Id: <0>
443In-Reply-To: <1>
444References: <1>
445---
446Message-Id: <2>
447In-Reply-To: <0>
448References: <1>
449 <0>
450---
451Message-Id: <3>
452In-Reply-To: <2>
453References: <1>
454 <0>
455 <2>
456EOF
457
458test_expect_success 'thread deep in-reply-to' '
459 check_threading expect.deep-irt --thread=deep \
460 --in-reply-to="<test.message>" master
461'
462
463cat > expect.deep-cl <<EOF
464---
465Message-Id: <0>
466---
467Message-Id: <1>
468In-Reply-To: <0>
469References: <0>
470---
471Message-Id: <2>
472In-Reply-To: <1>
473References: <0>
474 <1>
475---
476Message-Id: <3>
477In-Reply-To: <2>
478References: <0>
479 <1>
480 <2>
481EOF
482
483test_expect_success 'thread deep cover-letter' '
484 check_threading expect.deep-cl --cover-letter --thread=deep master
485'
486
487cat > expect.deep-cl-irt <<EOF
488---
489Message-Id: <0>
490In-Reply-To: <1>
491References: <1>
492---
493Message-Id: <2>
494In-Reply-To: <0>
495References: <1>
496 <0>
497---
498Message-Id: <3>
499In-Reply-To: <2>
500References: <1>
501 <0>
502 <2>
503---
504Message-Id: <4>
505In-Reply-To: <3>
506References: <1>
507 <0>
508 <2>
509 <3>
510EOF
511
512test_expect_success 'thread deep cover-letter in-reply-to' '
513 check_threading expect.deep-cl-irt --cover-letter \
514 --in-reply-to="<test.message>" --thread=deep master
515'
516
517test_expect_success 'thread via config' '
e8107155 518 test_config format.thread true &&
30984ed2
TR
519 check_threading expect.thread master
520'
521
522test_expect_success 'thread deep via config' '
e8107155 523 test_config format.thread deep &&
30984ed2
TR
524 check_threading expect.deep master
525'
526
527test_expect_success 'thread config + override' '
e8107155 528 test_config format.thread deep &&
30984ed2
TR
529 check_threading expect.thread --thread master
530'
531
532test_expect_success 'thread config + --no-thread' '
e8107155 533 test_config format.thread deep &&
30984ed2
TR
534 check_threading expect.no-threading --no-thread master
535'
536
7d812145
DB
537test_expect_success 'excessive subject' '
538
539 rm -rf patches/ &&
540 git checkout side &&
541 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
542 git update-index file &&
543 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." &&
544 git format-patch -o patches/ master..side &&
545 ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
546'
547
5d02294c
JS
548test_expect_success 'cover-letter inherits diff options' '
549
550 git mv file foo &&
551 git commit -m foo &&
5404c116 552 git format-patch --no-renames --cover-letter -1 &&
cc663d14 553 check_patch 0000-cover-letter.patch &&
9524cf29 554 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
5d02294c 555 git format-patch --cover-letter -1 -M &&
9524cf29 556 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
5d02294c
JS
557
558'
859c4fbe
JS
559
560cat > expect << EOF
561 This is an excessively long subject line for a message due to the
562 habit some projects have of not having a short, one-line subject at
563 the start of the commit message, but rather sticking a whole
564 paragraph right at the start as the only thing in the commit
565 message. It had better not become the filename for the patch.
566 foo
567
568EOF
569
570test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
571
572 git format-patch --cover-letter -2 &&
9524cf29 573 sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
3af82863 574 test_cmp expect output
859c4fbe
JS
575
576'
577
68daa64d 578cat > expect << EOF
68daa64d
JK
579index 40f36c6..2dc5c23 100644
580--- a/file
581+++ b/file
582@@ -13,4 +13,20 @@ C
583 10
584 D
585 E
586 F
587+5
588EOF
589
590test_expect_success 'format-patch respects -U' '
591
592 git format-patch -U4 -2 &&
6dd88832
JN
593 sed -e "1,/^diff/d" -e "/^+5/q" \
594 <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
595 >output &&
68daa64d
JK
596 test_cmp expect output
597
598'
599
1d46f2ea
JK
600cat > expect << EOF
601
602diff --git a/file b/file
603index 40f36c6..2dc5c23 100644
604--- a/file
605+++ b/file
606@@ -14,3 +14,19 @@ C
607 D
608 E
609 F
610+5
611EOF
612
613test_expect_success 'format-patch -p suppresses stat' '
614
615 git format-patch -p -2 &&
9524cf29 616 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
1d46f2ea
JK
617 test_cmp expect output
618
619'
620
9800a754
JH
621test_expect_success 'format-patch from a subdirectory (1)' '
622 filename=$(
623 rm -rf sub &&
624 mkdir -p sub/dir &&
625 cd sub/dir &&
626 git format-patch -1
627 ) &&
628 case "$filename" in
629 0*)
630 ;; # ok
631 *)
632 echo "Oops? $filename"
633 false
634 ;;
635 esac &&
636 test -f "$filename"
637'
638
639test_expect_success 'format-patch from a subdirectory (2)' '
640 filename=$(
641 rm -rf sub &&
642 mkdir -p sub/dir &&
643 cd sub/dir &&
644 git format-patch -1 -o ..
645 ) &&
646 case "$filename" in
647 ../0*)
648 ;; # ok
649 *)
650 echo "Oops? $filename"
651 false
652 ;;
653 esac &&
654 basename=$(expr "$filename" : ".*/\(.*\)") &&
655 test -f "sub/$basename"
656'
657
658test_expect_success 'format-patch from a subdirectory (3)' '
9800a754
JH
659 rm -f 0* &&
660 filename=$(
661 rm -rf sub &&
662 mkdir -p sub/dir &&
663 cd sub/dir &&
91c8b825 664 git format-patch -1 -o "$TRASH_DIRECTORY"
9800a754
JH
665 ) &&
666 basename=$(expr "$filename" : ".*/\(.*\)") &&
667 test -f "$basename"
668'
669
f044fe2d
SB
670test_expect_success 'format-patch --in-reply-to' '
671 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
672 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
673 grep "^References: <baz@foo.bar>" patch8
674'
675
676test_expect_success 'format-patch --signoff' '
212620fe
JH
677 git format-patch -1 --signoff --stdout >out &&
678 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
679'
680
681test_expect_success 'format-patch --notes --signoff' '
682 git notes --ref test add -m "test message" HEAD &&
683 git format-patch -1 --signoff --stdout --notes=test >out &&
bd1470b8 684 # Three dashes must come after S-o-b
212620fe 685 ! sed "/^Signed-off-by: /q" out | grep "test message" &&
bd1470b8
JH
686 sed "1,/^Signed-off-by: /d" out | grep "test message" &&
687 # Notes message must come after three dashes
688 ! sed "/^---$/q" out | grep "test message" &&
689 sed "1,/^---$/d" out | grep "test message"
f044fe2d
SB
690'
691
02bc5b03
BG
692echo "fatal: --name-only does not make sense" > expect.name-only
693echo "fatal: --name-status does not make sense" > expect.name-status
694echo "fatal: --check does not make sense" > expect.check
695
68b2a005 696test_expect_success 'options no longer allowed for format-patch' '
02bc5b03 697 test_must_fail git format-patch --name-only 2> output &&
68b2a005 698 test_i18ncmp expect.name-only output &&
02bc5b03 699 test_must_fail git format-patch --name-status 2> output &&
68b2a005 700 test_i18ncmp expect.name-status output &&
02bc5b03 701 test_must_fail git format-patch --check 2> output &&
68b2a005 702 test_i18ncmp expect.check output'
02bc5b03
BG
703
704test_expect_success 'format-patch --numstat should produce a patch' '
4fa80cf0 705 git format-patch --numstat --stdout master..side > output &&
5404c116 706 test 5 = $(grep "^diff --git a/" output | wc -l)'
02bc5b03 707
7e93d3b9
FC
708test_expect_success 'format-patch -- <path>' '
709 git format-patch master..side -- file 2>error &&
710 ! grep "Use .--" error
711'
712
657ab61e
KB
713test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
714 git format-patch --ignore-if-in-upstream HEAD
715'
716
6622d9c7
SB
717test_expect_success 'format-patch --signature' '
718 git format-patch --stdout --signature="my sig" -1 >output &&
719 grep "my sig" output
720'
721
722test_expect_success 'format-patch with format.signature config' '
723 git config format.signature "config sig" &&
724 git format-patch --stdout -1 >output &&
725 grep "config sig" output
726'
727
728test_expect_success 'format-patch --signature overrides format.signature' '
729 git config format.signature "config sig" &&
730 git format-patch --stdout --signature="overrides" -1 >output &&
731 ! grep "config sig" output &&
732 grep "overrides" output
733'
734
735test_expect_success 'format-patch --no-signature ignores format.signature' '
736 git config format.signature "config sig" &&
737 git format-patch --stdout --signature="my sig" --no-signature \
738 -1 >output &&
cc663d14 739 check_patch output &&
6622d9c7
SB
740 ! grep "config sig" output &&
741 ! grep "my sig" output &&
742 ! grep "^-- \$" output
743'
744
745test_expect_success 'format-patch --signature --cover-letter' '
746 git config --unset-all format.signature &&
747 git format-patch --stdout --signature="my sig" --cover-letter \
748 -1 >output &&
749 grep "my sig" output &&
750 test 2 = $(grep "my sig" output | wc -l)
751'
752
41ccfdd9 753test_expect_success 'format.signature="" suppresses signatures' '
6622d9c7
SB
754 git config format.signature "" &&
755 git format-patch --stdout -1 >output &&
cc663d14 756 check_patch output &&
6622d9c7
SB
757 ! grep "^-- \$" output
758'
759
41ccfdd9 760test_expect_success 'format-patch --no-signature suppresses signatures' '
6622d9c7
SB
761 git config --unset-all format.signature &&
762 git format-patch --stdout --no-signature -1 >output &&
cc663d14 763 check_patch output &&
6622d9c7
SB
764 ! grep "^-- \$" output
765'
766
41ccfdd9 767test_expect_success 'format-patch --signature="" suppresses signatures' '
2fdb5c62 768 git format-patch --stdout --signature="" -1 >output &&
cc663d14 769 check_patch output &&
6622d9c7
SB
770 ! grep "^-- \$" output
771'
772
7022650f
JM
773test_expect_success 'prepare mail-signature input' '
774 cat >mail-signature <<-\EOF
775
776 Test User <test.email@kernel.org>
777 http://git.kernel.org/cgit/git/git.git
778
779 git.kernel.org/?p=git/git.git;a=summary
780
781 EOF
782'
783
784test_expect_success '--signature-file=file works' '
785 git format-patch --stdout --signature-file=mail-signature -1 >output &&
786 check_patch output &&
787 sed -e "1,/^-- \$/d" <output >actual &&
788 {
789 cat mail-signature && echo
790 } >expect &&
791 test_cmp expect actual
792'
793
794test_expect_success 'format.signaturefile works' '
795 test_config format.signaturefile mail-signature &&
796 git format-patch --stdout -1 >output &&
797 check_patch output &&
798 sed -e "1,/^-- \$/d" <output >actual &&
799 {
800 cat mail-signature && echo
801 } >expect &&
802 test_cmp expect actual
803'
804
805test_expect_success '--no-signature suppresses format.signaturefile ' '
806 test_config format.signaturefile mail-signature &&
807 git format-patch --stdout --no-signature -1 >output &&
808 check_patch output &&
809 ! grep "^-- \$" output
810'
811
812test_expect_success '--signature-file overrides format.signaturefile' '
99094a7a 813 cat >other-mail-signature <<-\EOF &&
7022650f
JM
814 Use this other signature instead of mail-signature.
815 EOF
816 test_config format.signaturefile mail-signature &&
817 git format-patch --stdout \
818 --signature-file=other-mail-signature -1 >output &&
819 check_patch output &&
820 sed -e "1,/^-- \$/d" <output >actual &&
821 {
822 cat other-mail-signature && echo
823 } >expect &&
824 test_cmp expect actual
825'
826
827test_expect_success '--signature overrides format.signaturefile' '
828 test_config format.signaturefile mail-signature &&
829 git format-patch --stdout --signature="my sig" -1 >output &&
830 check_patch output &&
831 grep "my sig" output
832'
833
38a94bb6
TRC
834test_expect_success TTY 'format-patch --stdout paginates' '
835 rm -f pager_used &&
512477b1 836 test_terminal env GIT_PAGER="wc >pager_used" git format-patch --stdout --all &&
38a94bb6
TRC
837 test_path_is_file pager_used
838'
839
840 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
841 rm -f pager_used &&
512477b1
DT
842 test_terminal env GIT_PAGER="wc >pager_used" git --no-pager format-patch --stdout --all &&
843 test_terminal env GIT_PAGER="wc >pager_used" git -c "pager.format-patch=false" format-patch --stdout --all &&
38a94bb6
TRC
844 test_path_is_missing pager_used &&
845 test_path_is_missing .git/pager_used
846'
847
a1f6baa5
JK
848test_expect_success 'format-patch handles multi-line subjects' '
849 rm -rf patches/ &&
850 echo content >>file &&
851 for i in one two three; do echo $i; done >msg &&
852 git add file &&
853 git commit -F msg &&
854 git format-patch -o patches -1 &&
855 grep ^Subject: patches/0001-one.patch >actual &&
856 echo "Subject: [PATCH] one two three" >expect &&
857 test_cmp expect actual
858'
859
860test_expect_success 'format-patch handles multi-line encoded subjects' '
861 rm -rf patches/ &&
862 echo content >>file &&
863 for i in en två tre; do echo $i; done >msg &&
864 git add file &&
865 git commit -F msg &&
866 git format-patch -o patches -1 &&
867 grep ^Subject: patches/0001-en.patch >actual &&
868 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
869 test_cmp expect actual
870'
871
872M8="foo bar "
873M64=$M8$M8$M8$M8$M8$M8$M8$M8
874M512=$M64$M64$M64$M64$M64$M64$M64$M64
875cat >expect <<'EOF'
876Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
7a76e68a
JS
877 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
878 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
879 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
880 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
881 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
882 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
a1f6baa5 883EOF
7a76e68a 884test_expect_success 'format-patch wraps extremely long subject (ascii)' '
a1f6baa5
JK
885 echo content >>file &&
886 git add file &&
887 git commit -m "$M512" &&
888 git format-patch --stdout -1 >patch &&
889 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
890 test_cmp expect subject
891'
892
893M8="föö bar "
894M64=$M8$M8$M8$M8$M8$M8$M8$M8
895M512=$M64$M64$M64$M64$M64$M64$M64$M64
896cat >expect <<'EOF'
94f6cdf6
JS
897Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
898 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
899 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
900 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
6cd3c053
KS
901 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
902 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
94f6cdf6
JS
903 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
904 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
905 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
6cd3c053
KS
906 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
907 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
94f6cdf6
JS
908 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
909 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
910 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
6cd3c053
KS
911 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
912 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
913 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
914 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
915 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
916 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
917 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
918 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
919 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
920 =?UTF-8?q?bar?=
a1f6baa5 921EOF
94f6cdf6 922test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
a1f6baa5
JK
923 rm -rf patches/ &&
924 echo content >>file &&
925 git add file &&
926 git commit -m "$M512" &&
927 git format-patch --stdout -1 >patch &&
928 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
929 test_cmp expect subject
930'
931
4d03c18a
JK
932check_author() {
933 echo content >>file &&
934 git add file &&
935 GIT_AUTHOR_NAME=$1 git commit -m author-check &&
936 git format-patch --stdout -1 >patch &&
7a76e68a 937 sed -n "/^From: /p; /^ /p; /^$/q" <patch >actual &&
4d03c18a
JK
938 test_cmp expect actual
939}
940
941cat >expect <<'EOF'
942From: "Foo B. Bar" <author@example.com>
943EOF
0fcec2ce 944test_expect_success 'format-patch quotes dot in from-headers' '
4d03c18a
JK
945 check_author "Foo B. Bar"
946'
947
948cat >expect <<'EOF'
949From: "Foo \"The Baz\" Bar" <author@example.com>
950EOF
0fcec2ce 951test_expect_success 'format-patch quotes double-quote in from-headers' '
4d03c18a
JK
952 check_author "Foo \"The Baz\" Bar"
953'
954
955cat >expect <<'EOF'
0fcec2ce 956From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
4d03c18a 957EOF
0fcec2ce
JS
958test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
959 check_author "Föo Bar"
960'
961
962cat >expect <<'EOF'
963From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
964EOF
41dd00ba 965test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
4d03c18a
JK
966 check_author "Föo B. Bar"
967'
968
7a76e68a
JS
969cat >expect <<EOF
970From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
971 <author@example.com>
972EOF
973test_expect_success 'format-patch wraps moderately long from-header (ascii)' '
974 check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
975'
976
977cat >expect <<'EOF'
978From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
979 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
980 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
981EOF
982test_expect_success 'format-patch wraps extremely long from-header (ascii)' '
983 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"
984'
985
986cat >expect <<'EOF'
987From: "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 Foo
989 Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
990EOF
991test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
992 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"
993'
994
4d03c18a 995cat >expect <<'EOF'
94f6cdf6
JS
996From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
997 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
998 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
999 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
1000 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
1001EOF
1002test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
1003 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"
1004'
1005
1006cat >expect <<'EOF'
4d03c18a
JK
1007Subject: header with . in it
1008EOF
1009test_expect_success 'subject lines do not have 822 atom-quoting' '
1010 echo content >>file &&
1011 git add file &&
1012 git commit -m "header with . in it" &&
1013 git format-patch -k -1 --stdout >patch &&
1014 grep ^Subject: patch >actual &&
1015 test_cmp expect actual
1016'
1017
e7af8e49
JK
1018cat >expect <<'EOF'
1019Subject: [PREFIX 1/1] header with . in it
1020EOF
1021test_expect_success 'subject prefixes have space prepended' '
1022 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
1023 grep ^Subject: patch >actual &&
1024 test_cmp expect actual
1025'
1026
1027cat >expect <<'EOF'
1028Subject: [1/1] header with . in it
1029EOF
1030test_expect_success 'empty subject prefix does not have extra space' '
1031 git format-patch -n -1 --stdout --subject-prefix= >patch &&
1032 grep ^Subject: patch >actual &&
1033 test_cmp expect actual
1034'
1035
a9080475
JK
1036test_expect_success '--from=ident notices bogus ident' '
1037 test_must_fail git format-patch -1 --stdout --from=foo >patch
1038'
1039
1040test_expect_success '--from=ident replaces author' '
1041 git format-patch -1 --stdout --from="Me <me@example.com>" >patch &&
1042 cat >expect <<-\EOF &&
1043 From: Me <me@example.com>
1044
1045 From: A U Thor <author@example.com>
1046
1047 EOF
1048 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1049 test_cmp expect patch.head
1050'
1051
1052test_expect_success '--from uses committer ident' '
1053 git format-patch -1 --stdout --from >patch &&
1054 cat >expect <<-\EOF &&
1055 From: C O Mitter <committer@example.com>
1056
1057 From: A U Thor <author@example.com>
1058
1059 EOF
1060 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1061 test_cmp expect patch.head
1062'
1063
662cc30c
JK
1064test_expect_success '--from omits redundant in-body header' '
1065 git format-patch -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1066 cat >expect <<-\EOF &&
1067 From: A U Thor <author@example.com>
1068
1069 EOF
1070 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1071 test_cmp expect patch.head
1072'
1073
a9080475 1074test_expect_success 'in-body headers trigger content encoding' '
d2554c72 1075 test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
a9080475
JK
1076 test_when_finished "git reset --hard HEAD^" &&
1077 git format-patch -1 --stdout --from >patch &&
1078 cat >expect <<-\EOF &&
1079 From: C O Mitter <committer@example.com>
1080 Content-Type: text/plain; charset=UTF-8
1081
1082 From: éxötìc <author@example.com>
1083
1084 EOF
1085 sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" <patch >patch.head &&
1086 test_cmp expect patch.head
1087'
1088
79133a66
NTND
1089append_signoff()
1090{
1091 C=$(git commit-tree HEAD^^{tree} -p HEAD) &&
1092 git format-patch --stdout --signoff $C^..$C >append_signoff.patch &&
1093 sed -n -e "1,/^---$/p" append_signoff.patch |
1094 egrep -n "^Subject|Sign|^$"
1095}
1096
1097test_expect_success 'signoff: commit with no body' '
1098 append_signoff </dev/null >actual &&
1099 cat <<\EOF | sed "s/EOL$//" >expected &&
11004:Subject: [PATCH] EOL
11018:
11029:Signed-off-by: C O Mitter <committer@example.com>
1103EOF
1104 test_cmp expected actual
1105'
1106
1107test_expect_success 'signoff: commit with only subject' '
1108 echo subject | append_signoff >actual &&
1109 cat >expected <<\EOF &&
11104:Subject: [PATCH] subject
11118:
11129:Signed-off-by: C O Mitter <committer@example.com>
1113EOF
1114 test_cmp expected actual
1115'
1116
1117test_expect_success 'signoff: commit with only subject that does not end with NL' '
1118 printf subject | append_signoff >actual &&
1119 cat >expected <<\EOF &&
11204:Subject: [PATCH] subject
11218:
11229:Signed-off-by: C O Mitter <committer@example.com>
1123EOF
1124 test_cmp expected actual
1125'
1126
1127test_expect_success 'signoff: no existing signoffs' '
1128 append_signoff <<\EOF >actual &&
1129subject
1130
1131body
1132EOF
1133 cat >expected <<\EOF &&
11344:Subject: [PATCH] subject
11358:
113610:
113711:Signed-off-by: C O Mitter <committer@example.com>
1138EOF
1139 test_cmp expected actual
1140'
1141
1142test_expect_success 'signoff: no existing signoffs and no trailing NL' '
1143 printf "subject\n\nbody" | append_signoff >actual &&
1144 cat >expected <<\EOF &&
11454:Subject: [PATCH] subject
11468:
114710:
114811:Signed-off-by: C O Mitter <committer@example.com>
1149EOF
1150 test_cmp expected actual
1151'
1152
1153test_expect_success 'signoff: some random signoff' '
1154 append_signoff <<\EOF >actual &&
1155subject
1156
1157body
1158
1159Signed-off-by: my@house
1160EOF
1161 cat >expected <<\EOF &&
11624:Subject: [PATCH] subject
11638:
116410:
116511:Signed-off-by: my@house
116612:Signed-off-by: C O Mitter <committer@example.com>
1167EOF
1168 test_cmp expected actual
1169'
1170
959a2623
BC
1171test_expect_success 'signoff: misc conforming footer elements' '
1172 append_signoff <<\EOF >actual &&
1173subject
1174
1175body
1176
1177Signed-off-by: my@house
1178(cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1179Tested-by: Some One <someone@example.com>
1180Bug: 1234
1181EOF
1182 cat >expected <<\EOF &&
11834:Subject: [PATCH] subject
11848:
118510:
118611:Signed-off-by: my@house
118715:Signed-off-by: C O Mitter <committer@example.com>
1188EOF
1189 test_cmp expected actual
1190'
1191
1192test_expect_success 'signoff: some random signoff-alike' '
79133a66
NTND
1193 append_signoff <<\EOF >actual &&
1194subject
1195
1196body
1197Fooled-by-me: my@house
1198EOF
1199 cat >expected <<\EOF &&
12004:Subject: [PATCH] subject
12018:
120211:
120312:Signed-off-by: C O Mitter <committer@example.com>
1204EOF
1205 test_cmp expected actual
1206'
1207
959a2623 1208test_expect_success 'signoff: not really a signoff' '
79133a66
NTND
1209 append_signoff <<\EOF >actual &&
1210subject
1211
1212I want to mention about Signed-off-by: here.
1213EOF
1214 cat >expected <<\EOF &&
12154:Subject: [PATCH] subject
12168:
12179:I want to mention about Signed-off-by: here.
121810:
121911:Signed-off-by: C O Mitter <committer@example.com>
1220EOF
1221 test_cmp expected actual
1222'
1223
959a2623 1224test_expect_success 'signoff: not really a signoff (2)' '
79133a66
NTND
1225 append_signoff <<\EOF >actual &&
1226subject
1227
1228My unfortunate
1229Signed-off-by: example happens to be wrapped here.
1230EOF
1231 cat >expected <<\EOF &&
12324:Subject: [PATCH] subject
12338:
123410:Signed-off-by: example happens to be wrapped here.
123511:
123612:Signed-off-by: C O Mitter <committer@example.com>
1237EOF
1238 test_cmp expected actual
1239'
1240
959a2623 1241test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
79133a66
NTND
1242 append_signoff <<\EOF >actual &&
1243subject
1244
1245Signed-off-by: my@house
1246Signed-off-by: your@house
1247
1248A lot of houses.
1249EOF
1250 cat >expected <<\EOF &&
12514:Subject: [PATCH] subject
12528:
12539:Signed-off-by: my@house
125410:Signed-off-by: your@house
125511:
125613:
125714:Signed-off-by: C O Mitter <committer@example.com>
1258EOF
1259 test_cmp expected actual
1260'
1261
1262test_expect_success 'signoff: the same signoff at the end' '
1263 append_signoff <<\EOF >actual &&
1264subject
1265
1266body
1267
1268Signed-off-by: C O Mitter <committer@example.com>
1269EOF
1270 cat >expected <<\EOF &&
12714:Subject: [PATCH] subject
12728:
127310:
127411:Signed-off-by: C O Mitter <committer@example.com>
1275EOF
1276 test_cmp expected actual
1277'
1278
1279test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
1280 printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
1281 append_signoff >actual &&
1282 cat >expected <<\EOF &&
12834:Subject: [PATCH] subject
12848:
12859:Signed-off-by: C O Mitter <committer@example.com>
1286EOF
1287 test_cmp expected actual
1288'
1289
1290test_expect_success 'signoff: the same signoff NOT at the end' '
1291 append_signoff <<\EOF >actual &&
1292subject
1293
1294body
1295
1296Signed-off-by: C O Mitter <committer@example.com>
1297Signed-off-by: my@house
1298EOF
1299 cat >expected <<\EOF &&
13004:Subject: [PATCH] subject
13018:
130210:
130311:Signed-off-by: C O Mitter <committer@example.com>
130412:Signed-off-by: my@house
1305EOF
1306 test_cmp expected actual
1307'
1308
959a2623 1309test_expect_success 'signoff: detect garbage in non-conforming footer' '
79133a66
NTND
1310 append_signoff <<\EOF >actual &&
1311subject
1312
1313body
1314
1315Tested-by: my@house
1316Some Trash
1317Signed-off-by: C O Mitter <committer@example.com>
1318EOF
1319 cat >expected <<\EOF &&
13204:Subject: [PATCH] subject
13218:
132210:
132313:Signed-off-by: C O Mitter <committer@example.com>
132414:
132515:Signed-off-by: C O Mitter <committer@example.com>
1326EOF
1327 test_cmp expected actual
1328'
1329
1330test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
1331 append_signoff <<\EOF >actual &&
1332subject
1333
1334body
1335
1336Reviewed-id: Noone
1337Tested-by: my@house
1338Change-id: Ideadbeef
1339Signed-off-by: C O Mitter <committer@example.com>
1340Bug: 1234
1341EOF
1342 cat >expected <<\EOF &&
13434:Subject: [PATCH] subject
13448:
134510:
134614:Signed-off-by: C O Mitter <committer@example.com>
1347EOF
1348 test_cmp expected actual
1349'
1350
787570c7
PYH
1351test_expect_success 'format patch ignores color.ui' '
1352 test_unconfig color.ui &&
1353 git format-patch --stdout -1 >expect &&
1354 test_config color.ui always &&
1355 git format-patch --stdout -1 >actual &&
1356 test_cmp expect actual
1357'
1358
e216cc48
NTND
1359test_expect_success 'cover letter using branch description (1)' '
1360 git checkout rebuild-1 &&
1361 test_config branch.rebuild-1.description hello &&
1362 git format-patch --stdout --cover-letter master >actual &&
1363 grep hello actual >/dev/null
1364'
1365
1366test_expect_success 'cover letter using branch description (2)' '
1367 git checkout rebuild-1 &&
1368 test_config branch.rebuild-1.description hello &&
1369 git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
1370 grep hello actual >/dev/null
1371'
1372
1373test_expect_success 'cover letter using branch description (3)' '
1374 git checkout rebuild-1 &&
1375 test_config branch.rebuild-1.description hello &&
1376 git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
1377 grep hello actual >/dev/null
1378'
1379
20b630aa
NTND
1380test_expect_success 'cover letter using branch description (4)' '
1381 git checkout rebuild-1 &&
1382 test_config branch.rebuild-1.description hello &&
1383 git format-patch --stdout --cover-letter master.. >actual &&
1384 grep hello actual >/dev/null
1385'
1386
1387test_expect_success 'cover letter using branch description (5)' '
1388 git checkout rebuild-1 &&
1389 test_config branch.rebuild-1.description hello &&
1390 git format-patch --stdout --cover-letter -2 HEAD >actual &&
1391 grep hello actual >/dev/null
1392'
1393
5ee29aef
NTND
1394test_expect_success 'cover letter using branch description (6)' '
1395 git checkout rebuild-1 &&
1396 test_config branch.rebuild-1.description hello &&
1397 git format-patch --stdout --cover-letter -2 >actual &&
1398 grep hello actual >/dev/null
1399'
1400
80d35ca0
FC
1401test_expect_success 'cover letter with nothing' '
1402 git format-patch --stdout --cover-letter >actual &&
1403 test_line_count = 0 actual
1404'
1405
2a4c2607
FC
1406test_expect_success 'cover letter auto' '
1407 mkdir -p tmp &&
1408 test_when_finished "rm -rf tmp;
1409 git config --unset format.coverletter" &&
1410
1411 git config format.coverletter auto &&
1412 git format-patch -o tmp -1 >list &&
1413 test_line_count = 1 list &&
1414 git format-patch -o tmp -2 >list &&
1415 test_line_count = 3 list
1416'
1417
1418test_expect_success 'cover letter auto user override' '
1419 mkdir -p tmp &&
1420 test_when_finished "rm -rf tmp;
1421 git config --unset format.coverletter" &&
1422
1423 git config format.coverletter auto &&
1424 git format-patch -o tmp --cover-letter -1 >list &&
1425 test_line_count = 2 list &&
1426 git format-patch -o tmp --cover-letter -2 >list &&
1427 test_line_count = 3 list &&
1428 git format-patch -o tmp --no-cover-letter -1 >list &&
1429 test_line_count = 1 list &&
1430 git format-patch -o tmp --no-cover-letter -2 >list &&
1431 test_line_count = 2 list
1432'
1433
3a30aa17 1434test_expect_success 'format-patch --zero-commit' '
1435 git format-patch --zero-commit --stdout v2..v1 >patch2 &&
1436 grep "^From " patch2 | sort | uniq >actual &&
1437 echo "From $_z40 Mon Sep 17 00:00:00 2001" >expect &&
1438 test_cmp expect actual
1439'
1440
06dfc9eb 1441test_expect_success 'From line has expected format' '
1442 git format-patch --stdout v2..v1 >patch2 &&
1443 grep "^From " patch2 >from &&
1444 grep "^From $_x40 Mon Sep 17 00:00:00 2001$" patch2 >filtered &&
1445 test_cmp from filtered
1446'
1447
bc6bf2d7
AK
1448test_expect_success 'format-patch format.outputDirectory option' '
1449 test_config format.outputDirectory patches &&
1450 rm -fr patches &&
1451 git format-patch master..side &&
1452 test $(git rev-list master..side | wc -l) -eq $(ls patches | wc -l)
1453'
1454
1455test_expect_success 'format-patch -o overrides format.outputDirectory' '
1456 test_config format.outputDirectory patches &&
1457 rm -fr patches patchset &&
1458 git format-patch master..side -o patchset &&
1459 test_path_is_missing patches &&
1460 test_path_is_dir patchset
1461'
1462
fa2ab86d
XY
1463test_expect_success 'format-patch --base' '
1464 git checkout side &&
1465 git format-patch --stdout --base=HEAD~3 -1 >patch &&
1466 grep "^base-commit:" patch >actual &&
1467 grep "^prerequisite-patch-id:" patch >>actual &&
1468 echo "base-commit: $(git rev-parse HEAD~3)" >expected &&
1469 echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1470 echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1471 test_cmp expected actual
1472'
1473
1474test_expect_success 'format-patch --base errors out when base commit is in revision list' '
1475 test_must_fail git format-patch --base=HEAD -2 &&
1476 test_must_fail git format-patch --base=HEAD~1 -2 &&
1477 git format-patch --stdout --base=HEAD~2 -2 >patch &&
1478 grep "^base-commit:" patch >actual &&
1479 echo "base-commit: $(git rev-parse HEAD~2)" >expected &&
1480 test_cmp expected actual
1481'
1482
1483test_expect_success 'format-patch --base errors out when base commit is not ancestor of revision list' '
1484 # For history as below:
1485 #
1486 # ---Q---P---Z---Y---*---X
1487 # \ /
1488 # ------------W
1489 #
1490 # If "format-patch Z..X" is given, P and Z can not be specified as the base commit
1491 git checkout -b topic1 master &&
1492 git rev-parse HEAD >commit-id-base &&
1493 test_commit P &&
1494 git rev-parse HEAD >commit-id-P &&
1495 test_commit Z &&
1496 git rev-parse HEAD >commit-id-Z &&
1497 test_commit Y &&
1498 git checkout -b topic2 master &&
1499 test_commit W &&
1500 git merge topic1 &&
1501 test_commit X &&
1502 test_must_fail git format-patch --base=$(cat commit-id-P) -3 &&
1503 test_must_fail git format-patch --base=$(cat commit-id-Z) -3 &&
1504 git format-patch --stdout --base=$(cat commit-id-base) -3 >patch &&
1505 grep "^base-commit:" patch >actual &&
1506 echo "base-commit: $(cat commit-id-base)" >expected &&
1507 test_cmp expected actual
1508'
1509
3de66517
XY
1510test_expect_success 'format-patch --base=auto' '
1511 git checkout -b upstream master &&
1512 git checkout -b local upstream &&
1513 git branch --set-upstream-to=upstream &&
1514 test_commit N1 &&
1515 test_commit N2 &&
1516 git format-patch --stdout --base=auto -2 >patch &&
1517 grep "^base-commit:" patch >actual &&
1518 echo "base-commit: $(git rev-parse upstream)" >expected &&
1519 test_cmp expected actual
1520'
1521
1522test_expect_success 'format-patch errors out when history involves criss-cross' '
1523 # setup criss-cross history
1524 #
1525 # B---M1---D
1526 # / \ /
1527 # A X
1528 # \ / \
1529 # C---M2---E
1530 #
1531 git checkout master &&
1532 test_commit A &&
1533 git checkout -b xb master &&
1534 test_commit B &&
1535 git checkout -b xc master &&
1536 test_commit C &&
1537 git checkout -b xbc xb -- &&
1538 git merge xc &&
1539 git checkout -b xcb xc -- &&
1540 git branch --set-upstream-to=xbc &&
1541 git merge xb &&
1542 git checkout xbc &&
1543 test_commit D &&
1544 git checkout xcb &&
1545 test_commit E &&
1546 test_must_fail git format-patch --base=auto -1
1547'
1548
bb52995f
XY
1549test_expect_success 'format-patch format.useAutoBaseoption' '
1550 test_when_finished "git config --unset format.useAutoBase" &&
1551 git checkout local &&
1552 git config format.useAutoBase true &&
1553 git format-patch --stdout -1 >patch &&
1554 grep "^base-commit:" patch >actual &&
1555 echo "base-commit: $(git rev-parse upstream)" >expected &&
1556 test_cmp expected actual
1557'
1558
1559test_expect_success 'format-patch --base overrides format.useAutoBase' '
1560 test_when_finished "git config --unset format.useAutoBase" &&
1561 git config format.useAutoBase true &&
1562 git format-patch --stdout --base=HEAD~1 -1 >patch &&
1563 grep "^base-commit:" patch >actual &&
1564 echo "base-commit: $(git rev-parse HEAD~1)" >expected &&
1565 test_cmp expected actual
1566'
1567
ece3c67f 1568test_done