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