]> git.ipfire.org Git - thirdparty/git.git/blame - t/t4014-format-patch.sh
Merge branch 'en/ort-finalize-after-0-merges-fix'
[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 7
8f37854b 8GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
334afbc7
JS
9export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
10
ece3c67f 11. ./test-lib.sh
38a94bb6 12. "$TEST_DIRECTORY"/lib-terminal.sh
ece3c67f
JH
13
14test_expect_success setup '
08495412 15 test_write_lines 1 2 3 4 5 6 7 8 9 10 >file &&
cd894ee9
JH
16 cat file >elif &&
17 git add file elif &&
6426f2d2 18 test_tick &&
ece3c67f
JH
19 git commit -m Initial &&
20 git checkout -b side &&
21
08495412 22 test_write_lines 1 2 5 6 A B C 7 8 9 10 >file &&
1f553918 23 test_chmod +x elif &&
6426f2d2 24 test_tick &&
816366e2 25 git commit -m "Side changes #1" &&
ece3c67f 26
08495412 27 test_write_lines D E F >>file &&
ece3c67f 28 git update-index file &&
6426f2d2 29 test_tick &&
816366e2 30 git commit -m "Side changes #2" &&
982b64e4 31 git tag C2 &&
ece3c67f 32
08495412 33 test_write_lines 5 6 1 2 3 A 4 B C 7 8 9 10 D E F >file &&
ece3c67f 34 git update-index file &&
6426f2d2 35 test_tick &&
816366e2 36 git commit -m "Side changes #3 with \\n backslash-n in it." &&
ece3c67f 37
8f37854b 38 git checkout main &&
854b5cb4
DL
39 git diff-tree -p C2 >patch &&
40 git apply --index <patch &&
6426f2d2 41 test_tick &&
8f37854b 42 git commit -m "Main accepts moral equivalent of #2" &&
ece3c67f 43
6f93d261
SB
44 git checkout side &&
45 git checkout -b patchid &&
08495412
ES
46 test_write_lines 5 6 1 2 3 A 4 B C 7 8 9 10 D E F >file2 &&
47 test_write_lines 1 2 3 A 4 B C 7 8 9 10 D E F 5 6 >file3 &&
48 test_write_lines 8 9 10 >file &&
6f93d261
SB
49 git add file file2 file3 &&
50 test_tick &&
51 git commit -m "patchid 1" &&
08495412
ES
52 test_write_lines 4 A B 7 8 9 10 >file2 &&
53 test_write_lines 8 9 10 5 6 >file3 &&
6f93d261
SB
54 git add file2 file3 &&
55 test_tick &&
56 git commit -m "patchid 2" &&
08495412 57 test_write_lines 10 5 6 >file &&
6f93d261
SB
58 git add file &&
59 test_tick &&
60 git commit -m "patchid 3" &&
61
94c42894
JK
62 git checkout -b empty main &&
63 test_tick &&
64 git commit --allow-empty -m "empty commit" &&
65
8f37854b 66 git checkout main
ece3c67f
JH
67'
68
0ab74e97 69test_expect_success 'format-patch --ignore-if-in-upstream' '
8f37854b 70 git format-patch --stdout main..side >patch0 &&
6bd26f58
DL
71 grep "^From " patch0 >from0 &&
72 test_line_count = 3 from0
ece3c67f
JH
73'
74
0ab74e97 75test_expect_success 'format-patch --ignore-if-in-upstream' '
ece3c67f 76 git format-patch --stdout \
8f37854b 77 --ignore-if-in-upstream main..side >patch1 &&
6bd26f58
DL
78 grep "^From " patch1 >from1 &&
79 test_line_count = 2 from1
ece3c67f
JH
80'
81
0ab74e97 82test_expect_success 'format-patch --ignore-if-in-upstream handles tags' '
9b7a61d7 83 git tag -a v1 -m tag side &&
8f37854b 84 git tag -a v2 -m tag main &&
9b7a61d7 85 git format-patch --stdout --ignore-if-in-upstream v2..v1 >patch1 &&
6bd26f58
DL
86 grep "^From " patch1 >from1 &&
87 test_line_count = 2 from1
9b7a61d7
JH
88'
89
2c642ed8 90test_expect_success "format-patch doesn't consider merge commits" '
8f37854b 91 git checkout -b feature main &&
2c642ed8
RR
92 echo "Another line" >>file &&
93 test_tick &&
08dc2606 94 git commit -am "Feature branch change #1" &&
2c642ed8
RR
95 echo "Yet another line" >>file &&
96 test_tick &&
08dc2606 97 git commit -am "Feature branch change #2" &&
8f37854b 98 git checkout -b merger main &&
2c642ed8 99 test_tick &&
08dc2606 100 git merge --no-ff feature &&
6bd26f58
DL
101 git format-patch -3 --stdout >patch &&
102 grep "^From " patch >from &&
103 test_line_count = 3 from
2c642ed8
RR
104'
105
0ab74e97 106test_expect_success 'format-patch result applies' '
8f37854b 107 git checkout -b rebuild-0 main &&
ece3c67f 108 git am -3 patch0 &&
8f37854b 109 git rev-list main.. >list &&
6bd26f58 110 test_line_count = 2 list
ece3c67f
JH
111'
112
0ab74e97 113test_expect_success 'format-patch --ignore-if-in-upstream result applies' '
8f37854b 114 git checkout -b rebuild-1 main &&
ece3c67f 115 git am -3 patch1 &&
8f37854b 116 git rev-list main.. >list &&
6bd26f58 117 test_line_count = 2 list
ece3c67f
JH
118'
119
816366e2 120test_expect_success 'commit did not screw up the log message' '
854b5cb4
DL
121 git cat-file commit side >actual &&
122 grep "^Side .* with .* backslash-n" actual
816366e2
JH
123'
124
125test_expect_success 'format-patch did not screw up the log message' '
816366e2
JH
126 grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
127 grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
816366e2
JH
128'
129
130test_expect_success 'replay did not screw up the log message' '
854b5cb4
DL
131 git cat-file commit rebuild-1 >actual &&
132 grep "^Side .* with .* backslash-n" actual
816366e2
JH
133'
134
94c42894
JK
135test_expect_success 'format-patch empty commit' '
136 git format-patch --stdout main..empty >empty &&
137 grep "^From " empty >from &&
138 test_line_count = 1 from
139'
140
a8d8173e 141test_expect_success 'extra headers' '
25dc8dad 142 git config format.headers "To: R E Cipient <rcipient@example.com>
a8d8173e 143" &&
25dc8dad 144 git config --add format.headers "Cc: S E Cipient <scipient@example.com>
a8d8173e 145" &&
8f37854b 146 git format-patch --stdout main..side >patch2 &&
92014b69 147 sed -e "/^\$/q" patch2 >hdrs2 &&
25dc8dad
JS
148 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs2 &&
149 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs2
a8d8173e
DB
150'
151
7d22708b 152test_expect_success 'extra headers without newlines' '
25dc8dad
JS
153 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
154 git config --add format.headers "Cc: S E Cipient <scipient@example.com>" &&
8f37854b 155 git format-patch --stdout main..side >patch3 &&
92014b69 156 sed -e "/^\$/q" patch3 >hdrs3 &&
25dc8dad
JS
157 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs3 &&
158 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs3
a8d8173e
DB
159'
160
3ee79d9f 161test_expect_success 'extra headers with multiple To:s' '
25dc8dad
JS
162 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
163 git config --add format.headers "To: S E Cipient <scipient@example.com>" &&
8f37854b 164 git format-patch --stdout main..side >patch4 &&
92014b69 165 sed -e "/^\$/q" patch4 >hdrs4 &&
25dc8dad
JS
166 grep "^To: R E Cipient <rcipient@example.com>,\$" hdrs4 &&
167 grep "^ *S E Cipient <scipient@example.com>\$" hdrs4
a8d8173e
DB
168'
169
25dc8dad 170test_expect_success 'additional command line cc (ascii)' '
25dc8dad 171 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
8f37854b 172 git format-patch --cc="S E Cipient <scipient@example.com>" --stdout main..side >patch5 &&
854b5cb4
DL
173 sed -e "/^\$/q" patch5 >hdrs5 &&
174 grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs5 &&
175 grep "^ *S E Cipient <scipient@example.com>\$" hdrs5
25dc8dad
JS
176'
177
178test_expect_failure 'additional command line cc (rfc822)' '
25dc8dad 179 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
8f37854b 180 git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout main..side >patch5 &&
854b5cb4
DL
181 sed -e "/^\$/q" patch5 >hdrs5 &&
182 grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs5 &&
183 grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" hdrs5
736cc67d
DB
184'
185
d7d9c2d0 186test_expect_success 'command line headers' '
d7d9c2d0 187 git config --unset-all format.headers &&
8f37854b 188 git format-patch --add-header="Cc: R E Cipient <rcipient@example.com>" --stdout main..side >patch6 &&
854b5cb4
DL
189 sed -e "/^\$/q" patch6 >hdrs6 &&
190 grep "^Cc: R E Cipient <rcipient@example.com>\$" hdrs6
d7d9c2d0
MH
191'
192
193test_expect_success 'configuration headers and command line headers' '
25dc8dad 194 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
8f37854b 195 git format-patch --add-header="Cc: S E Cipient <scipient@example.com>" --stdout main..side >patch7 &&
854b5cb4
DL
196 sed -e "/^\$/q" patch7 >hdrs7 &&
197 grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs7 &&
198 grep "^ *S E Cipient <scipient@example.com>\$" hdrs7
d7d9c2d0
MH
199'
200
25dc8dad 201test_expect_success 'command line To: header (ascii)' '
ae6c098f 202 git config --unset-all format.headers &&
8f37854b 203 git format-patch --to="R E Cipient <rcipient@example.com>" --stdout main..side >patch8 &&
854b5cb4
DL
204 sed -e "/^\$/q" patch8 >hdrs8 &&
205 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs8
25dc8dad
JS
206'
207
208test_expect_failure 'command line To: header (rfc822)' '
8f37854b 209 git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout main..side >patch8 &&
854b5cb4
DL
210 sed -e "/^\$/q" patch8 >hdrs8 &&
211 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" hdrs8
25dc8dad
JS
212'
213
214test_expect_failure 'command line To: header (rfc2047)' '
8f37854b 215 git format-patch --to="R Ä Cipient <rcipient@example.com>" --stdout main..side >patch8 &&
854b5cb4
DL
216 sed -e "/^\$/q" patch8 >hdrs8 &&
217 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" hdrs8
ae6c098f
SD
218'
219
25dc8dad 220test_expect_success 'configuration To: header (ascii)' '
25dc8dad 221 git config format.to "R E Cipient <rcipient@example.com>" &&
8f37854b 222 git format-patch --stdout main..side >patch9 &&
854b5cb4
DL
223 sed -e "/^\$/q" patch9 >hdrs9 &&
224 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs9
25dc8dad
JS
225'
226
227test_expect_failure 'configuration To: header (rfc822)' '
ae6c098f 228 git config format.to "R. E. Cipient <rcipient@example.com>" &&
8f37854b 229 git format-patch --stdout main..side >patch9 &&
854b5cb4
DL
230 sed -e "/^\$/q" patch9 >hdrs9 &&
231 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" hdrs9
25dc8dad
JS
232'
233
234test_expect_failure 'configuration To: header (rfc2047)' '
25dc8dad 235 git config format.to "R Ä Cipient <rcipient@example.com>" &&
8f37854b 236 git format-patch --stdout main..side >patch9 &&
854b5cb4
DL
237 sed -e "/^\$/q" patch9 >hdrs9 &&
238 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" hdrs9
ae6c098f
SD
239'
240
cc663d14
TR
241# check_patch <patch>: Verify that <patch> looks like a half-sane
242# patch email to avoid a false positive with !grep
243check_patch () {
244 grep -e "^From:" "$1" &&
245 grep -e "^Date:" "$1" &&
246 grep -e "^Subject:" "$1"
247}
248
6bc6b6c0 249test_expect_success 'format.from=false' '
8f37854b 250 git -c format.from=false format-patch --stdout main..side >patch &&
854b5cb4 251 sed -e "/^\$/q" patch >hdrs &&
6bc6b6c0 252 check_patch patch &&
854b5cb4 253 ! grep "^From: C O Mitter <committer@example.com>\$" hdrs
6bc6b6c0
JT
254'
255
256test_expect_success 'format.from=true' '
8f37854b 257 git -c format.from=true format-patch --stdout main..side >patch &&
854b5cb4
DL
258 sed -e "/^\$/q" patch >hdrs &&
259 check_patch hdrs &&
260 grep "^From: C O Mitter <committer@example.com>\$" hdrs
6bc6b6c0
JT
261'
262
263test_expect_success 'format.from with address' '
8f37854b 264 git -c format.from="F R Om <from@example.com>" format-patch --stdout main..side >patch &&
854b5cb4
DL
265 sed -e "/^\$/q" patch >hdrs &&
266 check_patch hdrs &&
267 grep "^From: F R Om <from@example.com>\$" hdrs
6bc6b6c0
JT
268'
269
270test_expect_success '--no-from overrides format.from' '
8f37854b 271 git -c format.from="F R Om <from@example.com>" format-patch --no-from --stdout main..side >patch &&
854b5cb4
DL
272 sed -e "/^\$/q" patch >hdrs &&
273 check_patch hdrs &&
274 ! grep "^From: F R Om <from@example.com>\$" hdrs
6bc6b6c0
JT
275'
276
277test_expect_success '--from overrides format.from' '
8f37854b 278 git -c format.from="F R Om <from@example.com>" format-patch --from --stdout main..side >patch &&
854b5cb4
DL
279 sed -e "/^\$/q" patch >hdrs &&
280 check_patch hdrs &&
281 ! grep "^From: F R Om <from@example.com>\$" hdrs
6bc6b6c0
JT
282'
283
c4260034 284test_expect_success '--no-to overrides config.to' '
c4260034 285 git config --replace-all format.to \
25dc8dad 286 "R E Cipient <rcipient@example.com>" &&
8f37854b 287 git format-patch --no-to --stdout main..side >patch10 &&
854b5cb4
DL
288 sed -e "/^\$/q" patch10 >hdrs10 &&
289 check_patch hdrs10 &&
290 ! grep "^To: R E Cipient <rcipient@example.com>\$" hdrs10
c4260034
SB
291'
292
293test_expect_success '--no-to and --to replaces config.to' '
c4260034
SB
294 git config --replace-all format.to \
295 "Someone <someone@out.there>" &&
296 git format-patch --no-to --to="Someone Else <else@out.there>" \
8f37854b 297 --stdout main..side >patch11 &&
854b5cb4
DL
298 sed -e "/^\$/q" patch11 >hdrs11 &&
299 check_patch hdrs11 &&
300 ! grep "^To: Someone <someone@out.there>\$" hdrs11 &&
301 grep "^To: Someone Else <else@out.there>\$" hdrs11
c4260034
SB
302'
303
304test_expect_success '--no-cc overrides config.cc' '
c4260034 305 git config --replace-all format.cc \
25dc8dad 306 "C E Cipient <rcipient@example.com>" &&
8f37854b 307 git format-patch --no-cc --stdout main..side >patch12 &&
854b5cb4
DL
308 sed -e "/^\$/q" patch12 >hdrs12 &&
309 check_patch hdrs12 &&
310 ! grep "^Cc: C E Cipient <rcipient@example.com>\$" hdrs12
c4260034
SB
311'
312
688f4f2f 313test_expect_success '--no-add-header overrides config.headers' '
c4260034 314 git config --replace-all format.headers \
25dc8dad 315 "Header1: B E Cipient <rcipient@example.com>" &&
8f37854b 316 git format-patch --no-add-header --stdout main..side >patch13 &&
854b5cb4
DL
317 sed -e "/^\$/q" patch13 >hdrs13 &&
318 check_patch hdrs13 &&
319 ! grep "^Header1: B E Cipient <rcipient@example.com>\$" hdrs13
c4260034
SB
320'
321
7d812145 322test_expect_success 'multiple files' '
7d812145
DB
323 rm -rf patches/ &&
324 git checkout side &&
8f37854b 325 git format-patch -o patches/ main &&
7d812145
DB
326 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
327'
328
3baf58bf
JH
329test_expect_success 'filename length limit' '
330 test_when_finished "rm -f 000*" &&
331 rm -rf 000[1-9]-*.patch &&
332 for len in 15 25 35
333 do
334 git format-patch --filename-max-length=$len -3 side &&
335 max=$(
336 for patch in 000[1-9]-*.patch
337 do
cbe1d9d6 338 echo "$patch" | wc -c || exit 1
3baf58bf
JH
339 done |
340 sort -nr |
341 head -n 1
342 ) &&
343 test $max -le $len || return 1
344 done
345'
346
347test_expect_success 'filename length limit from config' '
348 test_when_finished "rm -f 000*" &&
349 rm -rf 000[1-9]-*.patch &&
350 for len in 15 25 35
351 do
352 git -c format.filenameMaxLength=$len format-patch -3 side &&
353 max=$(
354 for patch in 000[1-9]-*.patch
355 do
cbe1d9d6 356 echo "$patch" | wc -c || exit 1
3baf58bf
JH
357 done |
358 sort -nr |
359 head -n 1
360 ) &&
361 test $max -le $len || return 1
362 done
363'
364
365test_expect_success 'filename limit applies only to basename' '
366 test_when_finished "rm -rf patches/" &&
367 rm -rf patches/ &&
368 for len in 15 25 35
369 do
370 git format-patch -o patches --filename-max-length=$len -3 side &&
371 max=$(
372 for patch in patches/000[1-9]-*.patch
373 do
cbe1d9d6 374 echo "${patch#patches/}" | wc -c || exit 1
3baf58bf
JH
375 done |
376 sort -nr |
377 head -n 1
378 ) &&
379 test $max -le $len || return 1
380 done
381'
382
4aad08e0
JH
383test_expect_success 'reroll count' '
384 rm -fr patches &&
8f37854b 385 git format-patch -o patches --cover-letter --reroll-count 4 main..side >list &&
4aad08e0
JH
386 ! grep -v "^patches/v4-000[0-3]-" list &&
387 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
388 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
389'
390
7952ea66
JH
391test_expect_success 'reroll count (-v)' '
392 rm -fr patches &&
8f37854b 393 git format-patch -o patches --cover-letter -v4 main..side >list &&
7952ea66
JH
394 ! grep -v "^patches/v4-000[0-3]-" list &&
395 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
396 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
397'
398
db91988a
ZH
399test_expect_success 'reroll count (-v) with a fractional number' '
400 rm -fr patches &&
401 git format-patch -o patches --cover-letter -v4.4 main..side >list &&
402 ! grep -v "^patches/v4.4-000[0-3]-" list &&
403 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
404 ! grep -v "^Subject: \[PATCH v4.4 [0-3]/3\] " subjects
405'
406
407test_expect_success 'reroll (-v) count with a non number' '
408 rm -fr patches &&
409 git format-patch -o patches --cover-letter -v4rev2 main..side >list &&
410 ! grep -v "^patches/v4rev2-000[0-3]-" list &&
411 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
412 ! grep -v "^Subject: \[PATCH v4rev2 [0-3]/3\] " subjects
413'
414
415test_expect_success 'reroll (-v) count with a non-pathname character' '
416 rm -fr patches &&
417 git format-patch -o patches --cover-letter -v4---..././../--1/.2// main..side >list &&
418 ! grep -v "patches/v4-\.-\.-\.-1-\.2-000[0-3]-" list &&
419 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
420 ! grep -v "^Subject: \[PATCH v4---\.\.\./\./\.\./--1/\.2// [0-3]/3\] " subjects
421'
422
484cf6c3
TR
423check_threading () {
424 expect="$1" &&
425 shift &&
dd2b6b68 426 git format-patch --stdout "$@" >patch &&
484cf6c3
TR
427 # Prints everything between the Message-ID and In-Reply-To,
428 # and replaces all Message-ID-lookalikes by a sequence number
94221d22 429 perl -ne '
484cf6c3
TR
430 if (/^(message-id|references|in-reply-to)/i) {
431 $printing = 1;
432 } elsif (/^\S/) {
433 $printing = 0;
434 }
435 if ($printing) {
436 $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
437 for $k (keys %h) {s/$k/$h{$k}/};
438 print;
439 }
440 print "---\n" if /^From /i;
dd2b6b68 441 ' <patch >actual &&
484cf6c3
TR
442 test_cmp "$expect" actual
443}
444
92014b69 445cat >>expect.no-threading <<EOF
484cf6c3
TR
446---
447---
448---
449EOF
450
451test_expect_success 'no threading' '
7d812145 452 git checkout side &&
8f37854b 453 check_threading expect.no-threading main
7d812145
DB
454'
455
92014b69 456cat >expect.thread <<EOF
484cf6c3 457---
ba4324c4 458Message-ID: <0>
484cf6c3 459---
ba4324c4 460Message-ID: <1>
484cf6c3
TR
461In-Reply-To: <0>
462References: <0>
463---
ba4324c4 464Message-ID: <2>
484cf6c3
TR
465In-Reply-To: <0>
466References: <0>
467EOF
7d812145 468
484cf6c3 469test_expect_success 'thread' '
8f37854b 470 check_threading expect.thread --thread main
7d812145
DB
471'
472
f0249131
AH
473test_expect_success '--thread overrides format.thread=deep' '
474 test_config format.thread deep &&
475 check_threading expect.thread --thread main
476'
477
92014b69 478cat >expect.in-reply-to <<EOF
484cf6c3 479---
ba4324c4 480Message-ID: <0>
484cf6c3
TR
481In-Reply-To: <1>
482References: <1>
483---
ba4324c4 484Message-ID: <2>
484cf6c3
TR
485In-Reply-To: <1>
486References: <1>
487---
ba4324c4 488Message-ID: <3>
484cf6c3
TR
489In-Reply-To: <1>
490References: <1>
491EOF
a5a27c79 492
484cf6c3
TR
493test_expect_success 'thread in-reply-to' '
494 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
8f37854b 495 --thread main
a5a27c79
DB
496'
497
92014b69 498cat >expect.cover-letter <<EOF
484cf6c3 499---
ba4324c4 500Message-ID: <0>
484cf6c3 501---
ba4324c4 502Message-ID: <1>
484cf6c3
TR
503In-Reply-To: <0>
504References: <0>
505---
ba4324c4 506Message-ID: <2>
484cf6c3
TR
507In-Reply-To: <0>
508References: <0>
509---
ba4324c4 510Message-ID: <3>
484cf6c3
TR
511In-Reply-To: <0>
512References: <0>
513EOF
a5a27c79 514
484cf6c3 515test_expect_success 'thread cover-letter' '
8f37854b 516 check_threading expect.cover-letter --cover-letter --thread main
484cf6c3
TR
517'
518
92014b69 519cat >expect.cl-irt <<EOF
484cf6c3 520---
ba4324c4 521Message-ID: <0>
484cf6c3
TR
522In-Reply-To: <1>
523References: <1>
524---
ba4324c4 525Message-ID: <2>
2175c10d 526In-Reply-To: <0>
484cf6c3 527References: <1>
2175c10d 528 <0>
484cf6c3 529---
ba4324c4 530Message-ID: <3>
2175c10d 531In-Reply-To: <0>
484cf6c3 532References: <1>
2175c10d 533 <0>
484cf6c3 534---
ba4324c4 535Message-ID: <4>
2175c10d 536In-Reply-To: <0>
484cf6c3 537References: <1>
2175c10d 538 <0>
484cf6c3
TR
539EOF
540
541test_expect_success 'thread cover-letter in-reply-to' '
542 check_threading expect.cl-irt --cover-letter \
8f37854b 543 --in-reply-to="<test.message>" --thread main
a5a27c79
DB
544'
545
30984ed2
TR
546test_expect_success 'thread explicit shallow' '
547 check_threading expect.cl-irt --cover-letter \
8f37854b 548 --in-reply-to="<test.message>" --thread=shallow main
30984ed2
TR
549'
550
92014b69 551cat >expect.deep <<EOF
30984ed2 552---
ba4324c4 553Message-ID: <0>
30984ed2 554---
ba4324c4 555Message-ID: <1>
30984ed2
TR
556In-Reply-To: <0>
557References: <0>
558---
ba4324c4 559Message-ID: <2>
30984ed2
TR
560In-Reply-To: <1>
561References: <0>
562 <1>
563EOF
564
565test_expect_success 'thread deep' '
8f37854b 566 check_threading expect.deep --thread=deep main
30984ed2
TR
567'
568
92014b69 569cat >expect.deep-irt <<EOF
30984ed2 570---
ba4324c4 571Message-ID: <0>
30984ed2
TR
572In-Reply-To: <1>
573References: <1>
574---
ba4324c4 575Message-ID: <2>
30984ed2
TR
576In-Reply-To: <0>
577References: <1>
578 <0>
579---
ba4324c4 580Message-ID: <3>
30984ed2
TR
581In-Reply-To: <2>
582References: <1>
583 <0>
584 <2>
585EOF
586
587test_expect_success 'thread deep in-reply-to' '
588 check_threading expect.deep-irt --thread=deep \
8f37854b 589 --in-reply-to="<test.message>" main
30984ed2
TR
590'
591
92014b69 592cat >expect.deep-cl <<EOF
30984ed2 593---
ba4324c4 594Message-ID: <0>
30984ed2 595---
ba4324c4 596Message-ID: <1>
30984ed2
TR
597In-Reply-To: <0>
598References: <0>
599---
ba4324c4 600Message-ID: <2>
30984ed2
TR
601In-Reply-To: <1>
602References: <0>
603 <1>
604---
ba4324c4 605Message-ID: <3>
30984ed2
TR
606In-Reply-To: <2>
607References: <0>
608 <1>
609 <2>
610EOF
611
612test_expect_success 'thread deep cover-letter' '
8f37854b 613 check_threading expect.deep-cl --cover-letter --thread=deep main
30984ed2
TR
614'
615
92014b69 616cat >expect.deep-cl-irt <<EOF
30984ed2 617---
ba4324c4 618Message-ID: <0>
30984ed2
TR
619In-Reply-To: <1>
620References: <1>
621---
ba4324c4 622Message-ID: <2>
30984ed2
TR
623In-Reply-To: <0>
624References: <1>
625 <0>
626---
ba4324c4 627Message-ID: <3>
30984ed2
TR
628In-Reply-To: <2>
629References: <1>
630 <0>
631 <2>
632---
ba4324c4 633Message-ID: <4>
30984ed2
TR
634In-Reply-To: <3>
635References: <1>
636 <0>
637 <2>
638 <3>
639EOF
640
641test_expect_success 'thread deep cover-letter in-reply-to' '
642 check_threading expect.deep-cl-irt --cover-letter \
8f37854b 643 --in-reply-to="<test.message>" --thread=deep main
30984ed2
TR
644'
645
646test_expect_success 'thread via config' '
e8107155 647 test_config format.thread true &&
8f37854b 648 check_threading expect.thread main
30984ed2
TR
649'
650
651test_expect_success 'thread deep via config' '
e8107155 652 test_config format.thread deep &&
8f37854b 653 check_threading expect.deep main
30984ed2
TR
654'
655
656test_expect_success 'thread config + override' '
e8107155 657 test_config format.thread deep &&
8f37854b 658 check_threading expect.thread --thread main
30984ed2
TR
659'
660
661test_expect_success 'thread config + --no-thread' '
e8107155 662 test_config format.thread deep &&
8f37854b 663 check_threading expect.no-threading --no-thread main
30984ed2
TR
664'
665
7d812145 666test_expect_success 'excessive subject' '
7d812145
DB
667 rm -rf patches/ &&
668 git checkout side &&
bdee9cd6 669 before=$(git hash-object file) &&
670 before=$(git rev-parse --short $before) &&
08495412 671 test_write_lines 5 6 1 2 3 A 4 B C 7 8 9 10 D E F >>file &&
bdee9cd6 672 after=$(git hash-object file) &&
673 after=$(git rev-parse --short $after) &&
7d812145
DB
674 git update-index file &&
675 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." &&
8f37854b 676 git format-patch -o patches/ main..side &&
7d812145
DB
677 ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
678'
679
2fe95f49
JH
680test_expect_success 'failure to write cover-letter aborts gracefully' '
681 test_when_finished "rmdir 0000-cover-letter.patch" &&
682 mkdir 0000-cover-letter.patch &&
683 test_must_fail git format-patch --no-renames --cover-letter -1
684'
685
5d02294c 686test_expect_success 'cover-letter inherits diff options' '
5d02294c
JS
687 git mv file foo &&
688 git commit -m foo &&
5404c116 689 git format-patch --no-renames --cover-letter -1 &&
cc663d14 690 check_patch 0000-cover-letter.patch &&
9524cf29 691 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
5d02294c 692 git format-patch --cover-letter -1 -M &&
9524cf29 693 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
5d02294c 694'
859c4fbe 695
92014b69 696cat >expect <<EOF
859c4fbe
JS
697 This is an excessively long subject line for a message due to the
698 habit some projects have of not having a short, one-line subject at
699 the start of the commit message, but rather sticking a whole
700 paragraph right at the start as the only thing in the commit
701 message. It had better not become the filename for the patch.
702 foo
703
704EOF
705
706test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
859c4fbe 707 git format-patch --cover-letter -2 &&
c6ec6dad 708 sed -e "1,/A U Thor/d" -e "/^\$/q" 0000-cover-letter.patch >output &&
3af82863 709 test_cmp expect output
859c4fbe
JS
710'
711
92014b69 712cat >expect <<EOF
bdee9cd6 713index $before..$after 100644
68daa64d
JK
714--- a/file
715+++ b/file
716@@ -13,4 +13,20 @@ C
717 10
718 D
719 E
720 F
721+5
722EOF
723
724test_expect_success 'format-patch respects -U' '
68daa64d 725 git format-patch -U4 -2 &&
6dd88832
JN
726 sed -e "1,/^diff/d" -e "/^+5/q" \
727 <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
728 >output &&
68daa64d 729 test_cmp expect output
68daa64d
JK
730'
731
92014b69 732cat >expect <<EOF
1d46f2ea
JK
733
734diff --git a/file b/file
bdee9cd6 735index $before..$after 100644
1d46f2ea
JK
736--- a/file
737+++ b/file
738@@ -14,3 +14,19 @@ C
739 D
740 E
741 F
742+5
743EOF
744
745test_expect_success 'format-patch -p suppresses stat' '
1d46f2ea 746 git format-patch -p -2 &&
c6ec6dad 747 sed -e "1,/^\$/d" -e "/^+5/q" 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch >output &&
1d46f2ea 748 test_cmp expect output
1d46f2ea
JK
749'
750
9800a754
JH
751test_expect_success 'format-patch from a subdirectory (1)' '
752 filename=$(
753 rm -rf sub &&
754 mkdir -p sub/dir &&
755 cd sub/dir &&
756 git format-patch -1
757 ) &&
758 case "$filename" in
759 0*)
760 ;; # ok
761 *)
762 echo "Oops? $filename"
763 false
764 ;;
765 esac &&
766 test -f "$filename"
767'
768
769test_expect_success 'format-patch from a subdirectory (2)' '
770 filename=$(
771 rm -rf sub &&
772 mkdir -p sub/dir &&
773 cd sub/dir &&
774 git format-patch -1 -o ..
775 ) &&
776 case "$filename" in
777 ../0*)
778 ;; # ok
779 *)
780 echo "Oops? $filename"
781 false
782 ;;
783 esac &&
784 basename=$(expr "$filename" : ".*/\(.*\)") &&
785 test -f "sub/$basename"
786'
787
788test_expect_success 'format-patch from a subdirectory (3)' '
9800a754
JH
789 rm -f 0* &&
790 filename=$(
791 rm -rf sub &&
792 mkdir -p sub/dir &&
793 cd sub/dir &&
91c8b825 794 git format-patch -1 -o "$TRASH_DIRECTORY"
9800a754
JH
795 ) &&
796 basename=$(expr "$filename" : ".*/\(.*\)") &&
797 test -f "$basename"
798'
799
f044fe2d 800test_expect_success 'format-patch --in-reply-to' '
92014b69 801 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" >patch8 &&
f044fe2d
SB
802 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
803 grep "^References: <baz@foo.bar>" patch8
804'
805
806test_expect_success 'format-patch --signoff' '
212620fe
JH
807 git format-patch -1 --signoff --stdout >out &&
808 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
809'
810
811test_expect_success 'format-patch --notes --signoff' '
812 git notes --ref test add -m "test message" HEAD &&
813 git format-patch -1 --signoff --stdout --notes=test >out &&
bd1470b8 814 # Three dashes must come after S-o-b
212620fe 815 ! sed "/^Signed-off-by: /q" out | grep "test message" &&
bd1470b8
JH
816 sed "1,/^Signed-off-by: /d" out | grep "test message" &&
817 # Notes message must come after three dashes
818 ! sed "/^---$/q" out | grep "test message" &&
819 sed "1,/^---$/d" out | grep "test message"
f044fe2d
SB
820'
821
13cdf780
DL
822test_expect_success 'format-patch notes output control' '
823 git notes add -m "notes config message" HEAD &&
824 test_when_finished git notes remove HEAD &&
825
826 git format-patch -1 --stdout >out &&
827 ! grep "notes config message" out &&
828 git format-patch -1 --stdout --notes >out &&
829 grep "notes config message" out &&
830 git format-patch -1 --stdout --no-notes >out &&
831 ! grep "notes config message" out &&
832 git format-patch -1 --stdout --notes --no-notes >out &&
833 ! grep "notes config message" out &&
834 git format-patch -1 --stdout --no-notes --notes >out &&
835 grep "notes config message" out &&
836
837 test_config format.notes true &&
838 git format-patch -1 --stdout >out &&
839 grep "notes config message" out &&
840 git format-patch -1 --stdout --notes >out &&
841 grep "notes config message" out &&
842 git format-patch -1 --stdout --no-notes >out &&
843 ! grep "notes config message" out &&
844 git format-patch -1 --stdout --notes --no-notes >out &&
845 ! grep "notes config message" out &&
846 git format-patch -1 --stdout --no-notes --notes >out &&
847 grep "notes config message" out
848'
849
850test_expect_success 'format-patch with multiple notes refs' '
851 git notes --ref note1 add -m "this is note 1" HEAD &&
852 test_when_finished git notes --ref note1 remove HEAD &&
853 git notes --ref note2 add -m "this is note 2" HEAD &&
854 test_when_finished git notes --ref note2 remove HEAD &&
855
856 git format-patch -1 --stdout >out &&
857 ! grep "this is note 1" out &&
858 ! grep "this is note 2" out &&
859 git format-patch -1 --stdout --notes=note1 >out &&
860 grep "this is note 1" out &&
861 ! grep "this is note 2" out &&
862 git format-patch -1 --stdout --notes=note2 >out &&
863 ! grep "this is note 1" out &&
864 grep "this is note 2" out &&
865 git format-patch -1 --stdout --notes=note1 --notes=note2 >out &&
866 grep "this is note 1" out &&
867 grep "this is note 2" out &&
868
869 test_config format.notes note1 &&
870 git format-patch -1 --stdout >out &&
871 grep "this is note 1" out &&
872 ! grep "this is note 2" out &&
873 git format-patch -1 --stdout --no-notes >out &&
874 ! grep "this is note 1" out &&
875 ! grep "this is note 2" out &&
876 git format-patch -1 --stdout --notes=note2 >out &&
877 grep "this is note 1" out &&
878 grep "this is note 2" out &&
879 git format-patch -1 --stdout --no-notes --notes=note2 >out &&
880 ! grep "this is note 1" out &&
881 grep "this is note 2" out &&
882
883 git config --add format.notes note2 &&
884 git format-patch -1 --stdout >out &&
885 grep "this is note 1" out &&
886 grep "this is note 2" out &&
887 git format-patch -1 --stdout --no-notes >out &&
888 ! grep "this is note 1" out &&
889 ! grep "this is note 2" out
890'
891
8164c961
DL
892test_expect_success 'format-patch with multiple notes refs in config' '
893 test_when_finished "test_unconfig format.notes" &&
894
895 git notes --ref note1 add -m "this is note 1" HEAD &&
896 test_when_finished git notes --ref note1 remove HEAD &&
897 git notes --ref note2 add -m "this is note 2" HEAD &&
898 test_when_finished git notes --ref note2 remove HEAD &&
899
900 git config format.notes note1 &&
901 git format-patch -1 --stdout >out &&
902 grep "this is note 1" out &&
903 ! grep "this is note 2" out &&
904 git config format.notes note2 &&
905 git format-patch -1 --stdout >out &&
906 ! grep "this is note 1" out &&
907 grep "this is note 2" out &&
908 git config --add format.notes note1 &&
909 git format-patch -1 --stdout >out &&
910 grep "this is note 1" out &&
911 grep "this is note 2" out &&
912
913 git config --replace-all format.notes note1 &&
914 git config --add format.notes false &&
915 git format-patch -1 --stdout >out &&
916 ! grep "this is note 1" out &&
917 ! grep "this is note 2" out &&
918 git config --add format.notes note2 &&
919 git format-patch -1 --stdout >out &&
920 ! grep "this is note 1" out &&
921 grep "this is note 2" out
922'
923
92014b69
DL
924echo "fatal: --name-only does not make sense" >expect.name-only
925echo "fatal: --name-status does not make sense" >expect.name-status
926echo "fatal: --check does not make sense" >expect.check
02bc5b03 927
68b2a005 928test_expect_success 'options no longer allowed for format-patch' '
92014b69 929 test_must_fail git format-patch --name-only 2>output &&
1108cea7 930 test_cmp expect.name-only output &&
92014b69 931 test_must_fail git format-patch --name-status 2>output &&
1108cea7 932 test_cmp expect.name-status output &&
92014b69 933 test_must_fail git format-patch --check 2>output &&
1108cea7 934 test_cmp expect.check output
cb46c406 935'
02bc5b03
BG
936
937test_expect_success 'format-patch --numstat should produce a patch' '
8f37854b 938 git format-patch --numstat --stdout main..side >output &&
6bd26f58
DL
939 grep "^diff --git a/" output >diff &&
940 test_line_count = 5 diff
cb46c406 941'
02bc5b03 942
7e93d3b9 943test_expect_success 'format-patch -- <path>' '
91f8f7e4
RS
944 rm -f *.patch &&
945 git checkout -b pathspec main &&
946
947 echo file_a 1 >file_a &&
948 echo file_b 1 >file_b &&
949 git add file_a file_b &&
950 git commit -m pathspec_initial &&
951
952 echo file_a 2 >>file_a &&
953 git add file_a &&
954 git commit -m pathspec_a &&
955
956 echo file_b 2 >>file_b &&
957 git add file_b &&
958 git commit -m pathspec_b &&
959
960 echo file_a 3 >>file_a &&
961 echo file_b 3 >>file_b &&
962 git add file_a file_b &&
963 git commit -m pathspec_ab &&
964
965 cat >expect <<-\EOF &&
966 0001-pathspec_initial.patch
967 0002-pathspec_a.patch
968 0003-pathspec_ab.patch
969 EOF
970
971 git format-patch main..pathspec -- file_a >output &&
972 test_cmp expect output &&
973 ! grep file_b *.patch
7e93d3b9
FC
974'
975
657ab61e 976test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
91f8f7e4 977 git checkout side &&
657ab61e
KB
978 git format-patch --ignore-if-in-upstream HEAD
979'
980
854b5cb4
DL
981test_expect_success 'get git version' '
982 git_version=$(git --version) &&
983 git_version=${git_version##* }
984'
480871e0
JT
985
986signature() {
987 printf "%s\n%s\n\n" "-- " "${1:-$git_version}"
988}
989
990test_expect_success 'format-patch default signature' '
854b5cb4
DL
991 git format-patch --stdout -1 >patch &&
992 tail -n 3 patch >output &&
480871e0
JT
993 signature >expect &&
994 test_cmp expect output
995'
996
6622d9c7 997test_expect_success 'format-patch --signature' '
854b5cb4
DL
998 git format-patch --stdout --signature="my sig" -1 >patch &&
999 tail -n 3 patch >output &&
480871e0
JT
1000 signature "my sig" >expect &&
1001 test_cmp expect output
6622d9c7
SB
1002'
1003
1004test_expect_success 'format-patch with format.signature config' '
1005 git config format.signature "config sig" &&
1006 git format-patch --stdout -1 >output &&
1007 grep "config sig" output
1008'
1009
1010test_expect_success 'format-patch --signature overrides format.signature' '
1011 git config format.signature "config sig" &&
1012 git format-patch --stdout --signature="overrides" -1 >output &&
1013 ! grep "config sig" output &&
1014 grep "overrides" output
1015'
1016
1017test_expect_success 'format-patch --no-signature ignores format.signature' '
1018 git config format.signature "config sig" &&
1019 git format-patch --stdout --signature="my sig" --no-signature \
1020 -1 >output &&
cc663d14 1021 check_patch output &&
6622d9c7
SB
1022 ! grep "config sig" output &&
1023 ! grep "my sig" output &&
1024 ! grep "^-- \$" output
1025'
1026
1027test_expect_success 'format-patch --signature --cover-letter' '
1028 git config --unset-all format.signature &&
1029 git format-patch --stdout --signature="my sig" --cover-letter \
1030 -1 >output &&
6bd26f58
DL
1031 grep "my sig" output >sig &&
1032 test_line_count = 2 sig
6622d9c7
SB
1033'
1034
41ccfdd9 1035test_expect_success 'format.signature="" suppresses signatures' '
6622d9c7
SB
1036 git config format.signature "" &&
1037 git format-patch --stdout -1 >output &&
cc663d14 1038 check_patch output &&
6622d9c7
SB
1039 ! grep "^-- \$" output
1040'
1041
41ccfdd9 1042test_expect_success 'format-patch --no-signature suppresses signatures' '
6622d9c7
SB
1043 git config --unset-all format.signature &&
1044 git format-patch --stdout --no-signature -1 >output &&
cc663d14 1045 check_patch output &&
6622d9c7
SB
1046 ! grep "^-- \$" output
1047'
1048
41ccfdd9 1049test_expect_success 'format-patch --signature="" suppresses signatures' '
2fdb5c62 1050 git format-patch --stdout --signature="" -1 >output &&
cc663d14 1051 check_patch output &&
6622d9c7
SB
1052 ! grep "^-- \$" output
1053'
1054
7022650f
JM
1055test_expect_success 'prepare mail-signature input' '
1056 cat >mail-signature <<-\EOF
1057
1058 Test User <test.email@kernel.org>
1059 http://git.kernel.org/cgit/git/git.git
1060
1061 git.kernel.org/?p=git/git.git;a=summary
1062
1063 EOF
1064'
1065
1066test_expect_success '--signature-file=file works' '
1067 git format-patch --stdout --signature-file=mail-signature -1 >output &&
1068 check_patch output &&
c6ec6dad 1069 sed -e "1,/^-- \$/d" output >actual &&
7022650f
JM
1070 {
1071 cat mail-signature && echo
1072 } >expect &&
1073 test_cmp expect actual
1074'
1075
1076test_expect_success 'format.signaturefile works' '
1077 test_config format.signaturefile mail-signature &&
1078 git format-patch --stdout -1 >output &&
1079 check_patch output &&
c6ec6dad 1080 sed -e "1,/^-- \$/d" output >actual &&
7022650f
JM
1081 {
1082 cat mail-signature && echo
1083 } >expect &&
1084 test_cmp expect actual
1085'
1086
1087test_expect_success '--no-signature suppresses format.signaturefile ' '
1088 test_config format.signaturefile mail-signature &&
1089 git format-patch --stdout --no-signature -1 >output &&
1090 check_patch output &&
1091 ! grep "^-- \$" output
1092'
1093
1094test_expect_success '--signature-file overrides format.signaturefile' '
99094a7a 1095 cat >other-mail-signature <<-\EOF &&
7022650f
JM
1096 Use this other signature instead of mail-signature.
1097 EOF
1098 test_config format.signaturefile mail-signature &&
1099 git format-patch --stdout \
1100 --signature-file=other-mail-signature -1 >output &&
1101 check_patch output &&
c6ec6dad 1102 sed -e "1,/^-- \$/d" output >actual &&
7022650f
JM
1103 {
1104 cat other-mail-signature && echo
1105 } >expect &&
1106 test_cmp expect actual
1107'
1108
1109test_expect_success '--signature overrides format.signaturefile' '
1110 test_config format.signaturefile mail-signature &&
1111 git format-patch --stdout --signature="my sig" -1 >output &&
1112 check_patch output &&
1113 grep "my sig" output
1114'
1115
38a94bb6
TRC
1116test_expect_success TTY 'format-patch --stdout paginates' '
1117 rm -f pager_used &&
512477b1 1118 test_terminal env GIT_PAGER="wc >pager_used" git format-patch --stdout --all &&
38a94bb6
TRC
1119 test_path_is_file pager_used
1120'
1121
1122 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
1123 rm -f pager_used &&
512477b1
DT
1124 test_terminal env GIT_PAGER="wc >pager_used" git --no-pager format-patch --stdout --all &&
1125 test_terminal env GIT_PAGER="wc >pager_used" git -c "pager.format-patch=false" format-patch --stdout --all &&
38a94bb6
TRC
1126 test_path_is_missing pager_used &&
1127 test_path_is_missing .git/pager_used
1128'
1129
a1f6baa5
JK
1130test_expect_success 'format-patch handles multi-line subjects' '
1131 rm -rf patches/ &&
1132 echo content >>file &&
08495412 1133 test_write_lines one two three >msg &&
a1f6baa5
JK
1134 git add file &&
1135 git commit -F msg &&
1136 git format-patch -o patches -1 &&
1137 grep ^Subject: patches/0001-one.patch >actual &&
1138 echo "Subject: [PATCH] one two three" >expect &&
1139 test_cmp expect actual
1140'
1141
1142test_expect_success 'format-patch handles multi-line encoded subjects' '
1143 rm -rf patches/ &&
1144 echo content >>file &&
08495412 1145 test_write_lines en två tre >msg &&
a1f6baa5
JK
1146 git add file &&
1147 git commit -F msg &&
1148 git format-patch -o patches -1 &&
1149 grep ^Subject: patches/0001-en.patch >actual &&
1150 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
1151 test_cmp expect actual
1152'
1153
1154M8="foo bar "
1155M64=$M8$M8$M8$M8$M8$M8$M8$M8
1156M512=$M64$M64$M64$M64$M64$M64$M64$M64
1157cat >expect <<'EOF'
1158Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
7a76e68a
JS
1159 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1160 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1161 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1162 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1163 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1164 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
a1f6baa5 1165EOF
7a76e68a 1166test_expect_success 'format-patch wraps extremely long subject (ascii)' '
a1f6baa5
JK
1167 echo content >>file &&
1168 git add file &&
1169 git commit -m "$M512" &&
1170 git format-patch --stdout -1 >patch &&
c6ec6dad 1171 sed -n "/^Subject/p; /^ /p; /^$/q" patch >subject &&
a1f6baa5
JK
1172 test_cmp expect subject
1173'
1174
1175M8="föö bar "
1176M64=$M8$M8$M8$M8$M8$M8$M8$M8
1177M512=$M64$M64$M64$M64$M64$M64$M64$M64
1178cat >expect <<'EOF'
94f6cdf6
JS
1179Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1180 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1181 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1182 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
6cd3c053
KS
1183 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1184 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
94f6cdf6
JS
1185 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1186 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1187 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
6cd3c053
KS
1188 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1189 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
94f6cdf6
JS
1190 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1191 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1192 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
6cd3c053
KS
1193 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1194 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1195 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1196 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1197 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1198 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1199 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1200 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1201 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1202 =?UTF-8?q?bar?=
a1f6baa5 1203EOF
94f6cdf6 1204test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
a1f6baa5
JK
1205 rm -rf patches/ &&
1206 echo content >>file &&
1207 git add file &&
1208 git commit -m "$M512" &&
1209 git format-patch --stdout -1 >patch &&
c6ec6dad 1210 sed -n "/^Subject/p; /^ /p; /^$/q" patch >subject &&
a1f6baa5
JK
1211 test_cmp expect subject
1212'
1213
4d03c18a
JK
1214check_author() {
1215 echo content >>file &&
1216 git add file &&
1217 GIT_AUTHOR_NAME=$1 git commit -m author-check &&
1218 git format-patch --stdout -1 >patch &&
c6ec6dad 1219 sed -n "/^From: /p; /^ /p; /^$/q" patch >actual &&
4d03c18a
JK
1220 test_cmp expect actual
1221}
1222
1223cat >expect <<'EOF'
1224From: "Foo B. Bar" <author@example.com>
1225EOF
0fcec2ce 1226test_expect_success 'format-patch quotes dot in from-headers' '
4d03c18a
JK
1227 check_author "Foo B. Bar"
1228'
1229
1230cat >expect <<'EOF'
1231From: "Foo \"The Baz\" Bar" <author@example.com>
1232EOF
0fcec2ce 1233test_expect_success 'format-patch quotes double-quote in from-headers' '
4d03c18a
JK
1234 check_author "Foo \"The Baz\" Bar"
1235'
1236
1237cat >expect <<'EOF'
0fcec2ce 1238From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
4d03c18a 1239EOF
0fcec2ce
JS
1240test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
1241 check_author "Föo Bar"
1242'
1243
1244cat >expect <<'EOF'
1245From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
1246EOF
41dd00ba 1247test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
4d03c18a
JK
1248 check_author "Föo B. Bar"
1249'
1250
7a76e68a
JS
1251cat >expect <<EOF
1252From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
1253 <author@example.com>
1254EOF
1255test_expect_success 'format-patch wraps moderately long from-header (ascii)' '
1256 check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
1257'
1258
1259cat >expect <<'EOF'
1260From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1261 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1262 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
1263EOF
1264test_expect_success 'format-patch wraps extremely long from-header (ascii)' '
1265 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"
1266'
1267
1268cat >expect <<'EOF'
1269From: "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1270 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1271 Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
1272EOF
1273test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
1274 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"
1275'
1276
4d03c18a 1277cat >expect <<'EOF'
94f6cdf6
JS
1278From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
1279 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
1280 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
1281 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
1282 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
1283EOF
1284test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
1285 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"
1286'
1287
19d097e3
EB
1288cat >expect <<'EOF'
1289From: Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1290 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1291 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
1292EOF
1293test_expect_success 'format-patch wraps extremely long from-header (non-ASCII without Q-encoding)' '
1294 echo content >>file &&
1295 git add file &&
1296 GIT_AUTHOR_NAME="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" \
1297 git commit -m author-check &&
1298 git format-patch --no-encode-email-headers --stdout -1 >patch &&
1299 sed -n "/^From: /p; /^ /p; /^$/q" patch >actual &&
1300 test_cmp expect actual
1301'
1302
1303cat >expect <<'EOF'
1304Subject: [PATCH] Foö
1305EOF
1306test_expect_success 'subject lines are unencoded with --no-encode-email-headers' '
1307 echo content >>file &&
1308 git add file &&
1309 git commit -m "Foö" &&
1310 git format-patch --no-encode-email-headers -1 --stdout >patch &&
1311 grep ^Subject: patch >actual &&
1312 test_cmp expect actual
1313'
1314
1315cat >expect <<'EOF'
1316Subject: [PATCH] Foö
1317EOF
1318test_expect_success 'subject lines are unencoded with format.encodeEmailHeaders=false' '
1319 echo content >>file &&
1320 git add file &&
1321 git commit -m "Foö" &&
1322 git config format.encodeEmailHeaders false &&
1323 git format-patch -1 --stdout >patch &&
1324 grep ^Subject: patch >actual &&
1325 test_cmp expect actual
1326'
1327
1328cat >expect <<'EOF'
1329Subject: [PATCH] =?UTF-8?q?Fo=C3=B6?=
1330EOF
1331test_expect_success '--encode-email-headers overrides format.encodeEmailHeaders' '
1332 echo content >>file &&
1333 git add file &&
1334 git commit -m "Foö" &&
1335 git config format.encodeEmailHeaders false &&
1336 git format-patch --encode-email-headers -1 --stdout >patch &&
1337 grep ^Subject: patch >actual &&
1338 test_cmp expect actual
1339'
1340
94f6cdf6 1341cat >expect <<'EOF'
4d03c18a
JK
1342Subject: header with . in it
1343EOF
1344test_expect_success 'subject lines do not have 822 atom-quoting' '
1345 echo content >>file &&
1346 git add file &&
1347 git commit -m "header with . in it" &&
1348 git format-patch -k -1 --stdout >patch &&
1349 grep ^Subject: patch >actual &&
1350 test_cmp expect actual
1351'
1352
e7af8e49
JK
1353cat >expect <<'EOF'
1354Subject: [PREFIX 1/1] header with . in it
1355EOF
1356test_expect_success 'subject prefixes have space prepended' '
1357 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
1358 grep ^Subject: patch >actual &&
1359 test_cmp expect actual
1360'
1361
1362cat >expect <<'EOF'
1363Subject: [1/1] header with . in it
1364EOF
1365test_expect_success 'empty subject prefix does not have extra space' '
1366 git format-patch -n -1 --stdout --subject-prefix= >patch &&
1367 grep ^Subject: patch >actual &&
1368 test_cmp expect actual
1369'
1370
68e83a5b
JT
1371test_expect_success '--rfc' '
1372 cat >expect <<-\EOF &&
1373 Subject: [RFC PATCH 1/1] header with . in it
1374 EOF
1375 git format-patch -n -1 --stdout --rfc >patch &&
1376 grep ^Subject: patch >actual &&
1377 test_cmp expect actual
1378'
1379
a9080475
JK
1380test_expect_success '--from=ident notices bogus ident' '
1381 test_must_fail git format-patch -1 --stdout --from=foo >patch
1382'
1383
1384test_expect_success '--from=ident replaces author' '
1385 git format-patch -1 --stdout --from="Me <me@example.com>" >patch &&
1386 cat >expect <<-\EOF &&
1387 From: Me <me@example.com>
1388
1389 From: A U Thor <author@example.com>
1390
1391 EOF
c6ec6dad 1392 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
a9080475
JK
1393 test_cmp expect patch.head
1394'
1395
1396test_expect_success '--from uses committer ident' '
1397 git format-patch -1 --stdout --from >patch &&
1398 cat >expect <<-\EOF &&
1399 From: C O Mitter <committer@example.com>
1400
1401 From: A U Thor <author@example.com>
1402
1403 EOF
c6ec6dad 1404 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
a9080475
JK
1405 test_cmp expect patch.head
1406'
1407
662cc30c
JK
1408test_expect_success '--from omits redundant in-body header' '
1409 git format-patch -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1410 cat >expect <<-\EOF &&
1411 From: A U Thor <author@example.com>
1412
1413 EOF
c6ec6dad 1414 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
662cc30c
JK
1415 test_cmp expect patch.head
1416'
1417
34bc1b10
JH
1418test_expect_success 'with --force-in-body-from, redundant in-body from is kept' '
1419 git format-patch --force-in-body-from \
1420 -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1421 cat >expect <<-\EOF &&
1422 From: A U Thor <author@example.com>
1423
1424 From: A U Thor <author@example.com>
1425
1426 EOF
1427 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1428 test_cmp expect patch.head
1429'
1430
d5fc07df
JH
1431test_expect_success 'format.forceInBodyFrom, equivalent to --force-in-body-from' '
1432 git -c format.forceInBodyFrom=yes format-patch \
1433 -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1434 cat >expect <<-\EOF &&
1435 From: A U Thor <author@example.com>
1436
1437 From: A U Thor <author@example.com>
1438
1439 EOF
1440 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1441 test_cmp expect patch.head
1442'
1443
1444test_expect_success 'format.forceInBodyFrom, equivalent to --force-in-body-from' '
1445 git -c format.forceInBodyFrom=yes format-patch --no-force-in-body-from \
1446 -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1447 cat >expect <<-\EOF &&
1448 From: A U Thor <author@example.com>
1449
1450 EOF
1451 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1452 test_cmp expect patch.head
1453'
1454
a9080475 1455test_expect_success 'in-body headers trigger content encoding' '
d2554c72 1456 test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
a9080475
JK
1457 test_when_finished "git reset --hard HEAD^" &&
1458 git format-patch -1 --stdout --from >patch &&
1459 cat >expect <<-\EOF &&
1460 From: C O Mitter <committer@example.com>
1461 Content-Type: text/plain; charset=UTF-8
1462
1463 From: éxötìc <author@example.com>
1464
1465 EOF
c6ec6dad 1466 sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" patch >patch.head &&
a9080475
JK
1467 test_cmp expect patch.head
1468'
1469
79133a66
NTND
1470append_signoff()
1471{
1472 C=$(git commit-tree HEAD^^{tree} -p HEAD) &&
1473 git format-patch --stdout --signoff $C^..$C >append_signoff.patch &&
1474 sed -n -e "1,/^---$/p" append_signoff.patch |
81580fa0 1475 grep -E -n "^Subject|Sign|^$"
79133a66
NTND
1476}
1477
1478test_expect_success 'signoff: commit with no body' '
1479 append_signoff </dev/null >actual &&
460609cb
DL
1480 cat <<-\EOF | sed "s/EOL$//" >expect &&
1481 4:Subject: [PATCH] EOL
1482 8:
1483 9:Signed-off-by: C O Mitter <committer@example.com>
1484 EOF
b562a54c 1485 test_cmp expect actual
79133a66
NTND
1486'
1487
1488test_expect_success 'signoff: commit with only subject' '
1489 echo subject | append_signoff >actual &&
460609cb
DL
1490 cat >expect <<-\EOF &&
1491 4:Subject: [PATCH] subject
1492 8:
1493 9:Signed-off-by: C O Mitter <committer@example.com>
1494 EOF
b562a54c 1495 test_cmp expect actual
79133a66
NTND
1496'
1497
1498test_expect_success 'signoff: commit with only subject that does not end with NL' '
1499 printf subject | append_signoff >actual &&
460609cb
DL
1500 cat >expect <<-\EOF &&
1501 4:Subject: [PATCH] subject
1502 8:
1503 9:Signed-off-by: C O Mitter <committer@example.com>
1504 EOF
b562a54c 1505 test_cmp expect actual
79133a66
NTND
1506'
1507
1508test_expect_success 'signoff: no existing signoffs' '
460609cb
DL
1509 append_signoff <<-\EOF >actual &&
1510 subject
79133a66 1511
460609cb
DL
1512 body
1513 EOF
1514 cat >expect <<-\EOF &&
1515 4:Subject: [PATCH] subject
1516 8:
1517 10:
1518 11:Signed-off-by: C O Mitter <committer@example.com>
1519 EOF
b562a54c 1520 test_cmp expect actual
79133a66
NTND
1521'
1522
1523test_expect_success 'signoff: no existing signoffs and no trailing NL' '
1524 printf "subject\n\nbody" | append_signoff >actual &&
460609cb
DL
1525 cat >expect <<-\EOF &&
1526 4:Subject: [PATCH] subject
1527 8:
1528 10:
1529 11:Signed-off-by: C O Mitter <committer@example.com>
1530 EOF
b562a54c 1531 test_cmp expect actual
79133a66
NTND
1532'
1533
1534test_expect_success 'signoff: some random signoff' '
460609cb
DL
1535 append_signoff <<-\EOF >actual &&
1536 subject
79133a66 1537
460609cb 1538 body
79133a66 1539
460609cb
DL
1540 Signed-off-by: my@house
1541 EOF
1542 cat >expect <<-\EOF &&
1543 4:Subject: [PATCH] subject
1544 8:
1545 10:
1546 11:Signed-off-by: my@house
1547 12:Signed-off-by: C O Mitter <committer@example.com>
1548 EOF
b562a54c 1549 test_cmp expect actual
79133a66
NTND
1550'
1551
959a2623 1552test_expect_success 'signoff: misc conforming footer elements' '
460609cb
DL
1553 append_signoff <<-\EOF >actual &&
1554 subject
959a2623 1555
460609cb 1556 body
959a2623 1557
460609cb
DL
1558 Signed-off-by: my@house
1559 (cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1560 Tested-by: Some One <someone@example.com>
1561 Bug: 1234
1562 EOF
1563 cat >expect <<-\EOF &&
1564 4:Subject: [PATCH] subject
1565 8:
1566 10:
1567 11:Signed-off-by: my@house
1568 15:Signed-off-by: C O Mitter <committer@example.com>
1569 EOF
b562a54c 1570 test_cmp expect actual
959a2623
BC
1571'
1572
1573test_expect_success 'signoff: some random signoff-alike' '
460609cb
DL
1574 append_signoff <<-\EOF >actual &&
1575 subject
79133a66 1576
460609cb
DL
1577 body
1578 Fooled-by-me: my@house
1579 EOF
1580 cat >expect <<-\EOF &&
1581 4:Subject: [PATCH] subject
1582 8:
1583 11:
1584 12:Signed-off-by: C O Mitter <committer@example.com>
1585 EOF
b562a54c 1586 test_cmp expect actual
79133a66
NTND
1587'
1588
959a2623 1589test_expect_success 'signoff: not really a signoff' '
460609cb
DL
1590 append_signoff <<-\EOF >actual &&
1591 subject
79133a66 1592
460609cb
DL
1593 I want to mention about Signed-off-by: here.
1594 EOF
1595 cat >expect <<-\EOF &&
1596 4:Subject: [PATCH] subject
1597 8:
1598 9:I want to mention about Signed-off-by: here.
1599 10:
1600 11:Signed-off-by: C O Mitter <committer@example.com>
1601 EOF
b562a54c 1602 test_cmp expect actual
79133a66
NTND
1603'
1604
959a2623 1605test_expect_success 'signoff: not really a signoff (2)' '
460609cb
DL
1606 append_signoff <<-\EOF >actual &&
1607 subject
79133a66 1608
460609cb
DL
1609 My unfortunate
1610 Signed-off-by: example happens to be wrapped here.
1611 EOF
1612 cat >expect <<-\EOF &&
1613 4:Subject: [PATCH] subject
1614 8:
1615 10:Signed-off-by: example happens to be wrapped here.
1616 11:Signed-off-by: C O Mitter <committer@example.com>
1617 EOF
b562a54c 1618 test_cmp expect actual
79133a66
NTND
1619'
1620
959a2623 1621test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
460609cb
DL
1622 append_signoff <<-\EOF >actual &&
1623 subject
79133a66 1624
460609cb
DL
1625 Signed-off-by: my@house
1626 Signed-off-by: your@house
79133a66 1627
460609cb
DL
1628 A lot of houses.
1629 EOF
1630 cat >expect <<-\EOF &&
1631 4:Subject: [PATCH] subject
1632 8:
1633 9:Signed-off-by: my@house
1634 10:Signed-off-by: your@house
1635 11:
1636 13:
1637 14:Signed-off-by: C O Mitter <committer@example.com>
1638 EOF
b562a54c 1639 test_cmp expect actual
79133a66
NTND
1640'
1641
1642test_expect_success 'signoff: the same signoff at the end' '
460609cb
DL
1643 append_signoff <<-\EOF >actual &&
1644 subject
79133a66 1645
460609cb 1646 body
79133a66 1647
460609cb
DL
1648 Signed-off-by: C O Mitter <committer@example.com>
1649 EOF
1650 cat >expect <<-\EOF &&
1651 4:Subject: [PATCH] subject
1652 8:
1653 10:
1654 11:Signed-off-by: C O Mitter <committer@example.com>
1655 EOF
b562a54c 1656 test_cmp expect actual
79133a66
NTND
1657'
1658
1659test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
1660 printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
1661 append_signoff >actual &&
460609cb
DL
1662 cat >expect <<-\EOF &&
1663 4:Subject: [PATCH] subject
1664 8:
1665 9:Signed-off-by: C O Mitter <committer@example.com>
1666 EOF
b562a54c 1667 test_cmp expect actual
79133a66
NTND
1668'
1669
1670test_expect_success 'signoff: the same signoff NOT at the end' '
460609cb
DL
1671 append_signoff <<-\EOF >actual &&
1672 subject
79133a66 1673
460609cb 1674 body
79133a66 1675
460609cb
DL
1676 Signed-off-by: C O Mitter <committer@example.com>
1677 Signed-off-by: my@house
1678 EOF
1679 cat >expect <<-\EOF &&
1680 4:Subject: [PATCH] subject
1681 8:
1682 10:
1683 11:Signed-off-by: C O Mitter <committer@example.com>
1684 12:Signed-off-by: my@house
1685 EOF
b562a54c 1686 test_cmp expect actual
79133a66
NTND
1687'
1688
967dfd4d 1689test_expect_success 'signoff: tolerate garbage in conforming footer' '
460609cb
DL
1690 append_signoff <<-\EOF >actual &&
1691 subject
79133a66 1692
460609cb 1693 body
79133a66 1694
460609cb
DL
1695 Tested-by: my@house
1696 Some Trash
1697 Signed-off-by: C O Mitter <committer@example.com>
1698 EOF
1699 cat >expect <<-\EOF &&
1700 4:Subject: [PATCH] subject
1701 8:
1702 10:
1703 13:Signed-off-by: C O Mitter <committer@example.com>
1704 EOF
b562a54c 1705 test_cmp expect actual
967dfd4d
JT
1706'
1707
1708test_expect_success 'signoff: respect trailer config' '
460609cb
DL
1709 append_signoff <<-\EOF >actual &&
1710 subject
967dfd4d 1711
460609cb
DL
1712 Myfooter: x
1713 Some Trash
1714 EOF
1715 cat >expect <<-\EOF &&
1716 4:Subject: [PATCH] subject
1717 8:
1718 11:
1719 12:Signed-off-by: C O Mitter <committer@example.com>
1720 EOF
b562a54c 1721 test_cmp expect actual &&
967dfd4d
JT
1722
1723 test_config trailer.Myfooter.ifexists add &&
460609cb
DL
1724 append_signoff <<-\EOF >actual &&
1725 subject
967dfd4d 1726
460609cb
DL
1727 Myfooter: x
1728 Some Trash
1729 EOF
1730 cat >expect <<-\EOF &&
1731 4:Subject: [PATCH] subject
1732 8:
1733 11:Signed-off-by: C O Mitter <committer@example.com>
1734 EOF
b562a54c 1735 test_cmp expect actual
79133a66
NTND
1736'
1737
1738test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
460609cb
DL
1739 append_signoff <<-\EOF >actual &&
1740 subject
79133a66 1741
460609cb 1742 body
79133a66 1743
460609cb
DL
1744 Reviewed-id: Noone
1745 Tested-by: my@house
1746 Change-id: Ideadbeef
1747 Signed-off-by: C O Mitter <committer@example.com>
1748 Bug: 1234
1749 EOF
1750 cat >expect <<-\EOF &&
1751 4:Subject: [PATCH] subject
1752 8:
1753 10:
1754 14:Signed-off-by: C O Mitter <committer@example.com>
1755 EOF
b562a54c 1756 test_cmp expect actual
79133a66
NTND
1757'
1758
787570c7
PYH
1759test_expect_success 'format patch ignores color.ui' '
1760 test_unconfig color.ui &&
1761 git format-patch --stdout -1 >expect &&
1762 test_config color.ui always &&
1763 git format-patch --stdout -1 >actual &&
1764 test_cmp expect actual
1765'
1766
c28ded83
LA
1767test_expect_success 'format patch respects diff.relative' '
1768 rm -rf subdir &&
1769 mkdir subdir &&
1770 echo other content >subdir/file2 &&
1771 git add subdir/file2 &&
1772 git commit -F msg &&
1773 test_unconfig diff.relative &&
1774 git format-patch --relative=subdir --stdout -1 >expect &&
1775 test_config diff.relative true &&
1776 git -C subdir format-patch --stdout -1 >actual &&
1777 test_cmp expect actual
1778'
1779
bf8e65b3
DL
1780test_expect_success 'cover letter with invalid --cover-from-description and config' '
1781 test_config branch.rebuild-1.description "config subject
1782
1783body" &&
8f37854b 1784 test_must_fail git format-patch --cover-letter --cover-from-description garbage main &&
bf8e65b3 1785 test_config format.coverFromDescription garbage &&
8f37854b 1786 test_must_fail git format-patch --cover-letter main
bf8e65b3
DL
1787'
1788
1789test_expect_success 'cover letter with format.coverFromDescription = default' '
1790 test_config branch.rebuild-1.description "config subject
1791
1792body" &&
1793 test_config format.coverFromDescription default &&
1794 git checkout rebuild-1 &&
8f37854b 1795 git format-patch --stdout --cover-letter main >actual &&
bf8e65b3
DL
1796 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1797 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1798 grep "^config subject$" actual &&
1799 grep "^body$" actual
1800'
1801
1802test_expect_success 'cover letter with --cover-from-description default' '
1803 test_config branch.rebuild-1.description "config subject
1804
1805body" &&
1806 git checkout rebuild-1 &&
8f37854b 1807 git format-patch --stdout --cover-letter --cover-from-description default main >actual &&
bf8e65b3
DL
1808 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1809 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1810 grep "^config subject$" actual &&
1811 grep "^body$" actual
1812'
1813
1814test_expect_success 'cover letter with format.coverFromDescription = none' '
1815 test_config branch.rebuild-1.description "config subject
1816
1817body" &&
1818 test_config format.coverFromDescription none &&
1819 git checkout rebuild-1 &&
8f37854b 1820 git format-patch --stdout --cover-letter main >actual &&
bf8e65b3
DL
1821 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1822 grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1823 ! grep "^config subject$" actual &&
1824 ! grep "^body$" actual
1825'
1826
1827test_expect_success 'cover letter with --cover-from-description none' '
1828 test_config branch.rebuild-1.description "config subject
1829
1830body" &&
1831 git checkout rebuild-1 &&
8f37854b 1832 git format-patch --stdout --cover-letter --cover-from-description none main >actual &&
bf8e65b3
DL
1833 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1834 grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1835 ! grep "^config subject$" actual &&
1836 ! grep "^body$" actual
1837'
1838
1839test_expect_success 'cover letter with format.coverFromDescription = message' '
1840 test_config branch.rebuild-1.description "config subject
1841
1842body" &&
1843 test_config format.coverFromDescription message &&
1844 git checkout rebuild-1 &&
8f37854b 1845 git format-patch --stdout --cover-letter main >actual &&
bf8e65b3
DL
1846 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1847 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1848 grep "^config subject$" actual &&
1849 grep "^body$" actual
1850'
1851
1852test_expect_success 'cover letter with --cover-from-description message' '
1853 test_config branch.rebuild-1.description "config subject
1854
1855body" &&
1856 git checkout rebuild-1 &&
8f37854b 1857 git format-patch --stdout --cover-letter --cover-from-description message main >actual &&
bf8e65b3
DL
1858 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1859 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1860 grep "^config subject$" actual &&
1861 grep "^body$" actual
1862'
1863
1864test_expect_success 'cover letter with format.coverFromDescription = subject' '
1865 test_config branch.rebuild-1.description "config subject
1866
1867body" &&
1868 test_config format.coverFromDescription subject &&
1869 git checkout rebuild-1 &&
8f37854b 1870 git format-patch --stdout --cover-letter main >actual &&
bf8e65b3
DL
1871 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1872 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1873 ! grep "^config subject$" actual &&
1874 grep "^body$" actual
1875'
1876
1877test_expect_success 'cover letter with --cover-from-description subject' '
1878 test_config branch.rebuild-1.description "config subject
1879
1880body" &&
1881 git checkout rebuild-1 &&
8f37854b 1882 git format-patch --stdout --cover-letter --cover-from-description subject main >actual &&
bf8e65b3
DL
1883 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1884 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1885 ! grep "^config subject$" actual &&
1886 grep "^body$" actual
1887'
1888
1889test_expect_success 'cover letter with format.coverFromDescription = auto (short subject line)' '
1890 test_config branch.rebuild-1.description "config subject
1891
1892body" &&
1893 test_config format.coverFromDescription auto &&
1894 git checkout rebuild-1 &&
8f37854b 1895 git format-patch --stdout --cover-letter main >actual &&
bf8e65b3
DL
1896 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1897 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1898 ! grep "^config subject$" actual &&
1899 grep "^body$" actual
1900'
1901
1902test_expect_success 'cover letter with --cover-from-description auto (short subject line)' '
1903 test_config branch.rebuild-1.description "config subject
1904
1905body" &&
1906 git checkout rebuild-1 &&
8f37854b 1907 git format-patch --stdout --cover-letter --cover-from-description auto main >actual &&
bf8e65b3
DL
1908 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1909 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1910 ! grep "^config subject$" actual &&
1911 grep "^body$" actual
1912'
1913
1914test_expect_success 'cover letter with format.coverFromDescription = auto (long subject line)' '
1915 test_config branch.rebuild-1.description "this is a really long first line and it is over 100 characters long which is the threshold for long subjects
1916
1917body" &&
1918 test_config format.coverFromDescription auto &&
1919 git checkout rebuild-1 &&
8f37854b 1920 git format-patch --stdout --cover-letter main >actual &&
bf8e65b3
DL
1921 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1922 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1923 grep "^this is a really long first line and it is over 100 characters long which is the threshold for long subjects$" actual &&
1924 grep "^body$" actual
1925'
1926
1927test_expect_success 'cover letter with --cover-from-description auto (long subject line)' '
1928 test_config branch.rebuild-1.description "this is a really long first line and it is over 100 characters long which is the threshold for long subjects
1929
1930body" &&
1931 git checkout rebuild-1 &&
8f37854b 1932 git format-patch --stdout --cover-letter --cover-from-description auto main >actual &&
bf8e65b3
DL
1933 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1934 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1935 grep "^this is a really long first line and it is over 100 characters long which is the threshold for long subjects$" actual &&
1936 grep "^body$" actual
1937'
1938
1939test_expect_success 'cover letter with command-line --cover-from-description overrides config' '
1940 test_config branch.rebuild-1.description "config subject
1941
1942body" &&
1943 test_config format.coverFromDescription none &&
1944 git checkout rebuild-1 &&
8f37854b 1945 git format-patch --stdout --cover-letter --cover-from-description subject main >actual &&
bf8e65b3
DL
1946 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1947 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1948 ! grep "^config subject$" actual &&
1949 grep "^body$" actual
1950'
1951
e216cc48
NTND
1952test_expect_success 'cover letter using branch description (1)' '
1953 git checkout rebuild-1 &&
1954 test_config branch.rebuild-1.description hello &&
8f37854b 1955 git format-patch --stdout --cover-letter main >actual &&
f2e2fa8f 1956 grep hello actual
e216cc48
NTND
1957'
1958
1959test_expect_success 'cover letter using branch description (2)' '
1960 git checkout rebuild-1 &&
1961 test_config branch.rebuild-1.description hello &&
1962 git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
f2e2fa8f 1963 grep hello actual
e216cc48
NTND
1964'
1965
1966test_expect_success 'cover letter using branch description (3)' '
1967 git checkout rebuild-1 &&
1968 test_config branch.rebuild-1.description hello &&
8f37854b 1969 git format-patch --stdout --cover-letter ^main rebuild-1 >actual &&
f2e2fa8f 1970 grep hello actual
e216cc48
NTND
1971'
1972
20b630aa
NTND
1973test_expect_success 'cover letter using branch description (4)' '
1974 git checkout rebuild-1 &&
1975 test_config branch.rebuild-1.description hello &&
8f37854b 1976 git format-patch --stdout --cover-letter main.. >actual &&
f2e2fa8f 1977 grep hello actual
20b630aa
NTND
1978'
1979
1980test_expect_success 'cover letter using branch description (5)' '
1981 git checkout rebuild-1 &&
1982 test_config branch.rebuild-1.description hello &&
1983 git format-patch --stdout --cover-letter -2 HEAD >actual &&
f2e2fa8f 1984 grep hello actual
20b630aa
NTND
1985'
1986
5ee29aef
NTND
1987test_expect_success 'cover letter using branch description (6)' '
1988 git checkout rebuild-1 &&
1989 test_config branch.rebuild-1.description hello &&
1990 git format-patch --stdout --cover-letter -2 >actual &&
f2e2fa8f 1991 grep hello actual
5ee29aef
NTND
1992'
1993
80d35ca0
FC
1994test_expect_success 'cover letter with nothing' '
1995 git format-patch --stdout --cover-letter >actual &&
1996 test_line_count = 0 actual
1997'
1998
2a4c2607
FC
1999test_expect_success 'cover letter auto' '
2000 mkdir -p tmp &&
2001 test_when_finished "rm -rf tmp;
2002 git config --unset format.coverletter" &&
2003
2004 git config format.coverletter auto &&
2005 git format-patch -o tmp -1 >list &&
2006 test_line_count = 1 list &&
2007 git format-patch -o tmp -2 >list &&
2008 test_line_count = 3 list
2009'
2010
2011test_expect_success 'cover letter auto user override' '
2012 mkdir -p tmp &&
2013 test_when_finished "rm -rf tmp;
2014 git config --unset format.coverletter" &&
2015
2016 git config format.coverletter auto &&
2017 git format-patch -o tmp --cover-letter -1 >list &&
2018 test_line_count = 2 list &&
2019 git format-patch -o tmp --cover-letter -2 >list &&
2020 test_line_count = 3 list &&
2021 git format-patch -o tmp --no-cover-letter -1 >list &&
2022 test_line_count = 1 list &&
2023 git format-patch -o tmp --no-cover-letter -2 >list &&
2024 test_line_count = 2 list
2025'
2026
3a30aa17 2027test_expect_success 'format-patch --zero-commit' '
2028 git format-patch --zero-commit --stdout v2..v1 >patch2 &&
2029 grep "^From " patch2 | sort | uniq >actual &&
8125a58b 2030 echo "From $ZERO_OID Mon Sep 17 00:00:00 2001" >expect &&
3a30aa17 2031 test_cmp expect actual
2032'
2033
06dfc9eb 2034test_expect_success 'From line has expected format' '
2035 git format-patch --stdout v2..v1 >patch2 &&
2036 grep "^From " patch2 >from &&
2ece6ad2 2037 grep "^From $OID_REGEX Mon Sep 17 00:00:00 2001$" patch2 >filtered &&
06dfc9eb 2038 test_cmp from filtered
2039'
2040
edefc318
BW
2041test_expect_success 'format-patch -o with no leading directories' '
2042 rm -fr patches &&
8f37854b
JS
2043 git format-patch -o patches main..side &&
2044 count=$(git rev-list --count main..side) &&
edefc318
BW
2045 ls patches >list &&
2046 test_line_count = $count list
2047'
2048
2049test_expect_success 'format-patch -o with leading existing directories' '
19c29e53
BW
2050 rm -rf existing-dir &&
2051 mkdir existing-dir &&
8f37854b
JS
2052 git format-patch -o existing-dir/patches main..side &&
2053 count=$(git rev-list --count main..side) &&
19c29e53 2054 ls existing-dir/patches >list &&
edefc318
BW
2055 test_line_count = $count list
2056'
2057
2058test_expect_success 'format-patch -o with leading non-existing directories' '
19c29e53 2059 rm -rf non-existing-dir &&
8f37854b
JS
2060 git format-patch -o non-existing-dir/patches main..side &&
2061 count=$(git rev-list --count main..side) &&
19c29e53
BW
2062 test_path_is_dir non-existing-dir &&
2063 ls non-existing-dir/patches >list &&
edefc318
BW
2064 test_line_count = $count list
2065'
2066
bc6bf2d7
AK
2067test_expect_success 'format-patch format.outputDirectory option' '
2068 test_config format.outputDirectory patches &&
2069 rm -fr patches &&
8f37854b
JS
2070 git format-patch main..side &&
2071 count=$(git rev-list --count main..side) &&
756fb0de
DL
2072 ls patches >list &&
2073 test_line_count = $count list
bc6bf2d7
AK
2074'
2075
2076test_expect_success 'format-patch -o overrides format.outputDirectory' '
2077 test_config format.outputDirectory patches &&
2078 rm -fr patches patchset &&
8f37854b 2079 git format-patch main..side -o patchset &&
bc6bf2d7
AK
2080 test_path_is_missing patches &&
2081 test_path_is_dir patchset
2082'
2083
4c6f781f 2084test_expect_success 'format-patch forbids multiple outputs' '
dc1672dd 2085 rm -fr outfile outdir &&
4c6f781f 2086 test_must_fail \
dc1672dd
JK
2087 git format-patch --stdout --output-directory=outdir &&
2088 test_must_fail \
2089 git format-patch --stdout --output=outfile &&
2090 test_must_fail \
2091 git format-patch --output=outfile --output-directory=outdir
4c6f781f
JK
2092'
2093
2094test_expect_success 'configured outdir does not conflict with output options' '
dc1672dd 2095 rm -fr outfile outdir &&
4c6f781f
JK
2096 test_config format.outputDirectory outdir &&
2097 git format-patch --stdout &&
dc1672dd
JK
2098 test_path_is_missing outdir &&
2099 git format-patch --output=outfile &&
4c6f781f
JK
2100 test_path_is_missing outdir
2101'
2102
dc1672dd
JK
2103test_expect_success 'format-patch --output' '
2104 rm -fr outfile &&
2105 git format-patch -3 --stdout HEAD >expect &&
2106 git format-patch -3 --output=outfile HEAD &&
2107 test_cmp expect outfile
2108'
2109
2110test_expect_success 'format-patch --cover-letter --output' '
2111 rm -fr outfile &&
2112 git format-patch --cover-letter -3 --stdout HEAD >expect &&
2113 git format-patch --cover-letter -3 --output=outfile HEAD &&
2114 test_cmp expect outfile
2115'
2116
fa2ab86d 2117test_expect_success 'format-patch --base' '
6f93d261 2118 git checkout patchid &&
854b5cb4
DL
2119
2120 git format-patch --stdout --base=HEAD~3 -1 >patch &&
2121 tail -n 7 patch >actual1 &&
2122
2123 git format-patch --stdout --base=HEAD~3 HEAD~.. >patch &&
2124 tail -n 7 patch >actual2 &&
2125
b562a54c 2126 echo >expect &&
854b5cb4
DL
2127 git rev-parse HEAD~3 >commit-id-base &&
2128 echo "base-commit: $(cat commit-id-base)" >>expect &&
2129
2130 git show --patch HEAD~2 >patch &&
2131 git patch-id --stable <patch >patch.id.raw &&
2132 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>expect &&
2133
2134 git show --patch HEAD~1 >patch &&
2135 git patch-id --stable <patch >patch.id.raw &&
2136 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>expect &&
2137
92014b69 2138 signature >>expect &&
b562a54c
DL
2139 test_cmp expect actual1 &&
2140 test_cmp expect actual2 &&
854b5cb4 2141
6f93d261 2142 echo >fail &&
854b5cb4
DL
2143 echo "base-commit: $(cat commit-id-base)" >>fail &&
2144
2145 git show --patch HEAD~2 >patch &&
2146 git patch-id --unstable <patch >patch.id.raw &&
2147 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>fail &&
2148
2149 git show --patch HEAD~1 >patch &&
2150 git patch-id --unstable <patch >patch.id.raw &&
2151 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>fail &&
2152
92014b69 2153 signature >>fail &&
6f93d261
SB
2154 ! test_cmp fail actual1 &&
2155 ! test_cmp fail actual2
fa2ab86d
XY
2156'
2157
2158test_expect_success 'format-patch --base errors out when base commit is in revision list' '
2159 test_must_fail git format-patch --base=HEAD -2 &&
2160 test_must_fail git format-patch --base=HEAD~1 -2 &&
2161 git format-patch --stdout --base=HEAD~2 -2 >patch &&
2162 grep "^base-commit:" patch >actual &&
854b5cb4
DL
2163 git rev-parse HEAD~2 >commit-id-base &&
2164 echo "base-commit: $(cat commit-id-base)" >expect &&
b562a54c 2165 test_cmp expect actual
fa2ab86d
XY
2166'
2167
2168test_expect_success 'format-patch --base errors out when base commit is not ancestor of revision list' '
2169 # For history as below:
2170 #
2171 # ---Q---P---Z---Y---*---X
2172 # \ /
2173 # ------------W
2174 #
2175 # If "format-patch Z..X" is given, P and Z can not be specified as the base commit
8f37854b 2176 git checkout -b topic1 main &&
fa2ab86d
XY
2177 git rev-parse HEAD >commit-id-base &&
2178 test_commit P &&
2179 git rev-parse HEAD >commit-id-P &&
2180 test_commit Z &&
2181 git rev-parse HEAD >commit-id-Z &&
2182 test_commit Y &&
8f37854b 2183 git checkout -b topic2 main &&
fa2ab86d
XY
2184 test_commit W &&
2185 git merge topic1 &&
2186 test_commit X &&
2187 test_must_fail git format-patch --base=$(cat commit-id-P) -3 &&
2188 test_must_fail git format-patch --base=$(cat commit-id-Z) -3 &&
2189 git format-patch --stdout --base=$(cat commit-id-base) -3 >patch &&
2190 grep "^base-commit:" patch >actual &&
b562a54c
DL
2191 echo "base-commit: $(cat commit-id-base)" >expect &&
2192 test_cmp expect actual
fa2ab86d
XY
2193'
2194
3de66517 2195test_expect_success 'format-patch --base=auto' '
8f37854b 2196 git checkout -b upstream main &&
3de66517
XY
2197 git checkout -b local upstream &&
2198 git branch --set-upstream-to=upstream &&
2199 test_commit N1 &&
2200 test_commit N2 &&
2201 git format-patch --stdout --base=auto -2 >patch &&
2202 grep "^base-commit:" patch >actual &&
854b5cb4
DL
2203 git rev-parse upstream >commit-id-base &&
2204 echo "base-commit: $(cat commit-id-base)" >expect &&
b562a54c 2205 test_cmp expect actual
3de66517
XY
2206'
2207
2208test_expect_success 'format-patch errors out when history involves criss-cross' '
2209 # setup criss-cross history
2210 #
2211 # B---M1---D
2212 # / \ /
2213 # A X
2214 # \ / \
2215 # C---M2---E
2216 #
8f37854b 2217 git checkout main &&
3de66517 2218 test_commit A &&
8f37854b 2219 git checkout -b xb main &&
3de66517 2220 test_commit B &&
8f37854b 2221 git checkout -b xc main &&
3de66517
XY
2222 test_commit C &&
2223 git checkout -b xbc xb -- &&
2224 git merge xc &&
2225 git checkout -b xcb xc -- &&
2226 git branch --set-upstream-to=xbc &&
2227 git merge xb &&
2228 git checkout xbc &&
2229 test_commit D &&
2230 git checkout xcb &&
2231 test_commit E &&
2232 test_must_fail git format-patch --base=auto -1
2233'
2234
7efba5fa
JK
2235test_expect_success 'format-patch format.useAutoBase whenAble history involves criss-cross' '
2236 test_config format.useAutoBase whenAble &&
2237 git format-patch -1 >patch &&
2238 ! grep "^base-commit:" patch
2239'
2240
700e006c 2241test_expect_success 'format-patch format.useAutoBase option' '
bb52995f 2242 git checkout local &&
700e006c 2243 test_config format.useAutoBase true &&
bb52995f
XY
2244 git format-patch --stdout -1 >patch &&
2245 grep "^base-commit:" patch >actual &&
854b5cb4
DL
2246 git rev-parse upstream >commit-id-base &&
2247 echo "base-commit: $(cat commit-id-base)" >expect &&
b562a54c 2248 test_cmp expect actual
bb52995f
XY
2249'
2250
7efba5fa
JK
2251test_expect_success 'format-patch format.useAutoBase option with whenAble' '
2252 git checkout local &&
2253 test_config format.useAutoBase whenAble &&
2254 git format-patch --stdout -1 >patch &&
2255 grep "^base-commit:" patch >actual &&
2256 git rev-parse upstream >commit-id-base &&
2257 echo "base-commit: $(cat commit-id-base)" >expect &&
2258 test_cmp expect actual
2259'
2260
bb52995f 2261test_expect_success 'format-patch --base overrides format.useAutoBase' '
700e006c 2262 test_config format.useAutoBase true &&
bb52995f
XY
2263 git format-patch --stdout --base=HEAD~1 -1 >patch &&
2264 grep "^base-commit:" patch >actual &&
854b5cb4
DL
2265 git rev-parse HEAD~1 >commit-id-base &&
2266 echo "base-commit: $(cat commit-id-base)" >expect &&
b562a54c 2267 test_cmp expect actual
bb52995f
XY
2268'
2269
945dc55d
DL
2270test_expect_success 'format-patch --no-base overrides format.useAutoBase' '
2271 test_config format.useAutoBase true &&
2272 git format-patch --stdout --no-base -1 >patch &&
2273 ! grep "^base-commit:" patch
2274'
2275
7efba5fa
JK
2276test_expect_success 'format-patch --no-base overrides format.useAutoBase whenAble' '
2277 test_config format.useAutoBase whenAble &&
2278 git format-patch --stdout --no-base -1 >patch &&
2279 ! grep "^base-commit:" patch
2280'
2281
480871e0
JT
2282test_expect_success 'format-patch --base with --attach' '
2283 git format-patch --attach=mimemime --stdout --base=HEAD~ -1 >patch &&
2284 sed -n -e "/^base-commit:/s/.*/1/p" -e "/^---*mimemime--$/s/.*/2/p" \
2285 patch >actual &&
2286 test_write_lines 1 2 >expect &&
2287 test_cmp expect actual
2288'
50cd54ef 2289test_expect_success 'format-patch --attach cover-letter only is non-multipart' '
2290 test_when_finished "rm -fr patches" &&
2291 git format-patch -o patches --cover-letter --attach=mimemime --base=HEAD~ -1 &&
81580fa0
ĐTCD
2292 ! grep -E "^--+mimemime" patches/0000*.patch &&
2293 grep -E "^--+mimemime$" patches/0001*.patch >output &&
50cd54ef 2294 test_line_count = 2 output &&
81580fa0 2295 grep -E "^--+mimemime--$" patches/0001*.patch >output &&
50cd54ef 2296 test_line_count = 1 output
2297'
480871e0 2298
50bebf98
JH
2299test_expect_success 'format-patch with format.attach' '
2300 test_when_finished "rm -fr patches" &&
2301 separator=attachment-separator &&
2302 test_config format.attach "$separator" &&
2303 filename=$(git format-patch -o patches -1) &&
2304 grep "^Content-Type: multipart/.*$separator" "$filename"
2305'
2306
2307test_expect_success 'format-patch with format.attach=disabled' '
2308 test_when_finished "rm -fr patches" &&
2309 separator=attachment-separator &&
2310 test_config_global format.attach "$separator" &&
2311 test_config format.attach "" &&
2312 filename=$(git format-patch -o patches -1) &&
2313 # The output should not even declare content type for text/plain.
2314 ! grep "^Content-Type: multipart/" "$filename"
2315'
2316
4810946f 2317test_expect_success '-c format.mboxrd format-patch' '
9f23e040
EW
2318 sp=" " &&
2319 cat >msg <<-INPUT_END &&
2320 mboxrd should escape the body
2321
2322 From could trip up a loose mbox parser
2323 >From extra escape for reversibility
2324 >>From extra escape for reversibility 2
2325 from lower case not escaped
2326 Fromm bad speling not escaped
2327 From with leading space not escaped
2328
2329 F
2330 From
2331 From$sp
2332 From $sp
2333 From $sp
2334 INPUT_END
2335
2336 cat >expect <<-INPUT_END &&
2337 >From could trip up a loose mbox parser
2338 >>From extra escape for reversibility
2339 >>>From extra escape for reversibility 2
2340 from lower case not escaped
2341 Fromm bad speling not escaped
2342 From with leading space not escaped
2343
2344 F
2345 From
2346 From
2347 From
2348 From
2349 INPUT_END
2350
2351 C=$(git commit-tree HEAD^^{tree} -p HEAD <msg) &&
4810946f
EW
2352 git -c format.mboxrd format-patch --stdout -1 $C~1..$C >patch &&
2353 git format-patch --pretty=mboxrd --stdout -1 $C~1..$C >compat &&
2354 test_cmp patch compat &&
9f23e040
EW
2355 git grep -h --no-index -A11 \
2356 "^>From could trip up a loose mbox parser" patch >actual &&
2357 test_cmp expect actual
2358'
2359
126facf8 2360test_expect_success 'interdiff: setup' '
8f37854b 2361 git checkout -b boop main &&
126facf8
ES
2362 test_commit fnorp blorp &&
2363 test_commit fleep blorp
2364'
2365
2366test_expect_success 'interdiff: cover-letter' '
2367 sed "y/q/ /" >expect <<-\EOF &&
2368 +fleep
2369 --q
2370 EOF
2371 git format-patch --cover-letter --interdiff=boop~2 -1 boop &&
2372 test_i18ngrep "^Interdiff:$" 0000-cover-letter.patch &&
ee6cbf71 2373 test_i18ngrep ! "^Interdiff:$" 0001-fleep.patch &&
c6ec6dad 2374 sed "1,/^@@ /d; /^-- $/q" 0000-cover-letter.patch >actual &&
126facf8
ES
2375 test_cmp expect actual
2376'
2377
5ac290f9
ES
2378test_expect_success 'interdiff: reroll-count' '
2379 git format-patch --cover-letter --interdiff=boop~2 -v2 -1 boop &&
2380 test_i18ngrep "^Interdiff ..* v1:$" v2-0000-cover-letter.patch
2381'
2382
db91988a
ZH
2383test_expect_success 'interdiff: reroll-count with a non-integer' '
2384 git format-patch --cover-letter --interdiff=boop~2 -v2.2 -1 boop &&
2385 test_i18ngrep "^Interdiff:$" v2.2-0000-cover-letter.patch
2386'
2387
2388test_expect_success 'interdiff: reroll-count with a integer' '
2389 git format-patch --cover-letter --interdiff=boop~2 -v2 -1 boop &&
2390 test_i18ngrep "^Interdiff ..* v1:$" v2-0000-cover-letter.patch
2391'
2392
ee6cbf71
ES
2393test_expect_success 'interdiff: solo-patch' '
2394 cat >expect <<-\EOF &&
2395 +fleep
2396
2397 EOF
2398 git format-patch --interdiff=boop~2 -1 boop &&
2399 test_i18ngrep "^Interdiff:$" 0001-fleep.patch &&
c6ec6dad 2400 sed "1,/^ @@ /d; /^$/q" 0001-fleep.patch >actual &&
ee6cbf71
ES
2401 test_cmp expect actual
2402'
2403
c169af8f
JK
2404test_expect_success 'format-patch does not respect diff.noprefix' '
2405 git -c diff.noprefix format-patch -1 --stdout >actual &&
2406 grep "^--- a/blorp" actual
2407'
2408
8d5213de
JK
2409test_expect_success 'format-patch respects format.noprefix' '
2410 git -c format.noprefix format-patch -1 --stdout >actual &&
2411 grep "^--- blorp" actual
2412'
2413
2414test_expect_success 'format-patch --default-prefix overrides format.noprefix' '
2415 git -c format.noprefix \
2416 format-patch -1 --default-prefix --stdout >actual &&
2417 grep "^--- a/blorp" actual
2418'
2419
ece3c67f 2420test_done