3 # Copyright (c) 2006 Junio C Hamano
6 test_description
='various format-patch tests'
8 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
=main
9 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
12 .
"$TEST_DIRECTORY"/lib-terminal.sh
14 test_expect_success setup
'
15 for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i"; done >file &&
19 git commit -m Initial &&
20 git checkout -b side &&
22 for i in 1 2 5 6 A B C 7 8 9 10; do echo "$i"; done >file &&
25 git commit -m "Side changes #1" &&
27 for i in D E F; do echo "$i"; done >>file &&
28 git update-index file &&
30 git commit -m "Side changes #2" &&
33 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file &&
34 git update-index file &&
36 git commit -m "Side changes #3 with \\n backslash-n in it." &&
39 git diff-tree -p C2 >patch &&
40 git apply --index <patch &&
42 git commit -m "Main accepts moral equivalent of #2" &&
45 git checkout -b patchid &&
46 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file2 &&
47 for i in 1 2 3 A 4 B C 7 8 9 10 D E F 5 6; do echo "$i"; done >file3 &&
48 for i in 8 9 10; do echo "$i"; done >file &&
49 git add file file2 file3 &&
51 git commit -m "patchid 1" &&
52 for i in 4 A B 7 8 9 10; do echo "$i"; done >file2 &&
53 for i in 8 9 10 5 6; do echo "$i"; done >file3 &&
54 git add file2 file3 &&
56 git commit -m "patchid 2" &&
57 for i in 10 5 6; do echo "$i"; done >file &&
60 git commit -m "patchid 3" &&
65 test_expect_success
'format-patch --ignore-if-in-upstream' '
66 git format-patch --stdout main..side >patch0 &&
67 grep "^From " patch0 >from0 &&
68 test_line_count = 3 from0
71 test_expect_success
'format-patch --ignore-if-in-upstream' '
72 git format-patch --stdout \
73 --ignore-if-in-upstream main..side >patch1 &&
74 grep "^From " patch1 >from1 &&
75 test_line_count = 2 from1
78 test_expect_success
'format-patch --ignore-if-in-upstream handles tags' '
79 git tag -a v1 -m tag side &&
80 git tag -a v2 -m tag main &&
81 git format-patch --stdout --ignore-if-in-upstream v2..v1 >patch1 &&
82 grep "^From " patch1 >from1 &&
83 test_line_count = 2 from1
86 test_expect_success
"format-patch doesn't consider merge commits" '
87 git checkout -b feature main &&
88 echo "Another line" >>file &&
90 git commit -am "Feature branch change #1" &&
91 echo "Yet another line" >>file &&
93 git commit -am "Feature branch change #2" &&
94 git checkout -b merger main &&
96 git merge --no-ff feature &&
97 git format-patch -3 --stdout >patch &&
98 grep "^From " patch >from &&
99 test_line_count = 3 from
102 test_expect_success
'format-patch result applies' '
103 git checkout -b rebuild-0 main &&
105 git rev-list main.. >list &&
106 test_line_count = 2 list
109 test_expect_success
'format-patch --ignore-if-in-upstream result applies' '
110 git checkout -b rebuild-1 main &&
112 git rev-list main.. >list &&
113 test_line_count = 2 list
116 test_expect_success
'commit did not screw up the log message' '
117 git cat-file commit side >actual &&
118 grep "^Side .* with .* backslash-n" actual
121 test_expect_success
'format-patch did not screw up the log message' '
122 grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
123 grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
126 test_expect_success
'replay did not screw up the log message' '
127 git cat-file commit rebuild-1 >actual &&
128 grep "^Side .* with .* backslash-n" actual
131 test_expect_success
'extra headers' '
132 git config format.headers "To: R E Cipient <rcipient@example.com>
134 git config --add format.headers "Cc: S E Cipient <scipient@example.com>
136 git format-patch --stdout main..side >patch2 &&
137 sed -e "/^\$/q" patch2 >hdrs2 &&
138 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs2 &&
139 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs2
142 test_expect_success
'extra headers without newlines' '
143 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
144 git config --add format.headers "Cc: S E Cipient <scipient@example.com>" &&
145 git format-patch --stdout main..side >patch3 &&
146 sed -e "/^\$/q" patch3 >hdrs3 &&
147 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs3 &&
148 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs3
151 test_expect_success
'extra headers with multiple To:s' '
152 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
153 git config --add format.headers "To: S E Cipient <scipient@example.com>" &&
154 git format-patch --stdout main..side >patch4 &&
155 sed -e "/^\$/q" patch4 >hdrs4 &&
156 grep "^To: R E Cipient <rcipient@example.com>,\$" hdrs4 &&
157 grep "^ *S E Cipient <scipient@example.com>\$" hdrs4
160 test_expect_success
'additional command line cc (ascii)' '
161 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
162 git format-patch --cc="S E Cipient <scipient@example.com>" --stdout main..side >patch5 &&
163 sed -e "/^\$/q" patch5 >hdrs5 &&
164 grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs5 &&
165 grep "^ *S E Cipient <scipient@example.com>\$" hdrs5
168 test_expect_failure
'additional command line cc (rfc822)' '
169 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
170 git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout main..side >patch5 &&
171 sed -e "/^\$/q" patch5 >hdrs5 &&
172 grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs5 &&
173 grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" hdrs5
176 test_expect_success
'command line headers' '
177 git config --unset-all format.headers &&
178 git format-patch --add-header="Cc: R E Cipient <rcipient@example.com>" --stdout main..side >patch6 &&
179 sed -e "/^\$/q" patch6 >hdrs6 &&
180 grep "^Cc: R E Cipient <rcipient@example.com>\$" hdrs6
183 test_expect_success
'configuration headers and command line headers' '
184 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
185 git format-patch --add-header="Cc: S E Cipient <scipient@example.com>" --stdout main..side >patch7 &&
186 sed -e "/^\$/q" patch7 >hdrs7 &&
187 grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs7 &&
188 grep "^ *S E Cipient <scipient@example.com>\$" hdrs7
191 test_expect_success
'command line To: header (ascii)' '
192 git config --unset-all format.headers &&
193 git format-patch --to="R E Cipient <rcipient@example.com>" --stdout main..side >patch8 &&
194 sed -e "/^\$/q" patch8 >hdrs8 &&
195 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs8
198 test_expect_failure
'command line To: header (rfc822)' '
199 git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout main..side >patch8 &&
200 sed -e "/^\$/q" patch8 >hdrs8 &&
201 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" hdrs8
204 test_expect_failure
'command line To: header (rfc2047)' '
205 git format-patch --to="R Ä Cipient <rcipient@example.com>" --stdout main..side >patch8 &&
206 sed -e "/^\$/q" patch8 >hdrs8 &&
207 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" hdrs8
210 test_expect_success
'configuration To: header (ascii)' '
211 git config format.to "R E Cipient <rcipient@example.com>" &&
212 git format-patch --stdout main..side >patch9 &&
213 sed -e "/^\$/q" patch9 >hdrs9 &&
214 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs9
217 test_expect_failure
'configuration To: header (rfc822)' '
218 git config format.to "R. E. Cipient <rcipient@example.com>" &&
219 git format-patch --stdout main..side >patch9 &&
220 sed -e "/^\$/q" patch9 >hdrs9 &&
221 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" hdrs9
224 test_expect_failure
'configuration To: header (rfc2047)' '
225 git config format.to "R Ä Cipient <rcipient@example.com>" &&
226 git format-patch --stdout main..side >patch9 &&
227 sed -e "/^\$/q" patch9 >hdrs9 &&
228 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" hdrs9
231 # check_patch <patch>: Verify that <patch> looks like a half-sane
232 # patch email to avoid a false positive with !grep
234 grep -e "^From:" "$1" &&
235 grep -e "^Date:" "$1" &&
236 grep -e "^Subject:" "$1"
239 test_expect_success
'format.from=false' '
240 git -c format.from=false format-patch --stdout main..side >patch &&
241 sed -e "/^\$/q" patch >hdrs &&
243 ! grep "^From: C O Mitter <committer@example.com>\$" hdrs
246 test_expect_success
'format.from=true' '
247 git -c format.from=true format-patch --stdout main..side >patch &&
248 sed -e "/^\$/q" patch >hdrs &&
250 grep "^From: C O Mitter <committer@example.com>\$" hdrs
253 test_expect_success
'format.from with address' '
254 git -c format.from="F R Om <from@example.com>" format-patch --stdout main..side >patch &&
255 sed -e "/^\$/q" patch >hdrs &&
257 grep "^From: F R Om <from@example.com>\$" hdrs
260 test_expect_success
'--no-from overrides format.from' '
261 git -c format.from="F R Om <from@example.com>" format-patch --no-from --stdout main..side >patch &&
262 sed -e "/^\$/q" patch >hdrs &&
264 ! grep "^From: F R Om <from@example.com>\$" hdrs
267 test_expect_success
'--from overrides format.from' '
268 git -c format.from="F R Om <from@example.com>" format-patch --from --stdout main..side >patch &&
269 sed -e "/^\$/q" patch >hdrs &&
271 ! grep "^From: F R Om <from@example.com>\$" hdrs
274 test_expect_success
'--no-to overrides config.to' '
275 git config --replace-all format.to \
276 "R E Cipient <rcipient@example.com>" &&
277 git format-patch --no-to --stdout main..side >patch10 &&
278 sed -e "/^\$/q" patch10 >hdrs10 &&
279 check_patch hdrs10 &&
280 ! grep "^To: R E Cipient <rcipient@example.com>\$" hdrs10
283 test_expect_success
'--no-to and --to replaces config.to' '
284 git config --replace-all format.to \
285 "Someone <someone@out.there>" &&
286 git format-patch --no-to --to="Someone Else <else@out.there>" \
287 --stdout main..side >patch11 &&
288 sed -e "/^\$/q" patch11 >hdrs11 &&
289 check_patch hdrs11 &&
290 ! grep "^To: Someone <someone@out.there>\$" hdrs11 &&
291 grep "^To: Someone Else <else@out.there>\$" hdrs11
294 test_expect_success
'--no-cc overrides config.cc' '
295 git config --replace-all format.cc \
296 "C E Cipient <rcipient@example.com>" &&
297 git format-patch --no-cc --stdout main..side >patch12 &&
298 sed -e "/^\$/q" patch12 >hdrs12 &&
299 check_patch hdrs12 &&
300 ! grep "^Cc: C E Cipient <rcipient@example.com>\$" hdrs12
303 test_expect_success
'--no-add-header overrides config.headers' '
304 git config --replace-all format.headers \
305 "Header1: B E Cipient <rcipient@example.com>" &&
306 git format-patch --no-add-header --stdout main..side >patch13 &&
307 sed -e "/^\$/q" patch13 >hdrs13 &&
308 check_patch hdrs13 &&
309 ! grep "^Header1: B E Cipient <rcipient@example.com>\$" hdrs13
312 test_expect_success
'multiple files' '
315 git format-patch -o patches/ main &&
316 ls patches/0001-Side-changes-1.patch patches/0002-Side-changes-2.patch patches/0003-Side-changes-3-with-n-backslash-n-in-it.patch
319 test_expect_success
'filename length limit' '
320 test_when_finished "rm -f 000*" &&
321 rm -rf 000[1-9]-*.patch &&
324 git format-patch --filename-max-length=$len -3 side &&
326 for patch in 000[1-9]-*.patch
328 echo "$patch" | wc -c
333 test $max -le $len || return 1
337 test_expect_success
'filename length limit from config' '
338 test_when_finished "rm -f 000*" &&
339 rm -rf 000[1-9]-*.patch &&
342 git -c format.filenameMaxLength=$len format-patch -3 side &&
344 for patch in 000[1-9]-*.patch
346 echo "$patch" | wc -c
351 test $max -le $len || return 1
355 test_expect_success
'filename limit applies only to basename' '
356 test_when_finished "rm -rf patches/" &&
360 git format-patch -o patches --filename-max-length=$len -3 side &&
362 for patch in patches/000[1-9]-*.patch
364 echo "${patch#patches/}" | wc -c
369 test $max -le $len || return 1
373 test_expect_success
'reroll count' '
375 git format-patch -o patches --cover-letter --reroll-count 4 main..side >list &&
376 ! grep -v "^patches/v4-000[0-3]-" list &&
377 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
378 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
381 test_expect_success
'reroll count (-v)' '
383 git format-patch -o patches --cover-letter -v4 main..side >list &&
384 ! grep -v "^patches/v4-000[0-3]-" list &&
385 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
386 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
392 git format-patch
--stdout "$@" >patch &&
393 # Prints everything between the Message-ID and In-Reply-To,
394 # and replaces all Message-ID-lookalikes by a sequence number
396 if (/^(message-id|references|in-reply-to)/i) {
402 $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
403 for $k (keys %h) {s/$k/$h{$k}/};
406 print "---\n" if /^From /i;
408 test_cmp
"$expect" actual
411 cat >>expect.no-threading
<<EOF
417 test_expect_success
'no threading' '
419 check_threading expect.no-threading main
422 cat >expect.thread
<<EOF
435 test_expect_success
'thread' '
436 check_threading expect.thread --thread main
439 cat >expect.in-reply-to
<<EOF
454 test_expect_success
'thread in-reply-to' '
455 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
459 cat >expect.cover-letter
<<EOF
476 test_expect_success
'thread cover-letter' '
477 check_threading expect.cover-letter --cover-letter --thread main
480 cat >expect.cl-irt
<<EOF
502 test_expect_success
'thread cover-letter in-reply-to' '
503 check_threading expect.cl-irt --cover-letter \
504 --in-reply-to="<test.message>" --thread main
507 test_expect_success
'thread explicit shallow' '
508 check_threading expect.cl-irt --cover-letter \
509 --in-reply-to="<test.message>" --thread=shallow main
512 cat >expect.deep
<<EOF
526 test_expect_success
'thread deep' '
527 check_threading expect.deep --thread=deep main
530 cat >expect.deep-irt
<<EOF
548 test_expect_success
'thread deep in-reply-to' '
549 check_threading expect.deep-irt --thread=deep \
550 --in-reply-to="<test.message>" main
553 cat >expect.deep-cl
<<EOF
573 test_expect_success
'thread deep cover-letter' '
574 check_threading expect.deep-cl --cover-letter --thread=deep main
577 cat >expect.deep-cl-irt
<<EOF
602 test_expect_success
'thread deep cover-letter in-reply-to' '
603 check_threading expect.deep-cl-irt --cover-letter \
604 --in-reply-to="<test.message>" --thread=deep main
607 test_expect_success
'thread via config' '
608 test_config format.thread true &&
609 check_threading expect.thread main
612 test_expect_success
'thread deep via config' '
613 test_config format.thread deep &&
614 check_threading expect.deep main
617 test_expect_success
'thread config + override' '
618 test_config format.thread deep &&
619 check_threading expect.thread --thread main
622 test_expect_success
'thread config + --no-thread' '
623 test_config format.thread deep &&
624 check_threading expect.no-threading --no-thread main
627 test_expect_success
'excessive subject' '
630 before=$(git hash-object file) &&
631 before=$(git rev-parse --short $before) &&
632 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
633 after=$(git hash-object file) &&
634 after=$(git rev-parse --short $after) &&
635 git update-index file &&
636 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." &&
637 git format-patch -o patches/ main..side &&
638 ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
641 test_expect_success
'failure to write cover-letter aborts gracefully' '
642 test_when_finished "rmdir 0000-cover-letter.patch" &&
643 mkdir 0000-cover-letter.patch &&
644 test_must_fail git format-patch --no-renames --cover-letter -1
647 test_expect_success
'cover-letter inherits diff options' '
650 git format-patch --no-renames --cover-letter -1 &&
651 check_patch 0000-cover-letter.patch &&
652 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
653 git format-patch --cover-letter -1 -M &&
654 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
658 This is an excessively long subject line for a message due to the
659 habit some projects have of not having a short, one-line subject at
660 the start of the commit message, but rather sticking a whole
661 paragraph right at the start as the only thing in the commit
662 message. It had better not become the filename for the patch.
667 test_expect_success
'shortlog of cover-letter wraps overly-long onelines' '
668 git format-patch --cover-letter -2 &&
669 sed -e "1,/A U Thor/d" -e "/^\$/q" 0000-cover-letter.patch >output &&
670 test_cmp expect output
674 index $before..$after 100644
685 test_expect_success
'format-patch respects -U' '
686 git format-patch -U4 -2 &&
687 sed -e "1,/^diff/d" -e "/^+5/q" \
688 <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
690 test_cmp expect output
695 diff --git a/file b/file
696 index $before..$after 100644
706 test_expect_success
'format-patch -p suppresses stat' '
707 git format-patch -p -2 &&
708 sed -e "1,/^\$/d" -e "/^+5/q" 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch >output &&
709 test_cmp expect output
712 test_expect_success
'format-patch from a subdirectory (1)' '
723 echo "Oops? $filename"
730 test_expect_success
'format-patch from a subdirectory (2)' '
735 git format-patch -1 -o ..
741 echo "Oops? $filename"
745 basename=$(expr "$filename" : ".*/\(.*\)") &&
746 test -f "sub/$basename"
749 test_expect_success
'format-patch from a subdirectory (3)' '
755 git format-patch -1 -o "$TRASH_DIRECTORY"
757 basename=$(expr "$filename" : ".*/\(.*\)") &&
761 test_expect_success
'format-patch --in-reply-to' '
762 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" >patch8 &&
763 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
764 grep "^References: <baz@foo.bar>" patch8
767 test_expect_success
'format-patch --signoff' '
768 git format-patch -1 --signoff --stdout >out &&
769 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
772 test_expect_success
'format-patch --notes --signoff' '
773 git notes --ref test add -m "test message" HEAD &&
774 git format-patch -1 --signoff --stdout --notes=test >out &&
775 # Three dashes must come after S-o-b
776 ! sed "/^Signed-off-by: /q" out | grep "test message" &&
777 sed "1,/^Signed-off-by: /d" out | grep "test message" &&
778 # Notes message must come after three dashes
779 ! sed "/^---$/q" out | grep "test message" &&
780 sed "1,/^---$/d" out | grep "test message"
783 test_expect_success
'format-patch notes output control' '
784 git notes add -m "notes config message" HEAD &&
785 test_when_finished git notes remove HEAD &&
787 git format-patch -1 --stdout >out &&
788 ! grep "notes config message" out &&
789 git format-patch -1 --stdout --notes >out &&
790 grep "notes config message" out &&
791 git format-patch -1 --stdout --no-notes >out &&
792 ! grep "notes config message" out &&
793 git format-patch -1 --stdout --notes --no-notes >out &&
794 ! grep "notes config message" out &&
795 git format-patch -1 --stdout --no-notes --notes >out &&
796 grep "notes config message" out &&
798 test_config format.notes true &&
799 git format-patch -1 --stdout >out &&
800 grep "notes config message" out &&
801 git format-patch -1 --stdout --notes >out &&
802 grep "notes config message" out &&
803 git format-patch -1 --stdout --no-notes >out &&
804 ! grep "notes config message" out &&
805 git format-patch -1 --stdout --notes --no-notes >out &&
806 ! grep "notes config message" out &&
807 git format-patch -1 --stdout --no-notes --notes >out &&
808 grep "notes config message" out
811 test_expect_success
'format-patch with multiple notes refs' '
812 git notes --ref note1 add -m "this is note 1" HEAD &&
813 test_when_finished git notes --ref note1 remove HEAD &&
814 git notes --ref note2 add -m "this is note 2" HEAD &&
815 test_when_finished git notes --ref note2 remove HEAD &&
817 git format-patch -1 --stdout >out &&
818 ! grep "this is note 1" out &&
819 ! grep "this is note 2" out &&
820 git format-patch -1 --stdout --notes=note1 >out &&
821 grep "this is note 1" out &&
822 ! grep "this is note 2" out &&
823 git format-patch -1 --stdout --notes=note2 >out &&
824 ! grep "this is note 1" out &&
825 grep "this is note 2" out &&
826 git format-patch -1 --stdout --notes=note1 --notes=note2 >out &&
827 grep "this is note 1" out &&
828 grep "this is note 2" out &&
830 test_config format.notes note1 &&
831 git format-patch -1 --stdout >out &&
832 grep "this is note 1" out &&
833 ! grep "this is note 2" out &&
834 git format-patch -1 --stdout --no-notes >out &&
835 ! grep "this is note 1" out &&
836 ! grep "this is note 2" out &&
837 git format-patch -1 --stdout --notes=note2 >out &&
838 grep "this is note 1" out &&
839 grep "this is note 2" out &&
840 git format-patch -1 --stdout --no-notes --notes=note2 >out &&
841 ! grep "this is note 1" out &&
842 grep "this is note 2" out &&
844 git config --add format.notes note2 &&
845 git format-patch -1 --stdout >out &&
846 grep "this is note 1" out &&
847 grep "this is note 2" out &&
848 git format-patch -1 --stdout --no-notes >out &&
849 ! grep "this is note 1" out &&
850 ! grep "this is note 2" out
853 test_expect_success
'format-patch with multiple notes refs in config' '
854 test_when_finished "test_unconfig format.notes" &&
856 git notes --ref note1 add -m "this is note 1" HEAD &&
857 test_when_finished git notes --ref note1 remove HEAD &&
858 git notes --ref note2 add -m "this is note 2" HEAD &&
859 test_when_finished git notes --ref note2 remove HEAD &&
861 git config format.notes note1 &&
862 git format-patch -1 --stdout >out &&
863 grep "this is note 1" out &&
864 ! grep "this is note 2" out &&
865 git config format.notes note2 &&
866 git format-patch -1 --stdout >out &&
867 ! grep "this is note 1" out &&
868 grep "this is note 2" out &&
869 git config --add format.notes note1 &&
870 git format-patch -1 --stdout >out &&
871 grep "this is note 1" out &&
872 grep "this is note 2" out &&
874 git config --replace-all format.notes note1 &&
875 git config --add format.notes false &&
876 git format-patch -1 --stdout >out &&
877 ! grep "this is note 1" out &&
878 ! grep "this is note 2" out &&
879 git config --add format.notes note2 &&
880 git format-patch -1 --stdout >out &&
881 ! grep "this is note 1" out &&
882 grep "this is note 2" out
885 echo "fatal: --name-only does not make sense" >expect.name-only
886 echo "fatal: --name-status does not make sense" >expect.name-status
887 echo "fatal: --check does not make sense" >expect.check
889 test_expect_success
'options no longer allowed for format-patch' '
890 test_must_fail git format-patch --name-only 2>output &&
891 test_cmp expect.name-only output &&
892 test_must_fail git format-patch --name-status 2>output &&
893 test_cmp expect.name-status output &&
894 test_must_fail git format-patch --check 2>output &&
895 test_cmp expect.check output
898 test_expect_success
'format-patch --numstat should produce a patch' '
899 git format-patch --numstat --stdout main..side >output &&
900 grep "^diff --git a/" output >diff &&
901 test_line_count = 5 diff
904 test_expect_success
'format-patch -- <path>' '
905 git format-patch main..side -- file 2>error &&
906 ! grep "Use .--" error
909 test_expect_success
'format-patch --ignore-if-in-upstream HEAD' '
910 git format-patch --ignore-if-in-upstream HEAD
913 test_expect_success
'get git version' '
914 git_version=$(git --version) &&
915 git_version=${git_version##* }
919 printf "%s\n%s\n\n" "-- " "${1:-$git_version}"
922 test_expect_success
'format-patch default signature' '
923 git format-patch --stdout -1 >patch &&
924 tail -n 3 patch >output &&
926 test_cmp expect output
929 test_expect_success
'format-patch --signature' '
930 git format-patch --stdout --signature="my sig" -1 >patch &&
931 tail -n 3 patch >output &&
932 signature "my sig" >expect &&
933 test_cmp expect output
936 test_expect_success
'format-patch with format.signature config' '
937 git config format.signature "config sig" &&
938 git format-patch --stdout -1 >output &&
939 grep "config sig" output
942 test_expect_success
'format-patch --signature overrides format.signature' '
943 git config format.signature "config sig" &&
944 git format-patch --stdout --signature="overrides" -1 >output &&
945 ! grep "config sig" output &&
946 grep "overrides" output
949 test_expect_success
'format-patch --no-signature ignores format.signature' '
950 git config format.signature "config sig" &&
951 git format-patch --stdout --signature="my sig" --no-signature \
953 check_patch output &&
954 ! grep "config sig" output &&
955 ! grep "my sig" output &&
956 ! grep "^-- \$" output
959 test_expect_success
'format-patch --signature --cover-letter' '
960 git config --unset-all format.signature &&
961 git format-patch --stdout --signature="my sig" --cover-letter \
963 grep "my sig" output >sig &&
964 test_line_count = 2 sig
967 test_expect_success
'format.signature="" suppresses signatures' '
968 git config format.signature "" &&
969 git format-patch --stdout -1 >output &&
970 check_patch output &&
971 ! grep "^-- \$" output
974 test_expect_success
'format-patch --no-signature suppresses signatures' '
975 git config --unset-all format.signature &&
976 git format-patch --stdout --no-signature -1 >output &&
977 check_patch output &&
978 ! grep "^-- \$" output
981 test_expect_success
'format-patch --signature="" suppresses signatures' '
982 git format-patch --stdout --signature="" -1 >output &&
983 check_patch output &&
984 ! grep "^-- \$" output
987 test_expect_success
'prepare mail-signature input' '
988 cat >mail-signature <<-\EOF
990 Test User <test.email@kernel.org>
991 http://git.kernel.org/cgit/git/git.git
993 git.kernel.org/?p=git/git.git;a=summary
998 test_expect_success
'--signature-file=file works' '
999 git format-patch --stdout --signature-file=mail-signature -1 >output &&
1000 check_patch output &&
1001 sed -e "1,/^-- \$/d" output >actual &&
1003 cat mail-signature && echo
1005 test_cmp expect actual
1008 test_expect_success
'format.signaturefile works' '
1009 test_config format.signaturefile mail-signature &&
1010 git format-patch --stdout -1 >output &&
1011 check_patch output &&
1012 sed -e "1,/^-- \$/d" output >actual &&
1014 cat mail-signature && echo
1016 test_cmp expect actual
1019 test_expect_success
'--no-signature suppresses format.signaturefile ' '
1020 test_config format.signaturefile mail-signature &&
1021 git format-patch --stdout --no-signature -1 >output &&
1022 check_patch output &&
1023 ! grep "^-- \$" output
1026 test_expect_success
'--signature-file overrides format.signaturefile' '
1027 cat >other-mail-signature <<-\EOF &&
1028 Use this other signature instead of mail-signature.
1030 test_config format.signaturefile mail-signature &&
1031 git format-patch --stdout \
1032 --signature-file=other-mail-signature -1 >output &&
1033 check_patch output &&
1034 sed -e "1,/^-- \$/d" output >actual &&
1036 cat other-mail-signature && echo
1038 test_cmp expect actual
1041 test_expect_success
'--signature overrides format.signaturefile' '
1042 test_config format.signaturefile mail-signature &&
1043 git format-patch --stdout --signature="my sig" -1 >output &&
1044 check_patch output &&
1045 grep "my sig" output
1048 test_expect_success TTY
'format-patch --stdout paginates' '
1050 test_terminal env GIT_PAGER="wc >pager_used" git format-patch --stdout --all &&
1051 test_path_is_file pager_used
1054 test_expect_success TTY
'format-patch --stdout pagination can be disabled' '
1056 test_terminal env GIT_PAGER="wc >pager_used" git --no-pager format-patch --stdout --all &&
1057 test_terminal env GIT_PAGER="wc >pager_used" git -c "pager.format-patch=false" format-patch --stdout --all &&
1058 test_path_is_missing pager_used &&
1059 test_path_is_missing .git/pager_used
1062 test_expect_success
'format-patch handles multi-line subjects' '
1064 echo content >>file &&
1065 for i in one two three; do echo $i; done >msg &&
1067 git commit -F msg &&
1068 git format-patch -o patches -1 &&
1069 grep ^Subject: patches/0001-one.patch >actual &&
1070 echo "Subject: [PATCH] one two three" >expect &&
1071 test_cmp expect actual
1074 test_expect_success
'format-patch handles multi-line encoded subjects' '
1076 echo content >>file &&
1077 for i in en två tre; do echo $i; done >msg &&
1079 git commit -F msg &&
1080 git format-patch -o patches -1 &&
1081 grep ^Subject: patches/0001-en.patch >actual &&
1082 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
1083 test_cmp expect actual
1087 M64
=$M8$M8$M8$M8$M8$M8$M8$M8
1088 M512
=$M64$M64$M64$M64$M64$M64$M64$M64
1090 Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1091 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1092 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1093 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1094 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1095 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1096 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1098 test_expect_success
'format-patch wraps extremely long subject (ascii)' '
1099 echo content >>file &&
1101 git commit -m "$M512" &&
1102 git format-patch --stdout -1 >patch &&
1103 sed -n "/^Subject/p; /^ /p; /^$/q" patch >subject &&
1104 test_cmp expect subject
1108 M64
=$M8$M8$M8$M8$M8$M8$M8$M8
1109 M512
=$M64$M64$M64$M64$M64$M64$M64$M64
1111 Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1112 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1113 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1114 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1115 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1116 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1117 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1118 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1119 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1120 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1121 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1122 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1123 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1124 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1125 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1126 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1127 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1128 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1129 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1130 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1131 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1132 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1133 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1136 test_expect_success
'format-patch wraps extremely long subject (rfc2047)' '
1138 echo content >>file &&
1140 git commit -m "$M512" &&
1141 git format-patch --stdout -1 >patch &&
1142 sed -n "/^Subject/p; /^ /p; /^$/q" patch >subject &&
1143 test_cmp expect subject
1147 echo content
>>file &&
1149 GIT_AUTHOR_NAME
=$1 git commit
-m author-check
&&
1150 git format-patch
--stdout -1 >patch &&
1151 sed -n "/^From: /p; /^ /p; /^$/q" patch >actual
&&
1152 test_cmp expect actual
1156 From: "Foo B. Bar" <author@example.com>
1158 test_expect_success
'format-patch quotes dot in from-headers' '
1159 check_author "Foo B. Bar"
1163 From: "Foo \"The Baz\" Bar" <author@example.com>
1165 test_expect_success
'format-patch quotes double-quote in from-headers' '
1166 check_author "Foo \"The Baz\" Bar"
1170 From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
1172 test_expect_success
'format-patch uses rfc2047-encoded from-headers when necessary' '
1173 check_author "Föo Bar"
1177 From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
1179 test_expect_success
'rfc2047-encoded from-headers leave no rfc822 specials' '
1180 check_author "Föo B. Bar"
1184 From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
1185 <author@example.com>
1187 test_expect_success
'format-patch wraps moderately long from-header (ascii)' '
1188 check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
1192 From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1193 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1194 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
1196 test_expect_success
'format-patch wraps extremely long from-header (ascii)' '
1197 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"
1201 From: "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1202 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1203 Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
1205 test_expect_success
'format-patch wraps extremely long from-header (rfc822)' '
1206 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"
1210 From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
1211 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
1212 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
1213 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
1214 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
1216 test_expect_success
'format-patch wraps extremely long from-header (rfc2047)' '
1217 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"
1221 From: Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1222 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1223 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
1225 test_expect_success
'format-patch wraps extremely long from-header (non-ASCII without Q-encoding)' '
1226 echo content >>file &&
1228 GIT_AUTHOR_NAME="Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar" \
1229 git commit -m author-check &&
1230 git format-patch --no-encode-email-headers --stdout -1 >patch &&
1231 sed -n "/^From: /p; /^ /p; /^$/q" patch >actual &&
1232 test_cmp expect actual
1236 Subject: [PATCH] Foö
1238 test_expect_success
'subject lines are unencoded with --no-encode-email-headers' '
1239 echo content >>file &&
1241 git commit -m "Foö" &&
1242 git format-patch --no-encode-email-headers -1 --stdout >patch &&
1243 grep ^Subject: patch >actual &&
1244 test_cmp expect actual
1248 Subject: [PATCH] Foö
1250 test_expect_success
'subject lines are unencoded with format.encodeEmailHeaders=false' '
1251 echo content >>file &&
1253 git commit -m "Foö" &&
1254 git config format.encodeEmailHeaders false &&
1255 git format-patch -1 --stdout >patch &&
1256 grep ^Subject: patch >actual &&
1257 test_cmp expect actual
1261 Subject: [PATCH] =?UTF-8?q?Fo=C3=B6?=
1263 test_expect_success
'--encode-email-headers overrides format.encodeEmailHeaders' '
1264 echo content >>file &&
1266 git commit -m "Foö" &&
1267 git config format.encodeEmailHeaders false &&
1268 git format-patch --encode-email-headers -1 --stdout >patch &&
1269 grep ^Subject: patch >actual &&
1270 test_cmp expect actual
1274 Subject: header with . in it
1276 test_expect_success
'subject lines do not have 822 atom-quoting' '
1277 echo content >>file &&
1279 git commit -m "header with . in it" &&
1280 git format-patch -k -1 --stdout >patch &&
1281 grep ^Subject: patch >actual &&
1282 test_cmp expect actual
1286 Subject: [PREFIX 1/1] header with . in it
1288 test_expect_success
'subject prefixes have space prepended' '
1289 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
1290 grep ^Subject: patch >actual &&
1291 test_cmp expect actual
1295 Subject: [1/1] header with . in it
1297 test_expect_success
'empty subject prefix does not have extra space' '
1298 git format-patch -n -1 --stdout --subject-prefix= >patch &&
1299 grep ^Subject: patch >actual &&
1300 test_cmp expect actual
1303 test_expect_success
'--rfc' '
1304 cat >expect <<-\EOF &&
1305 Subject: [RFC PATCH 1/1] header with . in it
1307 git format-patch -n -1 --stdout --rfc >patch &&
1308 grep ^Subject: patch >actual &&
1309 test_cmp expect actual
1312 test_expect_success
'--from=ident notices bogus ident' '
1313 test_must_fail git format-patch -1 --stdout --from=foo >patch
1316 test_expect_success
'--from=ident replaces author' '
1317 git format-patch -1 --stdout --from="Me <me@example.com>" >patch &&
1318 cat >expect <<-\EOF &&
1319 From: Me <me@example.com>
1321 From: A U Thor <author@example.com>
1324 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1325 test_cmp expect patch.head
1328 test_expect_success
'--from uses committer ident' '
1329 git format-patch -1 --stdout --from >patch &&
1330 cat >expect <<-\EOF &&
1331 From: C O Mitter <committer@example.com>
1333 From: A U Thor <author@example.com>
1336 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1337 test_cmp expect patch.head
1340 test_expect_success
'--from omits redundant in-body header' '
1341 git format-patch -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1342 cat >expect <<-\EOF &&
1343 From: A U Thor <author@example.com>
1346 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1347 test_cmp expect patch.head
1350 test_expect_success
'in-body headers trigger content encoding' '
1351 test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
1352 test_when_finished "git reset --hard HEAD^" &&
1353 git format-patch -1 --stdout --from >patch &&
1354 cat >expect <<-\EOF &&
1355 From: C O Mitter <committer@example.com>
1356 Content-Type: text/plain; charset=UTF-8
1358 From: éxötìc <author@example.com>
1361 sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" patch >patch.head &&
1362 test_cmp expect patch.head
1367 C
=$
(git commit-tree HEAD^^
{tree
} -p HEAD
) &&
1368 git format-patch
--stdout --signoff $C^..
$C >append_signoff.
patch &&
1369 sed -n -e "1,/^---$/p" append_signoff.
patch |
1370 egrep -n "^Subject|Sign|^$"
1373 test_expect_success
'signoff: commit with no body' '
1374 append_signoff </dev/null >actual &&
1375 cat <<-\EOF | sed "s/EOL$//" >expect &&
1376 4:Subject: [PATCH] EOL
1378 9:Signed-off-by: C O Mitter <committer@example.com>
1380 test_cmp expect actual
1383 test_expect_success
'signoff: commit with only subject' '
1384 echo subject | append_signoff >actual &&
1385 cat >expect <<-\EOF &&
1386 4:Subject: [PATCH] subject
1388 9:Signed-off-by: C O Mitter <committer@example.com>
1390 test_cmp expect actual
1393 test_expect_success
'signoff: commit with only subject that does not end with NL' '
1394 printf subject | append_signoff >actual &&
1395 cat >expect <<-\EOF &&
1396 4:Subject: [PATCH] subject
1398 9:Signed-off-by: C O Mitter <committer@example.com>
1400 test_cmp expect actual
1403 test_expect_success
'signoff: no existing signoffs' '
1404 append_signoff <<-\EOF >actual &&
1409 cat >expect <<-\EOF &&
1410 4:Subject: [PATCH] subject
1413 11:Signed-off-by: C O Mitter <committer@example.com>
1415 test_cmp expect actual
1418 test_expect_success
'signoff: no existing signoffs and no trailing NL' '
1419 printf "subject\n\nbody" | append_signoff >actual &&
1420 cat >expect <<-\EOF &&
1421 4:Subject: [PATCH] subject
1424 11:Signed-off-by: C O Mitter <committer@example.com>
1426 test_cmp expect actual
1429 test_expect_success
'signoff: some random signoff' '
1430 append_signoff <<-\EOF >actual &&
1435 Signed-off-by: my@house
1437 cat >expect <<-\EOF &&
1438 4:Subject: [PATCH] subject
1441 11:Signed-off-by: my@house
1442 12:Signed-off-by: C O Mitter <committer@example.com>
1444 test_cmp expect actual
1447 test_expect_success
'signoff: misc conforming footer elements' '
1448 append_signoff <<-\EOF >actual &&
1453 Signed-off-by: my@house
1454 (cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1455 Tested-by: Some One <someone@example.com>
1458 cat >expect <<-\EOF &&
1459 4:Subject: [PATCH] subject
1462 11:Signed-off-by: my@house
1463 15:Signed-off-by: C O Mitter <committer@example.com>
1465 test_cmp expect actual
1468 test_expect_success
'signoff: some random signoff-alike' '
1469 append_signoff <<-\EOF >actual &&
1473 Fooled-by-me: my@house
1475 cat >expect <<-\EOF &&
1476 4:Subject: [PATCH] subject
1479 12:Signed-off-by: C O Mitter <committer@example.com>
1481 test_cmp expect actual
1484 test_expect_success
'signoff: not really a signoff' '
1485 append_signoff <<-\EOF >actual &&
1488 I want to mention about Signed-off-by: here.
1490 cat >expect <<-\EOF &&
1491 4:Subject: [PATCH] subject
1493 9:I want to mention about Signed-off-by: here.
1495 11:Signed-off-by: C O Mitter <committer@example.com>
1497 test_cmp expect actual
1500 test_expect_success
'signoff: not really a signoff (2)' '
1501 append_signoff <<-\EOF >actual &&
1505 Signed-off-by: example happens to be wrapped here.
1507 cat >expect <<-\EOF &&
1508 4:Subject: [PATCH] subject
1510 10:Signed-off-by: example happens to be wrapped here.
1511 11:Signed-off-by: C O Mitter <committer@example.com>
1513 test_cmp expect actual
1516 test_expect_success
'signoff: valid S-o-b paragraph in the middle' '
1517 append_signoff <<-\EOF >actual &&
1520 Signed-off-by: my@house
1521 Signed-off-by: your@house
1525 cat >expect <<-\EOF &&
1526 4:Subject: [PATCH] subject
1528 9:Signed-off-by: my@house
1529 10:Signed-off-by: your@house
1532 14:Signed-off-by: C O Mitter <committer@example.com>
1534 test_cmp expect actual
1537 test_expect_success
'signoff: the same signoff at the end' '
1538 append_signoff <<-\EOF >actual &&
1543 Signed-off-by: C O Mitter <committer@example.com>
1545 cat >expect <<-\EOF &&
1546 4:Subject: [PATCH] subject
1549 11:Signed-off-by: C O Mitter <committer@example.com>
1551 test_cmp expect actual
1554 test_expect_success
'signoff: the same signoff at the end, no trailing NL' '
1555 printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
1556 append_signoff >actual &&
1557 cat >expect <<-\EOF &&
1558 4:Subject: [PATCH] subject
1560 9:Signed-off-by: C O Mitter <committer@example.com>
1562 test_cmp expect actual
1565 test_expect_success
'signoff: the same signoff NOT at the end' '
1566 append_signoff <<-\EOF >actual &&
1571 Signed-off-by: C O Mitter <committer@example.com>
1572 Signed-off-by: my@house
1574 cat >expect <<-\EOF &&
1575 4:Subject: [PATCH] subject
1578 11:Signed-off-by: C O Mitter <committer@example.com>
1579 12:Signed-off-by: my@house
1581 test_cmp expect actual
1584 test_expect_success
'signoff: tolerate garbage in conforming footer' '
1585 append_signoff <<-\EOF >actual &&
1592 Signed-off-by: C O Mitter <committer@example.com>
1594 cat >expect <<-\EOF &&
1595 4:Subject: [PATCH] subject
1598 13:Signed-off-by: C O Mitter <committer@example.com>
1600 test_cmp expect actual
1603 test_expect_success
'signoff: respect trailer config' '
1604 append_signoff <<-\EOF >actual &&
1610 cat >expect <<-\EOF &&
1611 4:Subject: [PATCH] subject
1614 12:Signed-off-by: C O Mitter <committer@example.com>
1616 test_cmp expect actual &&
1618 test_config trailer.Myfooter.ifexists add &&
1619 append_signoff <<-\EOF >actual &&
1625 cat >expect <<-\EOF &&
1626 4:Subject: [PATCH] subject
1628 11:Signed-off-by: C O Mitter <committer@example.com>
1630 test_cmp expect actual
1633 test_expect_success
'signoff: footer begins with non-signoff without @ sign' '
1634 append_signoff <<-\EOF >actual &&
1641 Change-id: Ideadbeef
1642 Signed-off-by: C O Mitter <committer@example.com>
1645 cat >expect <<-\EOF &&
1646 4:Subject: [PATCH] subject
1649 14:Signed-off-by: C O Mitter <committer@example.com>
1651 test_cmp expect actual
1654 test_expect_success
'format patch ignores color.ui' '
1655 test_unconfig color.ui &&
1656 git format-patch --stdout -1 >expect &&
1657 test_config color.ui always &&
1658 git format-patch --stdout -1 >actual &&
1659 test_cmp expect actual
1662 test_expect_success
'format patch respects diff.relative' '
1665 echo other content >subdir/file2 &&
1666 git add subdir/file2 &&
1667 git commit -F msg &&
1668 test_unconfig diff.relative &&
1669 git format-patch --relative=subdir --stdout -1 >expect &&
1670 test_config diff.relative true &&
1671 git -C subdir format-patch --stdout -1 >actual &&
1672 test_cmp expect actual
1675 test_expect_success
'cover letter with invalid --cover-from-description and config' '
1676 test_config branch.rebuild-1.description "config subject
1679 test_must_fail git format-patch --cover-letter --cover-from-description garbage main &&
1680 test_config format.coverFromDescription garbage &&
1681 test_must_fail git format-patch --cover-letter main
1684 test_expect_success
'cover letter with format.coverFromDescription = default' '
1685 test_config branch.rebuild-1.description "config subject
1688 test_config format.coverFromDescription default &&
1689 git checkout rebuild-1 &&
1690 git format-patch --stdout --cover-letter main >actual &&
1691 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1692 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1693 grep "^config subject$" actual &&
1694 grep "^body$" actual
1697 test_expect_success
'cover letter with --cover-from-description default' '
1698 test_config branch.rebuild-1.description "config subject
1701 git checkout rebuild-1 &&
1702 git format-patch --stdout --cover-letter --cover-from-description default main >actual &&
1703 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1704 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1705 grep "^config subject$" actual &&
1706 grep "^body$" actual
1709 test_expect_success
'cover letter with format.coverFromDescription = none' '
1710 test_config branch.rebuild-1.description "config subject
1713 test_config format.coverFromDescription none &&
1714 git checkout rebuild-1 &&
1715 git format-patch --stdout --cover-letter main >actual &&
1716 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1717 grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1718 ! grep "^config subject$" actual &&
1719 ! grep "^body$" actual
1722 test_expect_success
'cover letter with --cover-from-description none' '
1723 test_config branch.rebuild-1.description "config subject
1726 git checkout rebuild-1 &&
1727 git format-patch --stdout --cover-letter --cover-from-description none main >actual &&
1728 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1729 grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1730 ! grep "^config subject$" actual &&
1731 ! grep "^body$" actual
1734 test_expect_success
'cover letter with format.coverFromDescription = message' '
1735 test_config branch.rebuild-1.description "config subject
1738 test_config format.coverFromDescription message &&
1739 git checkout rebuild-1 &&
1740 git format-patch --stdout --cover-letter main >actual &&
1741 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1742 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1743 grep "^config subject$" actual &&
1744 grep "^body$" actual
1747 test_expect_success
'cover letter with --cover-from-description message' '
1748 test_config branch.rebuild-1.description "config subject
1751 git checkout rebuild-1 &&
1752 git format-patch --stdout --cover-letter --cover-from-description message main >actual &&
1753 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1754 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1755 grep "^config subject$" actual &&
1756 grep "^body$" actual
1759 test_expect_success
'cover letter with format.coverFromDescription = subject' '
1760 test_config branch.rebuild-1.description "config subject
1763 test_config format.coverFromDescription subject &&
1764 git checkout rebuild-1 &&
1765 git format-patch --stdout --cover-letter main >actual &&
1766 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1767 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1768 ! grep "^config subject$" actual &&
1769 grep "^body$" actual
1772 test_expect_success
'cover letter with --cover-from-description subject' '
1773 test_config branch.rebuild-1.description "config subject
1776 git checkout rebuild-1 &&
1777 git format-patch --stdout --cover-letter --cover-from-description subject main >actual &&
1778 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1779 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1780 ! grep "^config subject$" actual &&
1781 grep "^body$" actual
1784 test_expect_success
'cover letter with format.coverFromDescription = auto (short subject line)' '
1785 test_config branch.rebuild-1.description "config subject
1788 test_config format.coverFromDescription auto &&
1789 git checkout rebuild-1 &&
1790 git format-patch --stdout --cover-letter main >actual &&
1791 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1792 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1793 ! grep "^config subject$" actual &&
1794 grep "^body$" actual
1797 test_expect_success
'cover letter with --cover-from-description auto (short subject line)' '
1798 test_config branch.rebuild-1.description "config subject
1801 git checkout rebuild-1 &&
1802 git format-patch --stdout --cover-letter --cover-from-description auto main >actual &&
1803 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1804 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1805 ! grep "^config subject$" actual &&
1806 grep "^body$" actual
1809 test_expect_success
'cover letter with format.coverFromDescription = auto (long subject line)' '
1810 test_config branch.rebuild-1.description "this is a really long first line and it is over 100 characters long which is the threshold for long subjects
1813 test_config format.coverFromDescription auto &&
1814 git checkout rebuild-1 &&
1815 git format-patch --stdout --cover-letter main >actual &&
1816 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1817 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1818 grep "^this is a really long first line and it is over 100 characters long which is the threshold for long subjects$" actual &&
1819 grep "^body$" actual
1822 test_expect_success
'cover letter with --cover-from-description auto (long subject line)' '
1823 test_config branch.rebuild-1.description "this is a really long first line and it is over 100 characters long which is the threshold for long subjects
1826 git checkout rebuild-1 &&
1827 git format-patch --stdout --cover-letter --cover-from-description auto main >actual &&
1828 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1829 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1830 grep "^this is a really long first line and it is over 100 characters long which is the threshold for long subjects$" actual &&
1831 grep "^body$" actual
1834 test_expect_success
'cover letter with command-line --cover-from-description overrides config' '
1835 test_config branch.rebuild-1.description "config subject
1838 test_config format.coverFromDescription none &&
1839 git checkout rebuild-1 &&
1840 git format-patch --stdout --cover-letter --cover-from-description subject main >actual &&
1841 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1842 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1843 ! grep "^config subject$" actual &&
1844 grep "^body$" actual
1847 test_expect_success
'cover letter using branch description (1)' '
1848 git checkout rebuild-1 &&
1849 test_config branch.rebuild-1.description hello &&
1850 git format-patch --stdout --cover-letter main >actual &&
1854 test_expect_success
'cover letter using branch description (2)' '
1855 git checkout rebuild-1 &&
1856 test_config branch.rebuild-1.description hello &&
1857 git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
1861 test_expect_success
'cover letter using branch description (3)' '
1862 git checkout rebuild-1 &&
1863 test_config branch.rebuild-1.description hello &&
1864 git format-patch --stdout --cover-letter ^main rebuild-1 >actual &&
1868 test_expect_success
'cover letter using branch description (4)' '
1869 git checkout rebuild-1 &&
1870 test_config branch.rebuild-1.description hello &&
1871 git format-patch --stdout --cover-letter main.. >actual &&
1875 test_expect_success
'cover letter using branch description (5)' '
1876 git checkout rebuild-1 &&
1877 test_config branch.rebuild-1.description hello &&
1878 git format-patch --stdout --cover-letter -2 HEAD >actual &&
1882 test_expect_success
'cover letter using branch description (6)' '
1883 git checkout rebuild-1 &&
1884 test_config branch.rebuild-1.description hello &&
1885 git format-patch --stdout --cover-letter -2 >actual &&
1889 test_expect_success
'cover letter with nothing' '
1890 git format-patch --stdout --cover-letter >actual &&
1891 test_line_count = 0 actual
1894 test_expect_success
'cover letter auto' '
1896 test_when_finished "rm -rf tmp;
1897 git config --unset format.coverletter" &&
1899 git config format.coverletter auto &&
1900 git format-patch -o tmp -1 >list &&
1901 test_line_count = 1 list &&
1902 git format-patch -o tmp -2 >list &&
1903 test_line_count = 3 list
1906 test_expect_success
'cover letter auto user override' '
1908 test_when_finished "rm -rf tmp;
1909 git config --unset format.coverletter" &&
1911 git config format.coverletter auto &&
1912 git format-patch -o tmp --cover-letter -1 >list &&
1913 test_line_count = 2 list &&
1914 git format-patch -o tmp --cover-letter -2 >list &&
1915 test_line_count = 3 list &&
1916 git format-patch -o tmp --no-cover-letter -1 >list &&
1917 test_line_count = 1 list &&
1918 git format-patch -o tmp --no-cover-letter -2 >list &&
1919 test_line_count = 2 list
1922 test_expect_success
'format-patch --zero-commit' '
1923 git format-patch --zero-commit --stdout v2..v1 >patch2 &&
1924 grep "^From " patch2 | sort | uniq >actual &&
1925 echo "From $ZERO_OID Mon Sep 17 00:00:00 2001" >expect &&
1926 test_cmp expect actual
1929 test_expect_success
'From line has expected format' '
1930 git format-patch --stdout v2..v1 >patch2 &&
1931 grep "^From " patch2 >from &&
1932 grep "^From $OID_REGEX Mon Sep 17 00:00:00 2001$" patch2 >filtered &&
1933 test_cmp from filtered
1936 test_expect_success
'format-patch -o with no leading directories' '
1938 git format-patch -o patches main..side &&
1939 count=$(git rev-list --count main..side) &&
1941 test_line_count = $count list
1944 test_expect_success
'format-patch -o with leading existing directories' '
1945 rm -rf existing-dir &&
1946 mkdir existing-dir &&
1947 git format-patch -o existing-dir/patches main..side &&
1948 count=$(git rev-list --count main..side) &&
1949 ls existing-dir/patches >list &&
1950 test_line_count = $count list
1953 test_expect_success
'format-patch -o with leading non-existing directories' '
1954 rm -rf non-existing-dir &&
1955 git format-patch -o non-existing-dir/patches main..side &&
1956 count=$(git rev-list --count main..side) &&
1957 test_path_is_dir non-existing-dir &&
1958 ls non-existing-dir/patches >list &&
1959 test_line_count = $count list
1962 test_expect_success
'format-patch format.outputDirectory option' '
1963 test_config format.outputDirectory patches &&
1965 git format-patch main..side &&
1966 count=$(git rev-list --count main..side) &&
1968 test_line_count = $count list
1971 test_expect_success
'format-patch -o overrides format.outputDirectory' '
1972 test_config format.outputDirectory patches &&
1973 rm -fr patches patchset &&
1974 git format-patch main..side -o patchset &&
1975 test_path_is_missing patches &&
1976 test_path_is_dir patchset
1979 test_expect_success
'format-patch forbids multiple outputs' '
1980 rm -fr outfile outdir &&
1982 git format-patch --stdout --output-directory=outdir &&
1984 git format-patch --stdout --output=outfile &&
1986 git format-patch --output=outfile --output-directory=outdir
1989 test_expect_success
'configured outdir does not conflict with output options' '
1990 rm -fr outfile outdir &&
1991 test_config format.outputDirectory outdir &&
1992 git format-patch --stdout &&
1993 test_path_is_missing outdir &&
1994 git format-patch --output=outfile &&
1995 test_path_is_missing outdir
1998 test_expect_success
'format-patch --output' '
2000 git format-patch -3 --stdout HEAD >expect &&
2001 git format-patch -3 --output=outfile HEAD &&
2002 test_cmp expect outfile
2005 test_expect_success
'format-patch --cover-letter --output' '
2007 git format-patch --cover-letter -3 --stdout HEAD >expect &&
2008 git format-patch --cover-letter -3 --output=outfile HEAD &&
2009 test_cmp expect outfile
2012 test_expect_success
'format-patch --base' '
2013 git checkout patchid &&
2015 git format-patch --stdout --base=HEAD~3 -1 >patch &&
2016 tail -n 7 patch >actual1 &&
2018 git format-patch --stdout --base=HEAD~3 HEAD~.. >patch &&
2019 tail -n 7 patch >actual2 &&
2022 git rev-parse HEAD~3 >commit-id-base &&
2023 echo "base-commit: $(cat commit-id-base)" >>expect &&
2025 git show --patch HEAD~2 >patch &&
2026 git patch-id --stable <patch >patch.id.raw &&
2027 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>expect &&
2029 git show --patch HEAD~1 >patch &&
2030 git patch-id --stable <patch >patch.id.raw &&
2031 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>expect &&
2033 signature >>expect &&
2034 test_cmp expect actual1 &&
2035 test_cmp expect actual2 &&
2038 echo "base-commit: $(cat commit-id-base)" >>fail &&
2040 git show --patch HEAD~2 >patch &&
2041 git patch-id --unstable <patch >patch.id.raw &&
2042 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>fail &&
2044 git show --patch HEAD~1 >patch &&
2045 git patch-id --unstable <patch >patch.id.raw &&
2046 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>fail &&
2049 ! test_cmp fail actual1 &&
2050 ! test_cmp fail actual2
2053 test_expect_success
'format-patch --base errors out when base commit is in revision list' '
2054 test_must_fail git format-patch --base=HEAD -2 &&
2055 test_must_fail git format-patch --base=HEAD~1 -2 &&
2056 git format-patch --stdout --base=HEAD~2 -2 >patch &&
2057 grep "^base-commit:" patch >actual &&
2058 git rev-parse HEAD~2 >commit-id-base &&
2059 echo "base-commit: $(cat commit-id-base)" >expect &&
2060 test_cmp expect actual
2063 test_expect_success
'format-patch --base errors out when base commit is not ancestor of revision list' '
2064 # For history as below:
2066 # ---Q---P---Z---Y---*---X
2070 # If "format-patch Z..X" is given, P and Z can not be specified as the base commit
2071 git checkout -b topic1 main &&
2072 git rev-parse HEAD >commit-id-base &&
2074 git rev-parse HEAD >commit-id-P &&
2076 git rev-parse HEAD >commit-id-Z &&
2078 git checkout -b topic2 main &&
2082 test_must_fail git format-patch --base=$(cat commit-id-P) -3 &&
2083 test_must_fail git format-patch --base=$(cat commit-id-Z) -3 &&
2084 git format-patch --stdout --base=$(cat commit-id-base) -3 >patch &&
2085 grep "^base-commit:" patch >actual &&
2086 echo "base-commit: $(cat commit-id-base)" >expect &&
2087 test_cmp expect actual
2090 test_expect_success
'format-patch --base=auto' '
2091 git checkout -b upstream main &&
2092 git checkout -b local upstream &&
2093 git branch --set-upstream-to=upstream &&
2096 git format-patch --stdout --base=auto -2 >patch &&
2097 grep "^base-commit:" patch >actual &&
2098 git rev-parse upstream >commit-id-base &&
2099 echo "base-commit: $(cat commit-id-base)" >expect &&
2100 test_cmp expect actual
2103 test_expect_success
'format-patch errors out when history involves criss-cross' '
2104 # setup criss-cross history
2112 git checkout main &&
2114 git checkout -b xb main &&
2116 git checkout -b xc main &&
2118 git checkout -b xbc xb -- &&
2120 git checkout -b xcb xc -- &&
2121 git branch --set-upstream-to=xbc &&
2127 test_must_fail git format-patch --base=auto -1
2130 test_expect_success
'format-patch format.useAutoBase whenAble history involves criss-cross' '
2131 test_config format.useAutoBase whenAble &&
2132 git format-patch -1 >patch &&
2133 ! grep "^base-commit:" patch
2136 test_expect_success
'format-patch format.useAutoBase option' '
2137 git checkout local &&
2138 test_config format.useAutoBase true &&
2139 git format-patch --stdout -1 >patch &&
2140 grep "^base-commit:" patch >actual &&
2141 git rev-parse upstream >commit-id-base &&
2142 echo "base-commit: $(cat commit-id-base)" >expect &&
2143 test_cmp expect actual
2146 test_expect_success
'format-patch format.useAutoBase option with whenAble' '
2147 git checkout local &&
2148 test_config format.useAutoBase whenAble &&
2149 git format-patch --stdout -1 >patch &&
2150 grep "^base-commit:" patch >actual &&
2151 git rev-parse upstream >commit-id-base &&
2152 echo "base-commit: $(cat commit-id-base)" >expect &&
2153 test_cmp expect actual
2156 test_expect_success
'format-patch --base overrides format.useAutoBase' '
2157 test_config format.useAutoBase true &&
2158 git format-patch --stdout --base=HEAD~1 -1 >patch &&
2159 grep "^base-commit:" patch >actual &&
2160 git rev-parse HEAD~1 >commit-id-base &&
2161 echo "base-commit: $(cat commit-id-base)" >expect &&
2162 test_cmp expect actual
2165 test_expect_success
'format-patch --no-base overrides format.useAutoBase' '
2166 test_config format.useAutoBase true &&
2167 git format-patch --stdout --no-base -1 >patch &&
2168 ! grep "^base-commit:" patch
2171 test_expect_success
'format-patch --no-base overrides format.useAutoBase whenAble' '
2172 test_config format.useAutoBase whenAble &&
2173 git format-patch --stdout --no-base -1 >patch &&
2174 ! grep "^base-commit:" patch
2177 test_expect_success
'format-patch --base with --attach' '
2178 git format-patch --attach=mimemime --stdout --base=HEAD~ -1 >patch &&
2179 sed -n -e "/^base-commit:/s/.*/1/p" -e "/^---*mimemime--$/s/.*/2/p" \
2181 test_write_lines 1 2 >expect &&
2182 test_cmp expect actual
2184 test_expect_success
'format-patch --attach cover-letter only is non-multipart' '
2185 test_when_finished "rm -fr patches" &&
2186 git format-patch -o patches --cover-letter --attach=mimemime --base=HEAD~ -1 &&
2187 ! egrep "^--+mimemime" patches/0000*.patch &&
2188 egrep "^--+mimemime$" patches/0001*.patch >output &&
2189 test_line_count = 2 output &&
2190 egrep "^--+mimemime--$" patches/0001*.patch >output &&
2191 test_line_count = 1 output
2194 test_expect_success
'format-patch --pretty=mboxrd' '
2196 cat >msg <<-INPUT_END &&
2197 mboxrd should escape the body
2199 From could trip up a loose mbox parser
2200 >From extra escape for reversibility
2201 >>From extra escape for reversibility 2
2202 from lower case not escaped
2203 Fromm bad speling not escaped
2204 From with leading space not escaped
2213 cat >expect <<-INPUT_END &&
2214 >From could trip up a loose mbox parser
2215 >>From extra escape for reversibility
2216 >>>From extra escape for reversibility 2
2217 from lower case not escaped
2218 Fromm bad speling not escaped
2219 From with leading space not escaped
2228 C=$(git commit-tree HEAD^^{tree} -p HEAD <msg) &&
2229 git format-patch --pretty=mboxrd --stdout -1 $C~1..$C >patch &&
2230 git grep -h --no-index -A11 \
2231 "^>From could trip up a loose mbox parser" patch >actual &&
2232 test_cmp expect actual
2235 test_expect_success
'interdiff: setup' '
2236 git checkout -b boop main &&
2237 test_commit fnorp blorp &&
2238 test_commit fleep blorp
2241 test_expect_success
'interdiff: cover-letter' '
2242 sed "y/q/ /" >expect <<-\EOF &&
2246 git format-patch --cover-letter --interdiff=boop~2 -1 boop &&
2247 test_i18ngrep "^Interdiff:$" 0000-cover-letter.patch &&
2248 test_i18ngrep ! "^Interdiff:$" 0001-fleep.patch &&
2249 sed "1,/^@@ /d; /^-- $/q" 0000-cover-letter.patch >actual &&
2250 test_cmp expect actual
2253 test_expect_success
'interdiff: reroll-count' '
2254 git format-patch --cover-letter --interdiff=boop~2 -v2 -1 boop &&
2255 test_i18ngrep "^Interdiff ..* v1:$" v2-0000-cover-letter.patch
2258 test_expect_success
'interdiff: solo-patch' '
2259 cat >expect <<-\EOF &&
2263 git format-patch --interdiff=boop~2 -1 boop &&
2264 test_i18ngrep "^Interdiff:$" 0001-fleep.patch &&
2265 sed "1,/^ @@ /d; /^$/q" 0001-fleep.patch >actual &&
2266 test_cmp expect actual