3 # Copyright (c) 2006 Junio C Hamano
6 test_description
='various format-patch tests'
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 &&
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 &&
23 git commit -m "Side changes #1" &&
25 for i in D E F; do echo "$i"; done >>file &&
26 git update-index file &&
28 git commit -m "Side changes #2" &&
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 &&
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 &&
39 git commit -m "Master accepts moral equivalent of #2" &&
42 git checkout -b patchid &&
43 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file2 &&
44 for i in 1 2 3 A 4 B C 7 8 9 10 D E F 5 6; do echo "$i"; done >file3 &&
45 for i in 8 9 10; do echo "$i"; done >file &&
46 git add file file2 file3 &&
48 git commit -m "patchid 1" &&
49 for i in 4 A B 7 8 9 10; do echo "$i"; done >file2 &&
50 for i in 8 9 10 5 6; do echo "$i"; done >file3 &&
51 git add file2 file3 &&
53 git commit -m "patchid 2" &&
54 for i in 10 5 6; do echo "$i"; done >file &&
57 git commit -m "patchid 3" &&
62 test_expect_success
"format-patch --ignore-if-in-upstream" '
64 git format-patch --stdout master..side >patch0 &&
65 cnt=$(grep "^From " patch0 | wc -l) &&
70 test_expect_success
"format-patch --ignore-if-in-upstream" '
72 git format-patch --stdout \
73 --ignore-if-in-upstream master..side >patch1 &&
74 cnt=$(grep "^From " patch1 | wc -l) &&
79 test_expect_success
"format-patch --ignore-if-in-upstream handles tags" '
80 git tag -a v1 -m tag side &&
81 git tag -a v2 -m tag master &&
82 git format-patch --stdout --ignore-if-in-upstream v2..v1 >patch1 &&
83 cnt=$(grep "^From " patch1 | wc -l) &&
87 test_expect_success
"format-patch doesn't consider merge commits" '
89 git checkout -b slave master &&
90 echo "Another line" >>file &&
92 git commit -am "Slave change #1" &&
93 echo "Yet another line" >>file &&
95 git commit -am "Slave change #2" &&
96 git checkout -b merger master &&
98 git merge --no-ff slave &&
99 cnt=$(git format-patch -3 --stdout | grep "^From " | wc -l) &&
103 test_expect_success
"format-patch result applies" '
105 git checkout -b rebuild-0 master &&
107 cnt=$(git rev-list master.. | wc -l) &&
111 test_expect_success
"format-patch --ignore-if-in-upstream result applies" '
113 git checkout -b rebuild-1 master &&
115 cnt=$(git rev-list master.. | wc -l) &&
119 test_expect_success
'commit did not screw up the log message' '
121 git cat-file commit side | grep "^Side .* with .* backslash-n"
125 test_expect_success
'format-patch did not screw up the log message' '
127 grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
128 grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
132 test_expect_success
'replay did not screw up the log message' '
134 git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
138 test_expect_success
'extra headers' '
140 git config format.headers "To: R E Cipient <rcipient@example.com>
142 git config --add format.headers "Cc: S E Cipient <scipient@example.com>
144 git format-patch --stdout master..side > patch2 &&
145 sed -e "/^\$/q" patch2 > hdrs2 &&
146 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs2 &&
147 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs2
151 test_expect_success
'extra headers without newlines' '
153 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
154 git config --add format.headers "Cc: S E Cipient <scipient@example.com>" &&
155 git format-patch --stdout master..side >patch3 &&
156 sed -e "/^\$/q" patch3 > hdrs3 &&
157 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs3 &&
158 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs3
162 test_expect_success
'extra headers with multiple To:s' '
164 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
165 git config --add format.headers "To: S E Cipient <scipient@example.com>" &&
166 git format-patch --stdout master..side > patch4 &&
167 sed -e "/^\$/q" patch4 > hdrs4 &&
168 grep "^To: R E Cipient <rcipient@example.com>,\$" hdrs4 &&
169 grep "^ *S E Cipient <scipient@example.com>\$" hdrs4
172 test_expect_success
'additional command line cc (ascii)' '
174 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
175 git format-patch --cc="S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
176 grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
177 grep "^ *S E Cipient <scipient@example.com>\$" patch5
180 test_expect_failure
'additional command line cc (rfc822)' '
182 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
183 git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
184 grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
185 grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" patch5
188 test_expect_success
'command line headers' '
190 git config --unset-all format.headers &&
191 git format-patch --add-header="Cc: R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 &&
192 grep "^Cc: R E Cipient <rcipient@example.com>\$" patch6
195 test_expect_success
'configuration headers and command line headers' '
197 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
198 git format-patch --add-header="Cc: S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 &&
199 grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch7 &&
200 grep "^ *S E Cipient <scipient@example.com>\$" patch7
203 test_expect_success
'command line To: header (ascii)' '
205 git config --unset-all format.headers &&
206 git format-patch --to="R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
207 grep "^To: R E Cipient <rcipient@example.com>\$" patch8
210 test_expect_failure
'command line To: header (rfc822)' '
212 git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
213 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch8
216 test_expect_failure
'command line To: header (rfc2047)' '
218 git format-patch --to="R Ä Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
219 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch8
222 test_expect_success
'configuration To: header (ascii)' '
224 git config format.to "R E Cipient <rcipient@example.com>" &&
225 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
226 grep "^To: R E Cipient <rcipient@example.com>\$" patch9
229 test_expect_failure
'configuration To: header (rfc822)' '
231 git config format.to "R. E. Cipient <rcipient@example.com>" &&
232 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
233 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch9
236 test_expect_failure
'configuration To: header (rfc2047)' '
238 git config format.to "R Ä Cipient <rcipient@example.com>" &&
239 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
240 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch9
243 # check_patch <patch>: Verify that <patch> looks like a half-sane
244 # patch email to avoid a false positive with !grep
246 grep -e "^From:" "$1" &&
247 grep -e "^Date:" "$1" &&
248 grep -e "^Subject:" "$1"
251 test_expect_success
'format.from=false' '
253 git -c format.from=false format-patch --stdout master..side |
254 sed -e "/^\$/q" >patch &&
256 ! grep "^From: C O Mitter <committer@example.com>\$" patch
259 test_expect_success
'format.from=true' '
261 git -c format.from=true format-patch --stdout master..side |
262 sed -e "/^\$/q" >patch &&
264 grep "^From: C O Mitter <committer@example.com>\$" patch
267 test_expect_success
'format.from with address' '
269 git -c format.from="F R Om <from@example.com>" format-patch --stdout master..side |
270 sed -e "/^\$/q" >patch &&
272 grep "^From: F R Om <from@example.com>\$" patch
275 test_expect_success
'--no-from overrides format.from' '
277 git -c format.from="F R Om <from@example.com>" format-patch --no-from --stdout master..side |
278 sed -e "/^\$/q" >patch &&
280 ! grep "^From: F R Om <from@example.com>\$" patch
283 test_expect_success
'--from overrides format.from' '
285 git -c format.from="F R Om <from@example.com>" format-patch --from --stdout master..side |
286 sed -e "/^\$/q" >patch &&
288 ! grep "^From: F R Om <from@example.com>\$" patch
291 test_expect_success
'--no-to overrides config.to' '
293 git config --replace-all format.to \
294 "R E Cipient <rcipient@example.com>" &&
295 git format-patch --no-to --stdout master..side |
296 sed -e "/^\$/q" >patch10 &&
297 check_patch patch10 &&
298 ! grep "^To: R E Cipient <rcipient@example.com>\$" patch10
301 test_expect_success
'--no-to and --to replaces config.to' '
303 git config --replace-all format.to \
304 "Someone <someone@out.there>" &&
305 git format-patch --no-to --to="Someone Else <else@out.there>" \
306 --stdout master..side |
307 sed -e "/^\$/q" >patch11 &&
308 check_patch patch11 &&
309 ! grep "^To: Someone <someone@out.there>\$" patch11 &&
310 grep "^To: Someone Else <else@out.there>\$" patch11
313 test_expect_success
'--no-cc overrides config.cc' '
315 git config --replace-all format.cc \
316 "C E Cipient <rcipient@example.com>" &&
317 git format-patch --no-cc --stdout master..side |
318 sed -e "/^\$/q" >patch12 &&
319 check_patch patch12 &&
320 ! grep "^Cc: C E Cipient <rcipient@example.com>\$" patch12
323 test_expect_success
'--no-add-header overrides config.headers' '
325 git config --replace-all format.headers \
326 "Header1: B E Cipient <rcipient@example.com>" &&
327 git format-patch --no-add-header --stdout master..side |
328 sed -e "/^\$/q" >patch13 &&
329 check_patch patch13 &&
330 ! grep "^Header1: B E Cipient <rcipient@example.com>\$" patch13
333 test_expect_success
'multiple files' '
337 git format-patch -o patches/ master &&
338 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
341 test_expect_success
'reroll count' '
343 git format-patch -o patches --cover-letter --reroll-count 4 master..side >list &&
344 ! grep -v "^patches/v4-000[0-3]-" list &&
345 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
346 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
349 test_expect_success
'reroll count (-v)' '
351 git format-patch -o patches --cover-letter -v4 master..side >list &&
352 ! grep -v "^patches/v4-000[0-3]-" list &&
353 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
354 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
360 (git format-patch
--stdout "$@"; echo $?
> status.out
) |
361 # Prints everything between the Message-ID and In-Reply-To,
362 # and replaces all Message-ID-lookalikes by a sequence number
364 if (/^(message-id|references|in-reply-to)/i) {
370 $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
371 for $k (keys %h) {s/$k/$h{$k}/};
374 print "---\n" if /^From /i;
376 test 0 = "$(cat status.out)" &&
377 test_cmp
"$expect" actual
380 cat >> expect.no-threading
<<EOF
386 test_expect_success
'no threading' '
388 check_threading expect.no-threading master
391 cat > expect.thread
<<EOF
404 test_expect_success
'thread' '
405 check_threading expect.thread --thread master
408 cat > expect.in-reply-to
<<EOF
423 test_expect_success
'thread in-reply-to' '
424 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
428 cat > expect.cover-letter
<<EOF
445 test_expect_success
'thread cover-letter' '
446 check_threading expect.cover-letter --cover-letter --thread master
449 cat > expect.cl-irt
<<EOF
471 test_expect_success
'thread cover-letter in-reply-to' '
472 check_threading expect.cl-irt --cover-letter \
473 --in-reply-to="<test.message>" --thread master
476 test_expect_success
'thread explicit shallow' '
477 check_threading expect.cl-irt --cover-letter \
478 --in-reply-to="<test.message>" --thread=shallow master
481 cat > expect.deep
<<EOF
495 test_expect_success
'thread deep' '
496 check_threading expect.deep --thread=deep master
499 cat > expect.deep-irt
<<EOF
517 test_expect_success
'thread deep in-reply-to' '
518 check_threading expect.deep-irt --thread=deep \
519 --in-reply-to="<test.message>" master
522 cat > expect.deep-cl
<<EOF
542 test_expect_success
'thread deep cover-letter' '
543 check_threading expect.deep-cl --cover-letter --thread=deep master
546 cat > expect.deep-cl-irt
<<EOF
571 test_expect_success
'thread deep cover-letter in-reply-to' '
572 check_threading expect.deep-cl-irt --cover-letter \
573 --in-reply-to="<test.message>" --thread=deep master
576 test_expect_success
'thread via config' '
577 test_config format.thread true &&
578 check_threading expect.thread master
581 test_expect_success
'thread deep via config' '
582 test_config format.thread deep &&
583 check_threading expect.deep master
586 test_expect_success
'thread config + override' '
587 test_config format.thread deep &&
588 check_threading expect.thread --thread master
591 test_expect_success
'thread config + --no-thread' '
592 test_config format.thread deep &&
593 check_threading expect.no-threading --no-thread master
596 test_expect_success
'excessive subject' '
600 before=$(git hash-object file) &&
601 before=$(git rev-parse --short $before) &&
602 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
603 after=$(git hash-object file) &&
604 after=$(git rev-parse --short $after) &&
605 git update-index file &&
606 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." &&
607 git format-patch -o patches/ master..side &&
608 ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
611 test_expect_success
'failure to write cover-letter aborts gracefully' '
612 test_when_finished "rmdir 0000-cover-letter.patch" &&
613 mkdir 0000-cover-letter.patch &&
614 test_must_fail git format-patch --no-renames --cover-letter -1
617 test_expect_success
'cover-letter inherits diff options' '
620 git format-patch --no-renames --cover-letter -1 &&
621 check_patch 0000-cover-letter.patch &&
622 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
623 git format-patch --cover-letter -1 -M &&
624 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
629 This is an excessively long subject line for a message due to the
630 habit some projects have of not having a short, one-line subject at
631 the start of the commit message, but rather sticking a whole
632 paragraph right at the start as the only thing in the commit
633 message. It had better not become the filename for the patch.
638 test_expect_success
'shortlog of cover-letter wraps overly-long onelines' '
640 git format-patch --cover-letter -2 &&
641 sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
642 test_cmp expect output
647 index $before..$after 100644
658 test_expect_success
'format-patch respects -U' '
660 git format-patch -U4 -2 &&
661 sed -e "1,/^diff/d" -e "/^+5/q" \
662 <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
664 test_cmp expect output
670 diff --git a/file b/file
671 index $before..$after 100644
681 test_expect_success
'format-patch -p suppresses stat' '
683 git format-patch -p -2 &&
684 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
685 test_cmp expect output
689 test_expect_success
'format-patch from a subdirectory (1)' '
700 echo "Oops? $filename"
707 test_expect_success
'format-patch from a subdirectory (2)' '
712 git format-patch -1 -o ..
718 echo "Oops? $filename"
722 basename=$(expr "$filename" : ".*/\(.*\)") &&
723 test -f "sub/$basename"
726 test_expect_success
'format-patch from a subdirectory (3)' '
732 git format-patch -1 -o "$TRASH_DIRECTORY"
734 basename=$(expr "$filename" : ".*/\(.*\)") &&
738 test_expect_success
'format-patch --in-reply-to' '
739 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
740 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
741 grep "^References: <baz@foo.bar>" patch8
744 test_expect_success
'format-patch --signoff' '
745 git format-patch -1 --signoff --stdout >out &&
746 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
749 test_expect_success
'format-patch --notes --signoff' '
750 git notes --ref test add -m "test message" HEAD &&
751 git format-patch -1 --signoff --stdout --notes=test >out &&
752 # Three dashes must come after S-o-b
753 ! sed "/^Signed-off-by: /q" out | grep "test message" &&
754 sed "1,/^Signed-off-by: /d" out | grep "test message" &&
755 # Notes message must come after three dashes
756 ! sed "/^---$/q" out | grep "test message" &&
757 sed "1,/^---$/d" out | grep "test message"
760 echo "fatal: --name-only does not make sense" > expect.name-only
761 echo "fatal: --name-status does not make sense" > expect.name-status
762 echo "fatal: --check does not make sense" > expect.check
764 test_expect_success
'options no longer allowed for format-patch' '
765 test_must_fail git format-patch --name-only 2> output &&
766 test_i18ncmp expect.name-only output &&
767 test_must_fail git format-patch --name-status 2> output &&
768 test_i18ncmp expect.name-status output &&
769 test_must_fail git format-patch --check 2> output &&
770 test_i18ncmp expect.check output'
772 test_expect_success
'format-patch --numstat should produce a patch' '
773 git format-patch --numstat --stdout master..side > output &&
774 test 5 = $(grep "^diff --git a/" output | wc -l)'
776 test_expect_success
'format-patch -- <path>' '
777 git format-patch master..side -- file 2>error &&
778 ! grep "Use .--" error
781 test_expect_success
'format-patch --ignore-if-in-upstream HEAD' '
782 git format-patch --ignore-if-in-upstream HEAD
785 git_version
="$(git --version | sed "s
/.
* //")"
788 printf "%s\n%s\n\n" "-- " "${1:-$git_version}"
791 test_expect_success
'format-patch default signature' '
792 git format-patch --stdout -1 | tail -n 3 >output &&
794 test_cmp expect output
797 test_expect_success
'format-patch --signature' '
798 git format-patch --stdout --signature="my sig" -1 | tail -n 3 >output &&
799 signature "my sig" >expect &&
800 test_cmp expect output
803 test_expect_success
'format-patch with format.signature config' '
804 git config format.signature "config sig" &&
805 git format-patch --stdout -1 >output &&
806 grep "config sig" output
809 test_expect_success
'format-patch --signature overrides format.signature' '
810 git config format.signature "config sig" &&
811 git format-patch --stdout --signature="overrides" -1 >output &&
812 ! grep "config sig" output &&
813 grep "overrides" output
816 test_expect_success
'format-patch --no-signature ignores format.signature' '
817 git config format.signature "config sig" &&
818 git format-patch --stdout --signature="my sig" --no-signature \
820 check_patch output &&
821 ! grep "config sig" output &&
822 ! grep "my sig" output &&
823 ! grep "^-- \$" output
826 test_expect_success
'format-patch --signature --cover-letter' '
827 git config --unset-all format.signature &&
828 git format-patch --stdout --signature="my sig" --cover-letter \
830 grep "my sig" output &&
831 test 2 = $(grep "my sig" output | wc -l)
834 test_expect_success
'format.signature="" suppresses signatures' '
835 git config format.signature "" &&
836 git format-patch --stdout -1 >output &&
837 check_patch output &&
838 ! grep "^-- \$" output
841 test_expect_success
'format-patch --no-signature suppresses signatures' '
842 git config --unset-all format.signature &&
843 git format-patch --stdout --no-signature -1 >output &&
844 check_patch output &&
845 ! grep "^-- \$" output
848 test_expect_success
'format-patch --signature="" suppresses signatures' '
849 git format-patch --stdout --signature="" -1 >output &&
850 check_patch output &&
851 ! grep "^-- \$" output
854 test_expect_success
'prepare mail-signature input' '
855 cat >mail-signature <<-\EOF
857 Test User <test.email@kernel.org>
858 http://git.kernel.org/cgit/git/git.git
860 git.kernel.org/?p=git/git.git;a=summary
865 test_expect_success
'--signature-file=file works' '
866 git format-patch --stdout --signature-file=mail-signature -1 >output &&
867 check_patch output &&
868 sed -e "1,/^-- \$/d" <output >actual &&
870 cat mail-signature && echo
872 test_cmp expect actual
875 test_expect_success
'format.signaturefile works' '
876 test_config format.signaturefile mail-signature &&
877 git format-patch --stdout -1 >output &&
878 check_patch output &&
879 sed -e "1,/^-- \$/d" <output >actual &&
881 cat mail-signature && echo
883 test_cmp expect actual
886 test_expect_success
'--no-signature suppresses format.signaturefile ' '
887 test_config format.signaturefile mail-signature &&
888 git format-patch --stdout --no-signature -1 >output &&
889 check_patch output &&
890 ! grep "^-- \$" output
893 test_expect_success
'--signature-file overrides format.signaturefile' '
894 cat >other-mail-signature <<-\EOF &&
895 Use this other signature instead of mail-signature.
897 test_config format.signaturefile mail-signature &&
898 git format-patch --stdout \
899 --signature-file=other-mail-signature -1 >output &&
900 check_patch output &&
901 sed -e "1,/^-- \$/d" <output >actual &&
903 cat other-mail-signature && echo
905 test_cmp expect actual
908 test_expect_success
'--signature overrides format.signaturefile' '
909 test_config format.signaturefile mail-signature &&
910 git format-patch --stdout --signature="my sig" -1 >output &&
911 check_patch output &&
915 test_expect_success TTY
'format-patch --stdout paginates' '
917 test_terminal env GIT_PAGER="wc >pager_used" git format-patch --stdout --all &&
918 test_path_is_file pager_used
921 test_expect_success TTY
'format-patch --stdout pagination can be disabled' '
923 test_terminal env GIT_PAGER="wc >pager_used" git --no-pager format-patch --stdout --all &&
924 test_terminal env GIT_PAGER="wc >pager_used" git -c "pager.format-patch=false" format-patch --stdout --all &&
925 test_path_is_missing pager_used &&
926 test_path_is_missing .git/pager_used
929 test_expect_success
'format-patch handles multi-line subjects' '
931 echo content >>file &&
932 for i in one two three; do echo $i; done >msg &&
935 git format-patch -o patches -1 &&
936 grep ^Subject: patches/0001-one.patch >actual &&
937 echo "Subject: [PATCH] one two three" >expect &&
938 test_cmp expect actual
941 test_expect_success
'format-patch handles multi-line encoded subjects' '
943 echo content >>file &&
944 for i in en två tre; do echo $i; done >msg &&
947 git format-patch -o patches -1 &&
948 grep ^Subject: patches/0001-en.patch >actual &&
949 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
950 test_cmp expect actual
954 M64
=$M8$M8$M8$M8$M8$M8$M8$M8
955 M512
=$M64$M64$M64$M64$M64$M64$M64$M64
957 Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
958 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
959 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
960 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
961 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
962 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
963 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
965 test_expect_success
'format-patch wraps extremely long subject (ascii)' '
966 echo content >>file &&
968 git commit -m "$M512" &&
969 git format-patch --stdout -1 >patch &&
970 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
971 test_cmp expect subject
975 M64
=$M8$M8$M8$M8$M8$M8$M8$M8
976 M512
=$M64$M64$M64$M64$M64$M64$M64$M64
978 Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
979 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
980 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
981 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
982 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
983 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
984 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
985 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
986 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
987 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
988 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
989 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
990 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
991 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
992 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
993 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
994 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
995 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
996 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
997 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
998 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
999 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1000 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1003 test_expect_success
'format-patch wraps extremely long subject (rfc2047)' '
1005 echo content >>file &&
1007 git commit -m "$M512" &&
1008 git format-patch --stdout -1 >patch &&
1009 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
1010 test_cmp expect subject
1014 echo content
>>file &&
1016 GIT_AUTHOR_NAME
=$1 git commit
-m author-check
&&
1017 git format-patch
--stdout -1 >patch &&
1018 sed -n "/^From: /p; /^ /p; /^$/q" <patch >actual
&&
1019 test_cmp expect actual
1023 From: "Foo B. Bar" <author@example.com>
1025 test_expect_success
'format-patch quotes dot in from-headers' '
1026 check_author "Foo B. Bar"
1030 From: "Foo \"The Baz\" Bar" <author@example.com>
1032 test_expect_success
'format-patch quotes double-quote in from-headers' '
1033 check_author "Foo \"The Baz\" Bar"
1037 From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
1039 test_expect_success
'format-patch uses rfc2047-encoded from-headers when necessary' '
1040 check_author "Föo Bar"
1044 From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
1046 test_expect_success
'rfc2047-encoded from-headers leave no rfc822 specials' '
1047 check_author "Föo B. Bar"
1051 From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
1052 <author@example.com>
1054 test_expect_success
'format-patch wraps moderately long from-header (ascii)' '
1055 check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
1059 From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1060 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1061 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
1063 test_expect_success
'format-patch wraps extremely long from-header (ascii)' '
1064 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"
1068 From: "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1069 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1070 Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
1072 test_expect_success
'format-patch wraps extremely long from-header (rfc822)' '
1073 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"
1077 From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
1078 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
1079 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
1080 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
1081 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
1083 test_expect_success
'format-patch wraps extremely long from-header (rfc2047)' '
1084 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"
1088 Subject: header with . in it
1090 test_expect_success
'subject lines do not have 822 atom-quoting' '
1091 echo content >>file &&
1093 git commit -m "header with . in it" &&
1094 git format-patch -k -1 --stdout >patch &&
1095 grep ^Subject: patch >actual &&
1096 test_cmp expect actual
1100 Subject: [PREFIX 1/1] header with . in it
1102 test_expect_success
'subject prefixes have space prepended' '
1103 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
1104 grep ^Subject: patch >actual &&
1105 test_cmp expect actual
1109 Subject: [1/1] header with . in it
1111 test_expect_success
'empty subject prefix does not have extra space' '
1112 git format-patch -n -1 --stdout --subject-prefix= >patch &&
1113 grep ^Subject: patch >actual &&
1114 test_cmp expect actual
1117 test_expect_success
'--rfc' '
1118 cat >expect <<-\EOF &&
1119 Subject: [RFC PATCH 1/1] header with . in it
1121 git format-patch -n -1 --stdout --rfc >patch &&
1122 grep ^Subject: patch >actual &&
1123 test_cmp expect actual
1126 test_expect_success
'--from=ident notices bogus ident' '
1127 test_must_fail git format-patch -1 --stdout --from=foo >patch
1130 test_expect_success
'--from=ident replaces author' '
1131 git format-patch -1 --stdout --from="Me <me@example.com>" >patch &&
1132 cat >expect <<-\EOF &&
1133 From: Me <me@example.com>
1135 From: A U Thor <author@example.com>
1138 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1139 test_cmp expect patch.head
1142 test_expect_success
'--from uses committer ident' '
1143 git format-patch -1 --stdout --from >patch &&
1144 cat >expect <<-\EOF &&
1145 From: C O Mitter <committer@example.com>
1147 From: A U Thor <author@example.com>
1150 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1151 test_cmp expect patch.head
1154 test_expect_success
'--from omits redundant in-body header' '
1155 git format-patch -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1156 cat >expect <<-\EOF &&
1157 From: A U Thor <author@example.com>
1160 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1161 test_cmp expect patch.head
1164 test_expect_success
'in-body headers trigger content encoding' '
1165 test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
1166 test_when_finished "git reset --hard HEAD^" &&
1167 git format-patch -1 --stdout --from >patch &&
1168 cat >expect <<-\EOF &&
1169 From: C O Mitter <committer@example.com>
1170 Content-Type: text/plain; charset=UTF-8
1172 From: éxötìc <author@example.com>
1175 sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" <patch >patch.head &&
1176 test_cmp expect patch.head
1181 C
=$
(git commit-tree HEAD^^
{tree
} -p HEAD
) &&
1182 git format-patch
--stdout --signoff $C^..
$C >append_signoff.
patch &&
1183 sed -n -e "1,/^---$/p" append_signoff.
patch |
1184 egrep -n "^Subject|Sign|^$"
1187 test_expect_success
'signoff: commit with no body' '
1188 append_signoff </dev/null >actual &&
1189 cat <<\EOF | sed "s/EOL$//" >expected &&
1190 4:Subject: [PATCH] EOL
1192 9:Signed-off-by: C O Mitter <committer@example.com>
1194 test_cmp expected actual
1197 test_expect_success
'signoff: commit with only subject' '
1198 echo subject | append_signoff >actual &&
1199 cat >expected <<\EOF &&
1200 4:Subject: [PATCH] subject
1202 9:Signed-off-by: C O Mitter <committer@example.com>
1204 test_cmp expected actual
1207 test_expect_success
'signoff: commit with only subject that does not end with NL' '
1208 printf subject | append_signoff >actual &&
1209 cat >expected <<\EOF &&
1210 4:Subject: [PATCH] subject
1212 9:Signed-off-by: C O Mitter <committer@example.com>
1214 test_cmp expected actual
1217 test_expect_success
'signoff: no existing signoffs' '
1218 append_signoff <<\EOF >actual &&
1223 cat >expected <<\EOF &&
1224 4:Subject: [PATCH] subject
1227 11:Signed-off-by: C O Mitter <committer@example.com>
1229 test_cmp expected actual
1232 test_expect_success
'signoff: no existing signoffs and no trailing NL' '
1233 printf "subject\n\nbody" | append_signoff >actual &&
1234 cat >expected <<\EOF &&
1235 4:Subject: [PATCH] subject
1238 11:Signed-off-by: C O Mitter <committer@example.com>
1240 test_cmp expected actual
1243 test_expect_success
'signoff: some random signoff' '
1244 append_signoff <<\EOF >actual &&
1249 Signed-off-by: my@house
1251 cat >expected <<\EOF &&
1252 4:Subject: [PATCH] subject
1255 11:Signed-off-by: my@house
1256 12:Signed-off-by: C O Mitter <committer@example.com>
1258 test_cmp expected actual
1261 test_expect_success
'signoff: misc conforming footer elements' '
1262 append_signoff <<\EOF >actual &&
1267 Signed-off-by: my@house
1268 (cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1269 Tested-by: Some One <someone@example.com>
1272 cat >expected <<\EOF &&
1273 4:Subject: [PATCH] subject
1276 11:Signed-off-by: my@house
1277 15:Signed-off-by: C O Mitter <committer@example.com>
1279 test_cmp expected actual
1282 test_expect_success
'signoff: some random signoff-alike' '
1283 append_signoff <<\EOF >actual &&
1287 Fooled-by-me: my@house
1289 cat >expected <<\EOF &&
1290 4:Subject: [PATCH] subject
1293 12:Signed-off-by: C O Mitter <committer@example.com>
1295 test_cmp expected actual
1298 test_expect_success
'signoff: not really a signoff' '
1299 append_signoff <<\EOF >actual &&
1302 I want to mention about Signed-off-by: here.
1304 cat >expected <<\EOF &&
1305 4:Subject: [PATCH] subject
1307 9:I want to mention about Signed-off-by: here.
1309 11:Signed-off-by: C O Mitter <committer@example.com>
1311 test_cmp expected actual
1314 test_expect_success
'signoff: not really a signoff (2)' '
1315 append_signoff <<\EOF >actual &&
1319 Signed-off-by: example happens to be wrapped here.
1321 cat >expected <<\EOF &&
1322 4:Subject: [PATCH] subject
1324 10:Signed-off-by: example happens to be wrapped here.
1325 11:Signed-off-by: C O Mitter <committer@example.com>
1327 test_cmp expected actual
1330 test_expect_success
'signoff: valid S-o-b paragraph in the middle' '
1331 append_signoff <<\EOF >actual &&
1334 Signed-off-by: my@house
1335 Signed-off-by: your@house
1339 cat >expected <<\EOF &&
1340 4:Subject: [PATCH] subject
1342 9:Signed-off-by: my@house
1343 10:Signed-off-by: your@house
1346 14:Signed-off-by: C O Mitter <committer@example.com>
1348 test_cmp expected actual
1351 test_expect_success
'signoff: the same signoff at the end' '
1352 append_signoff <<\EOF >actual &&
1357 Signed-off-by: C O Mitter <committer@example.com>
1359 cat >expected <<\EOF &&
1360 4:Subject: [PATCH] subject
1363 11:Signed-off-by: C O Mitter <committer@example.com>
1365 test_cmp expected actual
1368 test_expect_success
'signoff: the same signoff at the end, no trailing NL' '
1369 printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
1370 append_signoff >actual &&
1371 cat >expected <<\EOF &&
1372 4:Subject: [PATCH] subject
1374 9:Signed-off-by: C O Mitter <committer@example.com>
1376 test_cmp expected actual
1379 test_expect_success
'signoff: the same signoff NOT at the end' '
1380 append_signoff <<\EOF >actual &&
1385 Signed-off-by: C O Mitter <committer@example.com>
1386 Signed-off-by: my@house
1388 cat >expected <<\EOF &&
1389 4:Subject: [PATCH] subject
1392 11:Signed-off-by: C O Mitter <committer@example.com>
1393 12:Signed-off-by: my@house
1395 test_cmp expected actual
1398 test_expect_success
'signoff: tolerate garbage in conforming footer' '
1399 append_signoff <<\EOF >actual &&
1406 Signed-off-by: C O Mitter <committer@example.com>
1408 cat >expected <<\EOF &&
1409 4:Subject: [PATCH] subject
1412 13:Signed-off-by: C O Mitter <committer@example.com>
1414 test_cmp expected actual
1417 test_expect_success
'signoff: respect trailer config' '
1418 append_signoff <<\EOF >actual &&
1424 cat >expected <<\EOF &&
1425 4:Subject: [PATCH] subject
1428 12:Signed-off-by: C O Mitter <committer@example.com>
1430 test_cmp expected actual &&
1432 test_config trailer.Myfooter.ifexists add &&
1433 append_signoff <<\EOF >actual &&
1439 cat >expected <<\EOF &&
1440 4:Subject: [PATCH] subject
1442 11:Signed-off-by: C O Mitter <committer@example.com>
1444 test_cmp expected actual
1447 test_expect_success
'signoff: footer begins with non-signoff without @ sign' '
1448 append_signoff <<\EOF >actual &&
1455 Change-id: Ideadbeef
1456 Signed-off-by: C O Mitter <committer@example.com>
1459 cat >expected <<\EOF &&
1460 4:Subject: [PATCH] subject
1463 14:Signed-off-by: C O Mitter <committer@example.com>
1465 test_cmp expected actual
1468 test_expect_success
'format patch ignores color.ui' '
1469 test_unconfig color.ui &&
1470 git format-patch --stdout -1 >expect &&
1471 test_config color.ui always &&
1472 git format-patch --stdout -1 >actual &&
1473 test_cmp expect actual
1476 test_expect_success
'cover letter using branch description (1)' '
1477 git checkout rebuild-1 &&
1478 test_config branch.rebuild-1.description hello &&
1479 git format-patch --stdout --cover-letter master >actual &&
1480 grep hello actual >/dev/null
1483 test_expect_success
'cover letter using branch description (2)' '
1484 git checkout rebuild-1 &&
1485 test_config branch.rebuild-1.description hello &&
1486 git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
1487 grep hello actual >/dev/null
1490 test_expect_success
'cover letter using branch description (3)' '
1491 git checkout rebuild-1 &&
1492 test_config branch.rebuild-1.description hello &&
1493 git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
1494 grep hello actual >/dev/null
1497 test_expect_success
'cover letter using branch description (4)' '
1498 git checkout rebuild-1 &&
1499 test_config branch.rebuild-1.description hello &&
1500 git format-patch --stdout --cover-letter master.. >actual &&
1501 grep hello actual >/dev/null
1504 test_expect_success
'cover letter using branch description (5)' '
1505 git checkout rebuild-1 &&
1506 test_config branch.rebuild-1.description hello &&
1507 git format-patch --stdout --cover-letter -2 HEAD >actual &&
1508 grep hello actual >/dev/null
1511 test_expect_success
'cover letter using branch description (6)' '
1512 git checkout rebuild-1 &&
1513 test_config branch.rebuild-1.description hello &&
1514 git format-patch --stdout --cover-letter -2 >actual &&
1515 grep hello actual >/dev/null
1518 test_expect_success
'cover letter with nothing' '
1519 git format-patch --stdout --cover-letter >actual &&
1520 test_line_count = 0 actual
1523 test_expect_success
'cover letter auto' '
1525 test_when_finished "rm -rf tmp;
1526 git config --unset format.coverletter" &&
1528 git config format.coverletter auto &&
1529 git format-patch -o tmp -1 >list &&
1530 test_line_count = 1 list &&
1531 git format-patch -o tmp -2 >list &&
1532 test_line_count = 3 list
1535 test_expect_success
'cover letter auto user override' '
1537 test_when_finished "rm -rf tmp;
1538 git config --unset format.coverletter" &&
1540 git config format.coverletter auto &&
1541 git format-patch -o tmp --cover-letter -1 >list &&
1542 test_line_count = 2 list &&
1543 git format-patch -o tmp --cover-letter -2 >list &&
1544 test_line_count = 3 list &&
1545 git format-patch -o tmp --no-cover-letter -1 >list &&
1546 test_line_count = 1 list &&
1547 git format-patch -o tmp --no-cover-letter -2 >list &&
1548 test_line_count = 2 list
1551 test_expect_success
'format-patch --zero-commit' '
1552 git format-patch --zero-commit --stdout v2..v1 >patch2 &&
1553 grep "^From " patch2 | sort | uniq >actual &&
1554 echo "From $ZERO_OID Mon Sep 17 00:00:00 2001" >expect &&
1555 test_cmp expect actual
1558 test_expect_success
'From line has expected format' '
1559 git format-patch --stdout v2..v1 >patch2 &&
1560 grep "^From " patch2 >from &&
1561 grep "^From $OID_REGEX Mon Sep 17 00:00:00 2001$" patch2 >filtered &&
1562 test_cmp from filtered
1565 test_expect_success
'format-patch format.outputDirectory option' '
1566 test_config format.outputDirectory patches &&
1568 git format-patch master..side &&
1569 test $(git rev-list master..side | wc -l) -eq $(ls patches | wc -l)
1572 test_expect_success
'format-patch -o overrides format.outputDirectory' '
1573 test_config format.outputDirectory patches &&
1574 rm -fr patches patchset &&
1575 git format-patch master..side -o patchset &&
1576 test_path_is_missing patches &&
1577 test_path_is_dir patchset
1580 test_expect_success
'format-patch --base' '
1581 git checkout patchid &&
1582 git format-patch --stdout --base=HEAD~3 -1 | tail -n 7 >actual1 &&
1583 git format-patch --stdout --base=HEAD~3 HEAD~.. | tail -n 7 >actual2 &&
1585 echo "base-commit: $(git rev-parse HEAD~3)" >>expected &&
1586 echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1587 echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1588 signature >> expected &&
1589 test_cmp expected actual1 &&
1590 test_cmp expected actual2 &&
1592 echo "base-commit: $(git rev-parse HEAD~3)" >>fail &&
1593 echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --unstable | awk "{print \$1}")" >>fail &&
1594 echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --unstable | awk "{print \$1}")" >>fail &&
1595 signature >> fail &&
1596 ! test_cmp fail actual1 &&
1597 ! test_cmp fail actual2
1600 test_expect_success
'format-patch --base errors out when base commit is in revision list' '
1601 test_must_fail git format-patch --base=HEAD -2 &&
1602 test_must_fail git format-patch --base=HEAD~1 -2 &&
1603 git format-patch --stdout --base=HEAD~2 -2 >patch &&
1604 grep "^base-commit:" patch >actual &&
1605 echo "base-commit: $(git rev-parse HEAD~2)" >expected &&
1606 test_cmp expected actual
1609 test_expect_success
'format-patch --base errors out when base commit is not ancestor of revision list' '
1610 # For history as below:
1612 # ---Q---P---Z---Y---*---X
1616 # If "format-patch Z..X" is given, P and Z can not be specified as the base commit
1617 git checkout -b topic1 master &&
1618 git rev-parse HEAD >commit-id-base &&
1620 git rev-parse HEAD >commit-id-P &&
1622 git rev-parse HEAD >commit-id-Z &&
1624 git checkout -b topic2 master &&
1628 test_must_fail git format-patch --base=$(cat commit-id-P) -3 &&
1629 test_must_fail git format-patch --base=$(cat commit-id-Z) -3 &&
1630 git format-patch --stdout --base=$(cat commit-id-base) -3 >patch &&
1631 grep "^base-commit:" patch >actual &&
1632 echo "base-commit: $(cat commit-id-base)" >expected &&
1633 test_cmp expected actual
1636 test_expect_success
'format-patch --base=auto' '
1637 git checkout -b upstream master &&
1638 git checkout -b local upstream &&
1639 git branch --set-upstream-to=upstream &&
1642 git format-patch --stdout --base=auto -2 >patch &&
1643 grep "^base-commit:" patch >actual &&
1644 echo "base-commit: $(git rev-parse upstream)" >expected &&
1645 test_cmp expected actual
1648 test_expect_success
'format-patch errors out when history involves criss-cross' '
1649 # setup criss-cross history
1657 git checkout master &&
1659 git checkout -b xb master &&
1661 git checkout -b xc master &&
1663 git checkout -b xbc xb -- &&
1665 git checkout -b xcb xc -- &&
1666 git branch --set-upstream-to=xbc &&
1672 test_must_fail git format-patch --base=auto -1
1675 test_expect_success
'format-patch format.useAutoBaseoption' '
1676 test_when_finished "git config --unset format.useAutoBase" &&
1677 git checkout local &&
1678 git config format.useAutoBase true &&
1679 git format-patch --stdout -1 >patch &&
1680 grep "^base-commit:" patch >actual &&
1681 echo "base-commit: $(git rev-parse upstream)" >expected &&
1682 test_cmp expected actual
1685 test_expect_success
'format-patch --base overrides format.useAutoBase' '
1686 test_when_finished "git config --unset format.useAutoBase" &&
1687 git config format.useAutoBase true &&
1688 git format-patch --stdout --base=HEAD~1 -1 >patch &&
1689 grep "^base-commit:" patch >actual &&
1690 echo "base-commit: $(git rev-parse HEAD~1)" >expected &&
1691 test_cmp expected actual
1694 test_expect_success
'format-patch --base with --attach' '
1695 git format-patch --attach=mimemime --stdout --base=HEAD~ -1 >patch &&
1696 sed -n -e "/^base-commit:/s/.*/1/p" -e "/^---*mimemime--$/s/.*/2/p" \
1698 test_write_lines 1 2 >expect &&
1699 test_cmp expect actual
1701 test_expect_success
'format-patch --attach cover-letter only is non-multipart' '
1702 test_when_finished "rm -fr patches" &&
1703 git format-patch -o patches --cover-letter --attach=mimemime --base=HEAD~ -1 &&
1704 ! egrep "^--+mimemime" patches/0000*.patch &&
1705 egrep "^--+mimemime$" patches/0001*.patch >output &&
1706 test_line_count = 2 output &&
1707 egrep "^--+mimemime--$" patches/0001*.patch >output &&
1708 test_line_count = 1 output
1711 test_expect_success
'format-patch --pretty=mboxrd' '
1713 cat >msg <<-INPUT_END &&
1714 mboxrd should escape the body
1716 From could trip up a loose mbox parser
1717 >From extra escape for reversibility
1718 >>From extra escape for reversibility 2
1719 from lower case not escaped
1720 Fromm bad speling not escaped
1721 From with leading space not escaped
1730 cat >expect <<-INPUT_END &&
1731 >From could trip up a loose mbox parser
1732 >>From extra escape for reversibility
1733 >>>From extra escape for reversibility 2
1734 from lower case not escaped
1735 Fromm bad speling not escaped
1736 From with leading space not escaped
1745 C=$(git commit-tree HEAD^^{tree} -p HEAD <msg) &&
1746 git format-patch --pretty=mboxrd --stdout -1 $C~1..$C >patch &&
1747 git grep -h --no-index -A11 \
1748 "^>From could trip up a loose mbox parser" patch >actual &&
1749 test_cmp expect actual
1752 test_expect_success
'interdiff: setup' '
1753 git checkout -b boop master &&
1754 test_commit fnorp blorp &&
1755 test_commit fleep blorp
1758 test_expect_success
'interdiff: cover-letter' '
1759 sed "y/q/ /" >expect <<-\EOF &&
1763 git format-patch --cover-letter --interdiff=boop~2 -1 boop &&
1764 test_i18ngrep "^Interdiff:$" 0000-cover-letter.patch &&
1765 test_i18ngrep ! "^Interdiff:$" 0001-fleep.patch &&
1766 sed "1,/^@@ /d; /^-- $/q" <0000-cover-letter.patch >actual &&
1767 test_cmp expect actual
1770 test_expect_success
'interdiff: reroll-count' '
1771 git format-patch --cover-letter --interdiff=boop~2 -v2 -1 boop &&
1772 test_i18ngrep "^Interdiff ..* v1:$" v2-0000-cover-letter.patch
1775 test_expect_success
'interdiff: solo-patch' '
1776 cat >expect <<-\EOF &&
1780 git format-patch --interdiff=boop~2 -1 boop &&
1781 test_i18ngrep "^Interdiff:$" 0001-fleep.patch &&
1782 sed "1,/^ @@ /d; /^$/q" <0001-fleep.patch >actual &&
1783 test_cmp expect actual