use strbuf_addstr() for adding constant strings to a strbuf
[git.git] / t / t4014-format-patch.sh
blob805dc9012d5f765eb40a67e58c1572b1fe316bd6
1 #!/bin/sh
3 # Copyright (c) 2006 Junio C Hamano
6 test_description='various format-patch tests'
8 . ./test-lib.sh
9 . "$TEST_DIRECTORY"/lib-terminal.sh
11 test_expect_success setup '
13 for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i"; done >file &&
14 cat file >elif &&
15 git add file elif &&
16 test_tick &&
17 git commit -m Initial &&
18 git checkout -b side &&
20 for i in 1 2 5 6 A B C 7 8 9 10; do echo "$i"; done >file &&
21 test_chmod +x elif &&
22 test_tick &&
23 git commit -m "Side changes #1" &&
25 for i in D E F; do echo "$i"; done >>file &&
26 git update-index file &&
27 test_tick &&
28 git commit -m "Side changes #2" &&
29 git tag C2 &&
31 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file &&
32 git update-index file &&
33 test_tick &&
34 git commit -m "Side changes #3 with \\n backslash-n in it." &&
36 git checkout master &&
37 git diff-tree -p C2 | git apply --index &&
38 test_tick &&
39 git commit -m "Master accepts moral equivalent of #2"
43 test_expect_success "format-patch --ignore-if-in-upstream" '
45 git format-patch --stdout master..side >patch0 &&
46 cnt=$(grep "^From " patch0 | wc -l) &&
47 test $cnt = 3
51 test_expect_success "format-patch --ignore-if-in-upstream" '
53 git format-patch --stdout \
54 --ignore-if-in-upstream master..side >patch1 &&
55 cnt=$(grep "^From " patch1 | wc -l) &&
56 test $cnt = 2
60 test_expect_success "format-patch --ignore-if-in-upstream handles tags" '
61 git tag -a v1 -m tag side &&
62 git tag -a v2 -m tag master &&
63 git format-patch --stdout --ignore-if-in-upstream v2..v1 >patch1 &&
64 cnt=$(grep "^From " patch1 | wc -l) &&
65 test $cnt = 2
68 test_expect_success "format-patch doesn't consider merge commits" '
70 git checkout -b slave master &&
71 echo "Another line" >>file &&
72 test_tick &&
73 git commit -am "Slave change #1" &&
74 echo "Yet another line" >>file &&
75 test_tick &&
76 git commit -am "Slave change #2" &&
77 git checkout -b merger master &&
78 test_tick &&
79 git merge --no-ff slave &&
80 cnt=$(git format-patch -3 --stdout | grep "^From " | wc -l) &&
81 test $cnt = 3
84 test_expect_success "format-patch result applies" '
86 git checkout -b rebuild-0 master &&
87 git am -3 patch0 &&
88 cnt=$(git rev-list master.. | wc -l) &&
89 test $cnt = 2
92 test_expect_success "format-patch --ignore-if-in-upstream result applies" '
94 git checkout -b rebuild-1 master &&
95 git am -3 patch1 &&
96 cnt=$(git rev-list master.. | wc -l) &&
97 test $cnt = 2
100 test_expect_success 'commit did not screw up the log message' '
102 git cat-file commit side | grep "^Side .* with .* backslash-n"
106 test_expect_success 'format-patch did not screw up the log message' '
108 grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
109 grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
113 test_expect_success 'replay did not screw up the log message' '
115 git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
119 test_expect_success 'extra headers' '
121 git config format.headers "To: R E Cipient <rcipient@example.com>
122 " &&
123 git config --add format.headers "Cc: S E Cipient <scipient@example.com>
124 " &&
125 git format-patch --stdout master..side > patch2 &&
126 sed -e "/^\$/q" patch2 > hdrs2 &&
127 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs2 &&
128 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs2
132 test_expect_success 'extra headers without newlines' '
134 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
135 git config --add format.headers "Cc: S E Cipient <scipient@example.com>" &&
136 git format-patch --stdout master..side >patch3 &&
137 sed -e "/^\$/q" patch3 > hdrs3 &&
138 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs3 &&
139 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs3
143 test_expect_success 'extra headers with multiple To:s' '
145 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
146 git config --add format.headers "To: S E Cipient <scipient@example.com>" &&
147 git format-patch --stdout master..side > patch4 &&
148 sed -e "/^\$/q" patch4 > hdrs4 &&
149 grep "^To: R E Cipient <rcipient@example.com>,\$" hdrs4 &&
150 grep "^ *S E Cipient <scipient@example.com>\$" hdrs4
153 test_expect_success 'additional command line cc (ascii)' '
155 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
156 git format-patch --cc="S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
157 grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
158 grep "^ *S E Cipient <scipient@example.com>\$" patch5
161 test_expect_failure 'additional command line cc (rfc822)' '
163 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
164 git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
165 grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
166 grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" patch5
169 test_expect_success 'command line headers' '
171 git config --unset-all format.headers &&
172 git format-patch --add-header="Cc: R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 &&
173 grep "^Cc: R E Cipient <rcipient@example.com>\$" patch6
176 test_expect_success 'configuration headers and command line headers' '
178 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
179 git format-patch --add-header="Cc: S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 &&
180 grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch7 &&
181 grep "^ *S E Cipient <scipient@example.com>\$" patch7
184 test_expect_success 'command line To: header (ascii)' '
186 git config --unset-all format.headers &&
187 git format-patch --to="R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
188 grep "^To: R E Cipient <rcipient@example.com>\$" patch8
191 test_expect_failure 'command line To: header (rfc822)' '
193 git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
194 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch8
197 test_expect_failure 'command line To: header (rfc2047)' '
199 git format-patch --to="R Ä Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
200 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch8
203 test_expect_success 'configuration To: header (ascii)' '
205 git config format.to "R E Cipient <rcipient@example.com>" &&
206 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
207 grep "^To: R E Cipient <rcipient@example.com>\$" patch9
210 test_expect_failure 'configuration To: header (rfc822)' '
212 git config format.to "R. E. Cipient <rcipient@example.com>" &&
213 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
214 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch9
217 test_expect_failure 'configuration To: header (rfc2047)' '
219 git config format.to "R Ä Cipient <rcipient@example.com>" &&
220 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
221 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch9
224 # check_patch <patch>: Verify that <patch> looks like a half-sane
225 # patch email to avoid a false positive with !grep
226 check_patch () {
227 grep -e "^From:" "$1" &&
228 grep -e "^Date:" "$1" &&
229 grep -e "^Subject:" "$1"
232 test_expect_success '--no-to overrides config.to' '
234 git config --replace-all format.to \
235 "R E Cipient <rcipient@example.com>" &&
236 git format-patch --no-to --stdout master..side |
237 sed -e "/^\$/q" >patch10 &&
238 check_patch patch10 &&
239 ! grep "^To: R E Cipient <rcipient@example.com>\$" patch10
242 test_expect_success '--no-to and --to replaces config.to' '
244 git config --replace-all format.to \
245 "Someone <someone@out.there>" &&
246 git format-patch --no-to --to="Someone Else <else@out.there>" \
247 --stdout master..side |
248 sed -e "/^\$/q" >patch11 &&
249 check_patch patch11 &&
250 ! grep "^To: Someone <someone@out.there>\$" patch11 &&
251 grep "^To: Someone Else <else@out.there>\$" patch11
254 test_expect_success '--no-cc overrides config.cc' '
256 git config --replace-all format.cc \
257 "C E Cipient <rcipient@example.com>" &&
258 git format-patch --no-cc --stdout master..side |
259 sed -e "/^\$/q" >patch12 &&
260 check_patch patch12 &&
261 ! grep "^Cc: C E Cipient <rcipient@example.com>\$" patch12
264 test_expect_success '--no-add-header overrides config.headers' '
266 git config --replace-all format.headers \
267 "Header1: B E Cipient <rcipient@example.com>" &&
268 git format-patch --no-add-header --stdout master..side |
269 sed -e "/^\$/q" >patch13 &&
270 check_patch patch13 &&
271 ! grep "^Header1: B E Cipient <rcipient@example.com>\$" patch13
274 test_expect_success 'multiple files' '
276 rm -rf patches/ &&
277 git checkout side &&
278 git format-patch -o patches/ master &&
279 ls patches/0001-Side-changes-1.patch patches/0002-Side-changes-2.patch patches/0003-Side-changes-3-with-n-backslash-n-in-it.patch
282 test_expect_success 'reroll count' '
283 rm -fr patches &&
284 git format-patch -o patches --cover-letter --reroll-count 4 master..side >list &&
285 ! grep -v "^patches/v4-000[0-3]-" list &&
286 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
287 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
290 test_expect_success 'reroll count (-v)' '
291 rm -fr patches &&
292 git format-patch -o patches --cover-letter -v4 master..side >list &&
293 ! grep -v "^patches/v4-000[0-3]-" list &&
294 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
295 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
298 check_threading () {
299 expect="$1" &&
300 shift &&
301 (git format-patch --stdout "$@"; echo $? > status.out) |
302 # Prints everything between the Message-ID and In-Reply-To,
303 # and replaces all Message-ID-lookalikes by a sequence number
304 perl -ne '
305 if (/^(message-id|references|in-reply-to)/i) {
306 $printing = 1;
307 } elsif (/^\S/) {
308 $printing = 0;
310 if ($printing) {
311 $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
312 for $k (keys %h) {s/$k/$h{$k}/};
313 print;
315 print "---\n" if /^From /i;
316 ' > actual &&
317 test 0 = "$(cat status.out)" &&
318 test_cmp "$expect" actual
321 cat >> expect.no-threading <<EOF
327 test_expect_success 'no threading' '
328 git checkout side &&
329 check_threading expect.no-threading master
332 cat > expect.thread <<EOF
334 Message-Id: <0>
336 Message-Id: <1>
337 In-Reply-To: <0>
338 References: <0>
340 Message-Id: <2>
341 In-Reply-To: <0>
342 References: <0>
345 test_expect_success 'thread' '
346 check_threading expect.thread --thread master
349 cat > expect.in-reply-to <<EOF
351 Message-Id: <0>
352 In-Reply-To: <1>
353 References: <1>
355 Message-Id: <2>
356 In-Reply-To: <1>
357 References: <1>
359 Message-Id: <3>
360 In-Reply-To: <1>
361 References: <1>
364 test_expect_success 'thread in-reply-to' '
365 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
366 --thread master
369 cat > expect.cover-letter <<EOF
371 Message-Id: <0>
373 Message-Id: <1>
374 In-Reply-To: <0>
375 References: <0>
377 Message-Id: <2>
378 In-Reply-To: <0>
379 References: <0>
381 Message-Id: <3>
382 In-Reply-To: <0>
383 References: <0>
386 test_expect_success 'thread cover-letter' '
387 check_threading expect.cover-letter --cover-letter --thread master
390 cat > expect.cl-irt <<EOF
392 Message-Id: <0>
393 In-Reply-To: <1>
394 References: <1>
396 Message-Id: <2>
397 In-Reply-To: <0>
398 References: <1>
401 Message-Id: <3>
402 In-Reply-To: <0>
403 References: <1>
406 Message-Id: <4>
407 In-Reply-To: <0>
408 References: <1>
412 test_expect_success 'thread cover-letter in-reply-to' '
413 check_threading expect.cl-irt --cover-letter \
414 --in-reply-to="<test.message>" --thread master
417 test_expect_success 'thread explicit shallow' '
418 check_threading expect.cl-irt --cover-letter \
419 --in-reply-to="<test.message>" --thread=shallow master
422 cat > expect.deep <<EOF
424 Message-Id: <0>
426 Message-Id: <1>
427 In-Reply-To: <0>
428 References: <0>
430 Message-Id: <2>
431 In-Reply-To: <1>
432 References: <0>
436 test_expect_success 'thread deep' '
437 check_threading expect.deep --thread=deep master
440 cat > expect.deep-irt <<EOF
442 Message-Id: <0>
443 In-Reply-To: <1>
444 References: <1>
446 Message-Id: <2>
447 In-Reply-To: <0>
448 References: <1>
451 Message-Id: <3>
452 In-Reply-To: <2>
453 References: <1>
458 test_expect_success 'thread deep in-reply-to' '
459 check_threading expect.deep-irt --thread=deep \
460 --in-reply-to="<test.message>" master
463 cat > expect.deep-cl <<EOF
465 Message-Id: <0>
467 Message-Id: <1>
468 In-Reply-To: <0>
469 References: <0>
471 Message-Id: <2>
472 In-Reply-To: <1>
473 References: <0>
476 Message-Id: <3>
477 In-Reply-To: <2>
478 References: <0>
483 test_expect_success 'thread deep cover-letter' '
484 check_threading expect.deep-cl --cover-letter --thread=deep master
487 cat > expect.deep-cl-irt <<EOF
489 Message-Id: <0>
490 In-Reply-To: <1>
491 References: <1>
493 Message-Id: <2>
494 In-Reply-To: <0>
495 References: <1>
498 Message-Id: <3>
499 In-Reply-To: <2>
500 References: <1>
504 Message-Id: <4>
505 In-Reply-To: <3>
506 References: <1>
512 test_expect_success 'thread deep cover-letter in-reply-to' '
513 check_threading expect.deep-cl-irt --cover-letter \
514 --in-reply-to="<test.message>" --thread=deep master
517 test_expect_success 'thread via config' '
518 test_config format.thread true &&
519 check_threading expect.thread master
522 test_expect_success 'thread deep via config' '
523 test_config format.thread deep &&
524 check_threading expect.deep master
527 test_expect_success 'thread config + override' '
528 test_config format.thread deep &&
529 check_threading expect.thread --thread master
532 test_expect_success 'thread config + --no-thread' '
533 test_config format.thread deep &&
534 check_threading expect.no-threading --no-thread master
537 test_expect_success 'excessive subject' '
539 rm -rf patches/ &&
540 git checkout side &&
541 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
542 git update-index file &&
543 git commit -m "This is an excessively long subject line for a message due to the habit some projects have of not having a short, one-line subject at the start of the commit message, but rather sticking a whole paragraph right at the start as the only thing in the commit message. It had better not become the filename for the patch." &&
544 git format-patch -o patches/ master..side &&
545 ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
548 test_expect_success 'cover-letter inherits diff options' '
550 git mv file foo &&
551 git commit -m foo &&
552 git format-patch --no-renames --cover-letter -1 &&
553 check_patch 0000-cover-letter.patch &&
554 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
555 git format-patch --cover-letter -1 -M &&
556 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
560 cat > expect << EOF
561 This is an excessively long subject line for a message due to the
562 habit some projects have of not having a short, one-line subject at
563 the start of the commit message, but rather sticking a whole
564 paragraph right at the start as the only thing in the commit
565 message. It had better not become the filename for the patch.
570 test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
572 git format-patch --cover-letter -2 &&
573 sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
574 test_cmp expect output
578 cat > expect << EOF
579 index 40f36c6..2dc5c23 100644
580 --- a/file
581 +++ b/file
582 @@ -13,4 +13,20 @@ C
590 test_expect_success 'format-patch respects -U' '
592 git format-patch -U4 -2 &&
593 sed -e "1,/^diff/d" -e "/^+5/q" \
594 <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
595 >output &&
596 test_cmp expect output
600 cat > expect << EOF
602 diff --git a/file b/file
603 index 40f36c6..2dc5c23 100644
604 --- a/file
605 +++ b/file
606 @@ -14,3 +14,19 @@ C
613 test_expect_success 'format-patch -p suppresses stat' '
615 git format-patch -p -2 &&
616 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
617 test_cmp expect output
621 test_expect_success 'format-patch from a subdirectory (1)' '
622 filename=$(
623 rm -rf sub &&
624 mkdir -p sub/dir &&
625 cd sub/dir &&
626 git format-patch -1
627 ) &&
628 case "$filename" in
630 ;; # ok
632 echo "Oops? $filename"
633 false
635 esac &&
636 test -f "$filename"
639 test_expect_success 'format-patch from a subdirectory (2)' '
640 filename=$(
641 rm -rf sub &&
642 mkdir -p sub/dir &&
643 cd sub/dir &&
644 git format-patch -1 -o ..
645 ) &&
646 case "$filename" in
647 ../0*)
648 ;; # ok
650 echo "Oops? $filename"
651 false
653 esac &&
654 basename=$(expr "$filename" : ".*/\(.*\)") &&
655 test -f "sub/$basename"
658 test_expect_success 'format-patch from a subdirectory (3)' '
659 rm -f 0* &&
660 filename=$(
661 rm -rf sub &&
662 mkdir -p sub/dir &&
663 cd sub/dir &&
664 git format-patch -1 -o "$TRASH_DIRECTORY"
665 ) &&
666 basename=$(expr "$filename" : ".*/\(.*\)") &&
667 test -f "$basename"
670 test_expect_success 'format-patch --in-reply-to' '
671 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
672 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
673 grep "^References: <baz@foo.bar>" patch8
676 test_expect_success 'format-patch --signoff' '
677 git format-patch -1 --signoff --stdout >out &&
678 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
681 test_expect_success 'format-patch --notes --signoff' '
682 git notes --ref test add -m "test message" HEAD &&
683 git format-patch -1 --signoff --stdout --notes=test >out &&
684 # Three dashes must come after S-o-b
685 ! sed "/^Signed-off-by: /q" out | grep "test message" &&
686 sed "1,/^Signed-off-by: /d" out | grep "test message" &&
687 # Notes message must come after three dashes
688 ! sed "/^---$/q" out | grep "test message" &&
689 sed "1,/^---$/d" out | grep "test message"
692 echo "fatal: --name-only does not make sense" > expect.name-only
693 echo "fatal: --name-status does not make sense" > expect.name-status
694 echo "fatal: --check does not make sense" > expect.check
696 test_expect_success 'options no longer allowed for format-patch' '
697 test_must_fail git format-patch --name-only 2> output &&
698 test_i18ncmp expect.name-only output &&
699 test_must_fail git format-patch --name-status 2> output &&
700 test_i18ncmp expect.name-status output &&
701 test_must_fail git format-patch --check 2> output &&
702 test_i18ncmp expect.check output'
704 test_expect_success 'format-patch --numstat should produce a patch' '
705 git format-patch --numstat --stdout master..side > output &&
706 test 5 = $(grep "^diff --git a/" output | wc -l)'
708 test_expect_success 'format-patch -- <path>' '
709 git format-patch master..side -- file 2>error &&
710 ! grep "Use .--" error
713 test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
714 git format-patch --ignore-if-in-upstream HEAD
717 test_expect_success 'format-patch --signature' '
718 git format-patch --stdout --signature="my sig" -1 >output &&
719 grep "my sig" output
722 test_expect_success 'format-patch with format.signature config' '
723 git config format.signature "config sig" &&
724 git format-patch --stdout -1 >output &&
725 grep "config sig" output
728 test_expect_success 'format-patch --signature overrides format.signature' '
729 git config format.signature "config sig" &&
730 git format-patch --stdout --signature="overrides" -1 >output &&
731 ! grep "config sig" output &&
732 grep "overrides" output
735 test_expect_success 'format-patch --no-signature ignores format.signature' '
736 git config format.signature "config sig" &&
737 git format-patch --stdout --signature="my sig" --no-signature \
738 -1 >output &&
739 check_patch output &&
740 ! grep "config sig" output &&
741 ! grep "my sig" output &&
742 ! grep "^-- \$" output
745 test_expect_success 'format-patch --signature --cover-letter' '
746 git config --unset-all format.signature &&
747 git format-patch --stdout --signature="my sig" --cover-letter \
748 -1 >output &&
749 grep "my sig" output &&
750 test 2 = $(grep "my sig" output | wc -l)
753 test_expect_success 'format.signature="" suppresses signatures' '
754 git config format.signature "" &&
755 git format-patch --stdout -1 >output &&
756 check_patch output &&
757 ! grep "^-- \$" output
760 test_expect_success 'format-patch --no-signature suppresses signatures' '
761 git config --unset-all format.signature &&
762 git format-patch --stdout --no-signature -1 >output &&
763 check_patch output &&
764 ! grep "^-- \$" output
767 test_expect_success 'format-patch --signature="" suppresses signatures' '
768 git format-patch --stdout --signature="" -1 >output &&
769 check_patch output &&
770 ! grep "^-- \$" output
773 test_expect_success 'prepare mail-signature input' '
774 cat >mail-signature <<-\EOF
776 Test User <test.email@kernel.org>
777 http://git.kernel.org/cgit/git/git.git
779 git.kernel.org/?p=git/git.git;a=summary
784 test_expect_success '--signature-file=file works' '
785 git format-patch --stdout --signature-file=mail-signature -1 >output &&
786 check_patch output &&
787 sed -e "1,/^-- \$/d" <output >actual &&
789 cat mail-signature && echo
790 } >expect &&
791 test_cmp expect actual
794 test_expect_success 'format.signaturefile works' '
795 test_config format.signaturefile mail-signature &&
796 git format-patch --stdout -1 >output &&
797 check_patch output &&
798 sed -e "1,/^-- \$/d" <output >actual &&
800 cat mail-signature && echo
801 } >expect &&
802 test_cmp expect actual
805 test_expect_success '--no-signature suppresses format.signaturefile ' '
806 test_config format.signaturefile mail-signature &&
807 git format-patch --stdout --no-signature -1 >output &&
808 check_patch output &&
809 ! grep "^-- \$" output
812 test_expect_success '--signature-file overrides format.signaturefile' '
813 cat >other-mail-signature <<-\EOF &&
814 Use this other signature instead of mail-signature.
816 test_config format.signaturefile mail-signature &&
817 git format-patch --stdout \
818 --signature-file=other-mail-signature -1 >output &&
819 check_patch output &&
820 sed -e "1,/^-- \$/d" <output >actual &&
822 cat other-mail-signature && echo
823 } >expect &&
824 test_cmp expect actual
827 test_expect_success '--signature overrides format.signaturefile' '
828 test_config format.signaturefile mail-signature &&
829 git format-patch --stdout --signature="my sig" -1 >output &&
830 check_patch output &&
831 grep "my sig" output
834 test_expect_success TTY 'format-patch --stdout paginates' '
835 rm -f pager_used &&
836 test_terminal env GIT_PAGER="wc >pager_used" git format-patch --stdout --all &&
837 test_path_is_file pager_used
840 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
841 rm -f pager_used &&
842 test_terminal env GIT_PAGER="wc >pager_used" git --no-pager format-patch --stdout --all &&
843 test_terminal env GIT_PAGER="wc >pager_used" git -c "pager.format-patch=false" format-patch --stdout --all &&
844 test_path_is_missing pager_used &&
845 test_path_is_missing .git/pager_used
848 test_expect_success 'format-patch handles multi-line subjects' '
849 rm -rf patches/ &&
850 echo content >>file &&
851 for i in one two three; do echo $i; done >msg &&
852 git add file &&
853 git commit -F msg &&
854 git format-patch -o patches -1 &&
855 grep ^Subject: patches/0001-one.patch >actual &&
856 echo "Subject: [PATCH] one two three" >expect &&
857 test_cmp expect actual
860 test_expect_success 'format-patch handles multi-line encoded subjects' '
861 rm -rf patches/ &&
862 echo content >>file &&
863 for i in en två tre; do echo $i; done >msg &&
864 git add file &&
865 git commit -F msg &&
866 git format-patch -o patches -1 &&
867 grep ^Subject: patches/0001-en.patch >actual &&
868 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
869 test_cmp expect actual
872 M8="foo bar "
873 M64=$M8$M8$M8$M8$M8$M8$M8$M8
874 M512=$M64$M64$M64$M64$M64$M64$M64$M64
875 cat >expect <<'EOF'
876 Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
877 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
878 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
879 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
880 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
881 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
882 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
884 test_expect_success 'format-patch wraps extremely long subject (ascii)' '
885 echo content >>file &&
886 git add file &&
887 git commit -m "$M512" &&
888 git format-patch --stdout -1 >patch &&
889 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
890 test_cmp expect subject
893 M8="föö bar "
894 M64=$M8$M8$M8$M8$M8$M8$M8$M8
895 M512=$M64$M64$M64$M64$M64$M64$M64$M64
896 cat >expect <<'EOF'
897 Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
898 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
899 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
900 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
901 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
902 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
903 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
904 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
905 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
906 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
907 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
908 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
909 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
910 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
911 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
912 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
913 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
914 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
915 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
916 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
917 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
918 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
919 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
920 =?UTF-8?q?bar?=
922 test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
923 rm -rf patches/ &&
924 echo content >>file &&
925 git add file &&
926 git commit -m "$M512" &&
927 git format-patch --stdout -1 >patch &&
928 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
929 test_cmp expect subject
932 check_author() {
933 echo content >>file &&
934 git add file &&
935 GIT_AUTHOR_NAME=$1 git commit -m author-check &&
936 git format-patch --stdout -1 >patch &&
937 sed -n "/^From: /p; /^ /p; /^$/q" <patch >actual &&
938 test_cmp expect actual
941 cat >expect <<'EOF'
942 From: "Foo B. Bar" <author@example.com>
944 test_expect_success 'format-patch quotes dot in from-headers' '
945 check_author "Foo B. Bar"
948 cat >expect <<'EOF'
949 From: "Foo \"The Baz\" Bar" <author@example.com>
951 test_expect_success 'format-patch quotes double-quote in from-headers' '
952 check_author "Foo \"The Baz\" Bar"
955 cat >expect <<'EOF'
956 From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
958 test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
959 check_author "Föo Bar"
962 cat >expect <<'EOF'
963 From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
965 test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
966 check_author "Föo B. Bar"
969 cat >expect <<EOF
970 From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
971 <author@example.com>
973 test_expect_success 'format-patch wraps moderately long from-header (ascii)' '
974 check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
977 cat >expect <<'EOF'
978 From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
979 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
980 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
982 test_expect_success 'format-patch wraps extremely long from-header (ascii)' '
983 check_author "Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar"
986 cat >expect <<'EOF'
987 From: "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
988 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
989 Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
991 test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
992 check_author "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar"
995 cat >expect <<'EOF'
996 From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
997 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
998 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
999 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
1000 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
1002 test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
1003 check_author "Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar"
1006 cat >expect <<'EOF'
1007 Subject: header with . in it
1009 test_expect_success 'subject lines do not have 822 atom-quoting' '
1010 echo content >>file &&
1011 git add file &&
1012 git commit -m "header with . in it" &&
1013 git format-patch -k -1 --stdout >patch &&
1014 grep ^Subject: patch >actual &&
1015 test_cmp expect actual
1018 cat >expect <<'EOF'
1019 Subject: [PREFIX 1/1] header with . in it
1021 test_expect_success 'subject prefixes have space prepended' '
1022 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
1023 grep ^Subject: patch >actual &&
1024 test_cmp expect actual
1027 cat >expect <<'EOF'
1028 Subject: [1/1] header with . in it
1030 test_expect_success 'empty subject prefix does not have extra space' '
1031 git format-patch -n -1 --stdout --subject-prefix= >patch &&
1032 grep ^Subject: patch >actual &&
1033 test_cmp expect actual
1036 test_expect_success '--from=ident notices bogus ident' '
1037 test_must_fail git format-patch -1 --stdout --from=foo >patch
1040 test_expect_success '--from=ident replaces author' '
1041 git format-patch -1 --stdout --from="Me <me@example.com>" >patch &&
1042 cat >expect <<-\EOF &&
1043 From: Me <me@example.com>
1045 From: A U Thor <author@example.com>
1048 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1049 test_cmp expect patch.head
1052 test_expect_success '--from uses committer ident' '
1053 git format-patch -1 --stdout --from >patch &&
1054 cat >expect <<-\EOF &&
1055 From: C O Mitter <committer@example.com>
1057 From: A U Thor <author@example.com>
1060 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1061 test_cmp expect patch.head
1064 test_expect_success '--from omits redundant in-body header' '
1065 git format-patch -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1066 cat >expect <<-\EOF &&
1067 From: A U Thor <author@example.com>
1070 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1071 test_cmp expect patch.head
1074 test_expect_success 'in-body headers trigger content encoding' '
1075 test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
1076 test_when_finished "git reset --hard HEAD^" &&
1077 git format-patch -1 --stdout --from >patch &&
1078 cat >expect <<-\EOF &&
1079 From: C O Mitter <committer@example.com>
1080 Content-Type: text/plain; charset=UTF-8
1082 From: éxötìc <author@example.com>
1085 sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" <patch >patch.head &&
1086 test_cmp expect patch.head
1089 append_signoff()
1091 C=$(git commit-tree HEAD^^{tree} -p HEAD) &&
1092 git format-patch --stdout --signoff $C^..$C >append_signoff.patch &&
1093 sed -n -e "1,/^---$/p" append_signoff.patch |
1094 egrep -n "^Subject|Sign|^$"
1097 test_expect_success 'signoff: commit with no body' '
1098 append_signoff </dev/null >actual &&
1099 cat <<\EOF | sed "s/EOL$//" >expected &&
1100 4:Subject: [PATCH] EOL
1102 9:Signed-off-by: C O Mitter <committer@example.com>
1104 test_cmp expected actual
1107 test_expect_success 'signoff: commit with only subject' '
1108 echo subject | append_signoff >actual &&
1109 cat >expected <<\EOF &&
1110 4:Subject: [PATCH] subject
1112 9:Signed-off-by: C O Mitter <committer@example.com>
1114 test_cmp expected actual
1117 test_expect_success 'signoff: commit with only subject that does not end with NL' '
1118 printf subject | append_signoff >actual &&
1119 cat >expected <<\EOF &&
1120 4:Subject: [PATCH] subject
1122 9:Signed-off-by: C O Mitter <committer@example.com>
1124 test_cmp expected actual
1127 test_expect_success 'signoff: no existing signoffs' '
1128 append_signoff <<\EOF >actual &&
1129 subject
1131 body
1133 cat >expected <<\EOF &&
1134 4:Subject: [PATCH] subject
1137 11:Signed-off-by: C O Mitter <committer@example.com>
1139 test_cmp expected actual
1142 test_expect_success 'signoff: no existing signoffs and no trailing NL' '
1143 printf "subject\n\nbody" | append_signoff >actual &&
1144 cat >expected <<\EOF &&
1145 4:Subject: [PATCH] subject
1148 11:Signed-off-by: C O Mitter <committer@example.com>
1150 test_cmp expected actual
1153 test_expect_success 'signoff: some random signoff' '
1154 append_signoff <<\EOF >actual &&
1155 subject
1157 body
1159 Signed-off-by: my@house
1161 cat >expected <<\EOF &&
1162 4:Subject: [PATCH] subject
1165 11:Signed-off-by: my@house
1166 12:Signed-off-by: C O Mitter <committer@example.com>
1168 test_cmp expected actual
1171 test_expect_success 'signoff: misc conforming footer elements' '
1172 append_signoff <<\EOF >actual &&
1173 subject
1175 body
1177 Signed-off-by: my@house
1178 (cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1179 Tested-by: Some One <someone@example.com>
1180 Bug: 1234
1182 cat >expected <<\EOF &&
1183 4:Subject: [PATCH] subject
1186 11:Signed-off-by: my@house
1187 15:Signed-off-by: C O Mitter <committer@example.com>
1189 test_cmp expected actual
1192 test_expect_success 'signoff: some random signoff-alike' '
1193 append_signoff <<\EOF >actual &&
1194 subject
1196 body
1197 Fooled-by-me: my@house
1199 cat >expected <<\EOF &&
1200 4:Subject: [PATCH] subject
1203 12:Signed-off-by: C O Mitter <committer@example.com>
1205 test_cmp expected actual
1208 test_expect_success 'signoff: not really a signoff' '
1209 append_signoff <<\EOF >actual &&
1210 subject
1212 I want to mention about Signed-off-by: here.
1214 cat >expected <<\EOF &&
1215 4:Subject: [PATCH] subject
1217 9:I want to mention about Signed-off-by: here.
1219 11:Signed-off-by: C O Mitter <committer@example.com>
1221 test_cmp expected actual
1224 test_expect_success 'signoff: not really a signoff (2)' '
1225 append_signoff <<\EOF >actual &&
1226 subject
1228 My unfortunate
1229 Signed-off-by: example happens to be wrapped here.
1231 cat >expected <<\EOF &&
1232 4:Subject: [PATCH] subject
1234 10:Signed-off-by: example happens to be wrapped here.
1236 12:Signed-off-by: C O Mitter <committer@example.com>
1238 test_cmp expected actual
1241 test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
1242 append_signoff <<\EOF >actual &&
1243 subject
1245 Signed-off-by: my@house
1246 Signed-off-by: your@house
1248 A lot of houses.
1250 cat >expected <<\EOF &&
1251 4:Subject: [PATCH] subject
1253 9:Signed-off-by: my@house
1254 10:Signed-off-by: your@house
1257 14:Signed-off-by: C O Mitter <committer@example.com>
1259 test_cmp expected actual
1262 test_expect_success 'signoff: the same signoff at the end' '
1263 append_signoff <<\EOF >actual &&
1264 subject
1266 body
1268 Signed-off-by: C O Mitter <committer@example.com>
1270 cat >expected <<\EOF &&
1271 4:Subject: [PATCH] subject
1274 11:Signed-off-by: C O Mitter <committer@example.com>
1276 test_cmp expected actual
1279 test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
1280 printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
1281 append_signoff >actual &&
1282 cat >expected <<\EOF &&
1283 4:Subject: [PATCH] subject
1285 9:Signed-off-by: C O Mitter <committer@example.com>
1287 test_cmp expected actual
1290 test_expect_success 'signoff: the same signoff NOT at the end' '
1291 append_signoff <<\EOF >actual &&
1292 subject
1294 body
1296 Signed-off-by: C O Mitter <committer@example.com>
1297 Signed-off-by: my@house
1299 cat >expected <<\EOF &&
1300 4:Subject: [PATCH] subject
1303 11:Signed-off-by: C O Mitter <committer@example.com>
1304 12:Signed-off-by: my@house
1306 test_cmp expected actual
1309 test_expect_success 'signoff: detect garbage in non-conforming footer' '
1310 append_signoff <<\EOF >actual &&
1311 subject
1313 body
1315 Tested-by: my@house
1316 Some Trash
1317 Signed-off-by: C O Mitter <committer@example.com>
1319 cat >expected <<\EOF &&
1320 4:Subject: [PATCH] subject
1323 13:Signed-off-by: C O Mitter <committer@example.com>
1325 15:Signed-off-by: C O Mitter <committer@example.com>
1327 test_cmp expected actual
1330 test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
1331 append_signoff <<\EOF >actual &&
1332 subject
1334 body
1336 Reviewed-id: Noone
1337 Tested-by: my@house
1338 Change-id: Ideadbeef
1339 Signed-off-by: C O Mitter <committer@example.com>
1340 Bug: 1234
1342 cat >expected <<\EOF &&
1343 4:Subject: [PATCH] subject
1346 14:Signed-off-by: C O Mitter <committer@example.com>
1348 test_cmp expected actual
1351 test_expect_success 'format patch ignores color.ui' '
1352 test_unconfig color.ui &&
1353 git format-patch --stdout -1 >expect &&
1354 test_config color.ui always &&
1355 git format-patch --stdout -1 >actual &&
1356 test_cmp expect actual
1359 test_expect_success 'cover letter using branch description (1)' '
1360 git checkout rebuild-1 &&
1361 test_config branch.rebuild-1.description hello &&
1362 git format-patch --stdout --cover-letter master >actual &&
1363 grep hello actual >/dev/null
1366 test_expect_success 'cover letter using branch description (2)' '
1367 git checkout rebuild-1 &&
1368 test_config branch.rebuild-1.description hello &&
1369 git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
1370 grep hello actual >/dev/null
1373 test_expect_success 'cover letter using branch description (3)' '
1374 git checkout rebuild-1 &&
1375 test_config branch.rebuild-1.description hello &&
1376 git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
1377 grep hello actual >/dev/null
1380 test_expect_success 'cover letter using branch description (4)' '
1381 git checkout rebuild-1 &&
1382 test_config branch.rebuild-1.description hello &&
1383 git format-patch --stdout --cover-letter master.. >actual &&
1384 grep hello actual >/dev/null
1387 test_expect_success 'cover letter using branch description (5)' '
1388 git checkout rebuild-1 &&
1389 test_config branch.rebuild-1.description hello &&
1390 git format-patch --stdout --cover-letter -2 HEAD >actual &&
1391 grep hello actual >/dev/null
1394 test_expect_success 'cover letter using branch description (6)' '
1395 git checkout rebuild-1 &&
1396 test_config branch.rebuild-1.description hello &&
1397 git format-patch --stdout --cover-letter -2 >actual &&
1398 grep hello actual >/dev/null
1401 test_expect_success 'cover letter with nothing' '
1402 git format-patch --stdout --cover-letter >actual &&
1403 test_line_count = 0 actual
1406 test_expect_success 'cover letter auto' '
1407 mkdir -p tmp &&
1408 test_when_finished "rm -rf tmp;
1409 git config --unset format.coverletter" &&
1411 git config format.coverletter auto &&
1412 git format-patch -o tmp -1 >list &&
1413 test_line_count = 1 list &&
1414 git format-patch -o tmp -2 >list &&
1415 test_line_count = 3 list
1418 test_expect_success 'cover letter auto user override' '
1419 mkdir -p tmp &&
1420 test_when_finished "rm -rf tmp;
1421 git config --unset format.coverletter" &&
1423 git config format.coverletter auto &&
1424 git format-patch -o tmp --cover-letter -1 >list &&
1425 test_line_count = 2 list &&
1426 git format-patch -o tmp --cover-letter -2 >list &&
1427 test_line_count = 3 list &&
1428 git format-patch -o tmp --no-cover-letter -1 >list &&
1429 test_line_count = 1 list &&
1430 git format-patch -o tmp --no-cover-letter -2 >list &&
1431 test_line_count = 2 list
1434 test_expect_success 'format-patch --zero-commit' '
1435 git format-patch --zero-commit --stdout v2..v1 >patch2 &&
1436 grep "^From " patch2 | sort | uniq >actual &&
1437 echo "From $_z40 Mon Sep 17 00:00:00 2001" >expect &&
1438 test_cmp expect actual
1441 test_expect_success 'From line has expected format' '
1442 git format-patch --stdout v2..v1 >patch2 &&
1443 grep "^From " patch2 >from &&
1444 grep "^From $_x40 Mon Sep 17 00:00:00 2001$" patch2 >filtered &&
1445 test_cmp from filtered
1448 test_expect_success 'format-patch format.outputDirectory option' '
1449 test_config format.outputDirectory patches &&
1450 rm -fr patches &&
1451 git format-patch master..side &&
1452 test $(git rev-list master..side | wc -l) -eq $(ls patches | wc -l)
1455 test_expect_success 'format-patch -o overrides format.outputDirectory' '
1456 test_config format.outputDirectory patches &&
1457 rm -fr patches patchset &&
1458 git format-patch master..side -o patchset &&
1459 test_path_is_missing patches &&
1460 test_path_is_dir patchset
1463 test_expect_success 'format-patch --base' '
1464 git checkout side &&
1465 git format-patch --stdout --base=HEAD~3 -1 >patch &&
1466 grep "^base-commit:" patch >actual &&
1467 grep "^prerequisite-patch-id:" patch >>actual &&
1468 echo "base-commit: $(git rev-parse HEAD~3)" >expected &&
1469 echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1470 echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1471 test_cmp expected actual
1474 test_expect_success 'format-patch --base errors out when base commit is in revision list' '
1475 test_must_fail git format-patch --base=HEAD -2 &&
1476 test_must_fail git format-patch --base=HEAD~1 -2 &&
1477 git format-patch --stdout --base=HEAD~2 -2 >patch &&
1478 grep "^base-commit:" patch >actual &&
1479 echo "base-commit: $(git rev-parse HEAD~2)" >expected &&
1480 test_cmp expected actual
1483 test_expect_success 'format-patch --base errors out when base commit is not ancestor of revision list' '
1484 # For history as below:
1486 # ---Q---P---Z---Y---*---X
1487 # \ /
1488 # ------------W
1490 # If "format-patch Z..X" is given, P and Z can not be specified as the base commit
1491 git checkout -b topic1 master &&
1492 git rev-parse HEAD >commit-id-base &&
1493 test_commit P &&
1494 git rev-parse HEAD >commit-id-P &&
1495 test_commit Z &&
1496 git rev-parse HEAD >commit-id-Z &&
1497 test_commit Y &&
1498 git checkout -b topic2 master &&
1499 test_commit W &&
1500 git merge topic1 &&
1501 test_commit X &&
1502 test_must_fail git format-patch --base=$(cat commit-id-P) -3 &&
1503 test_must_fail git format-patch --base=$(cat commit-id-Z) -3 &&
1504 git format-patch --stdout --base=$(cat commit-id-base) -3 >patch &&
1505 grep "^base-commit:" patch >actual &&
1506 echo "base-commit: $(cat commit-id-base)" >expected &&
1507 test_cmp expected actual
1510 test_expect_success 'format-patch --base=auto' '
1511 git checkout -b upstream master &&
1512 git checkout -b local upstream &&
1513 git branch --set-upstream-to=upstream &&
1514 test_commit N1 &&
1515 test_commit N2 &&
1516 git format-patch --stdout --base=auto -2 >patch &&
1517 grep "^base-commit:" patch >actual &&
1518 echo "base-commit: $(git rev-parse upstream)" >expected &&
1519 test_cmp expected actual
1522 test_expect_success 'format-patch errors out when history involves criss-cross' '
1523 # setup criss-cross history
1525 # B---M1---D
1526 # / \ /
1527 # A X
1528 # \ / \
1529 # C---M2---E
1531 git checkout master &&
1532 test_commit A &&
1533 git checkout -b xb master &&
1534 test_commit B &&
1535 git checkout -b xc master &&
1536 test_commit C &&
1537 git checkout -b xbc xb -- &&
1538 git merge xc &&
1539 git checkout -b xcb xc -- &&
1540 git branch --set-upstream-to=xbc &&
1541 git merge xb &&
1542 git checkout xbc &&
1543 test_commit D &&
1544 git checkout xcb &&
1545 test_commit E &&
1546 test_must_fail git format-patch --base=auto -1
1549 test_expect_success 'format-patch format.useAutoBaseoption' '
1550 test_when_finished "git config --unset format.useAutoBase" &&
1551 git checkout local &&
1552 git config format.useAutoBase true &&
1553 git format-patch --stdout -1 >patch &&
1554 grep "^base-commit:" patch >actual &&
1555 echo "base-commit: $(git rev-parse upstream)" >expected &&
1556 test_cmp expected actual
1559 test_expect_success 'format-patch --base overrides format.useAutoBase' '
1560 test_when_finished "git config --unset format.useAutoBase" &&
1561 git config format.useAutoBase true &&
1562 git format-patch --stdout --base=HEAD~1 -1 >patch &&
1563 grep "^base-commit:" patch >actual &&
1564 echo "base-commit: $(git rev-parse HEAD~1)" >expected &&
1565 test_cmp expected actual
1568 test_done