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 test_write_lines 1 2 3 4 5 6 7 8 9 10 >file &&
19 git commit -m Initial &&
20 git checkout -b side &&
22 test_write_lines 1 2 5 6 A B C 7 8 9 10 >file &&
25 git commit -m "Side changes #1" &&
27 test_write_lines D E F >>file &&
28 git update-index file &&
30 git commit -m "Side changes #2" &&
33 test_write_lines 5 6 1 2 3 A 4 B C 7 8 9 10 D E F >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 test_write_lines 5 6 1 2 3 A 4 B C 7 8 9 10 D E F >file2 &&
47 test_write_lines 1 2 3 A 4 B C 7 8 9 10 D E F 5 6 >file3 &&
48 test_write_lines 8 9 10 >file &&
49 git add file file2 file3 &&
51 git commit -m "patchid 1" &&
52 test_write_lines 4 A B 7 8 9 10 >file2 &&
53 test_write_lines 8 9 10 5 6 >file3 &&
54 git add file2 file3 &&
56 git commit -m "patchid 2" &&
57 test_write_lines 10 5 6 >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 || exit 1
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 || exit 1
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 || exit 1
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
389 test_expect_success
'reroll count (-v) with a fractional number' '
391 git format-patch -o patches --cover-letter -v4.4 main..side >list &&
392 ! grep -v "^patches/v4.4-000[0-3]-" list &&
393 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
394 ! grep -v "^Subject: \[PATCH v4.4 [0-3]/3\] " subjects
397 test_expect_success
'reroll (-v) count with a non number' '
399 git format-patch -o patches --cover-letter -v4rev2 main..side >list &&
400 ! grep -v "^patches/v4rev2-000[0-3]-" list &&
401 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
402 ! grep -v "^Subject: \[PATCH v4rev2 [0-3]/3\] " subjects
405 test_expect_success
'reroll (-v) count with a non-pathname character' '
407 git format-patch -o patches --cover-letter -v4---..././../--1/.2// main..side >list &&
408 ! grep -v "patches/v4-\.-\.-\.-1-\.2-000[0-3]-" list &&
409 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
410 ! grep -v "^Subject: \[PATCH v4---\.\.\./\./\.\./--1/\.2// [0-3]/3\] " subjects
416 git format-patch
--stdout "$@" >patch &&
417 # Prints everything between the Message-ID and In-Reply-To,
418 # and replaces all Message-ID-lookalikes by a sequence number
420 if (/^(message-id|references|in-reply-to)/i) {
426 $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
427 for $k (keys %h) {s/$k/$h{$k}/};
430 print "---\n" if /^From /i;
432 test_cmp
"$expect" actual
435 cat >>expect.no-threading
<<EOF
441 test_expect_success
'no threading' '
443 check_threading expect.no-threading main
446 cat >expect.thread
<<EOF
459 test_expect_success
'thread' '
460 check_threading expect.thread --thread main
463 cat >expect.in-reply-to
<<EOF
478 test_expect_success
'thread in-reply-to' '
479 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
483 cat >expect.cover-letter
<<EOF
500 test_expect_success
'thread cover-letter' '
501 check_threading expect.cover-letter --cover-letter --thread main
504 cat >expect.cl-irt
<<EOF
526 test_expect_success
'thread cover-letter in-reply-to' '
527 check_threading expect.cl-irt --cover-letter \
528 --in-reply-to="<test.message>" --thread main
531 test_expect_success
'thread explicit shallow' '
532 check_threading expect.cl-irt --cover-letter \
533 --in-reply-to="<test.message>" --thread=shallow main
536 cat >expect.deep
<<EOF
550 test_expect_success
'thread deep' '
551 check_threading expect.deep --thread=deep main
554 cat >expect.deep-irt
<<EOF
572 test_expect_success
'thread deep in-reply-to' '
573 check_threading expect.deep-irt --thread=deep \
574 --in-reply-to="<test.message>" main
577 cat >expect.deep-cl
<<EOF
597 test_expect_success
'thread deep cover-letter' '
598 check_threading expect.deep-cl --cover-letter --thread=deep main
601 cat >expect.deep-cl-irt
<<EOF
626 test_expect_success
'thread deep cover-letter in-reply-to' '
627 check_threading expect.deep-cl-irt --cover-letter \
628 --in-reply-to="<test.message>" --thread=deep main
631 test_expect_success
'thread via config' '
632 test_config format.thread true &&
633 check_threading expect.thread main
636 test_expect_success
'thread deep via config' '
637 test_config format.thread deep &&
638 check_threading expect.deep main
641 test_expect_success
'thread config + override' '
642 test_config format.thread deep &&
643 check_threading expect.thread --thread main
646 test_expect_success
'thread config + --no-thread' '
647 test_config format.thread deep &&
648 check_threading expect.no-threading --no-thread main
651 test_expect_success
'excessive subject' '
654 before=$(git hash-object file) &&
655 before=$(git rev-parse --short $before) &&
656 test_write_lines 5 6 1 2 3 A 4 B C 7 8 9 10 D E F >>file &&
657 after=$(git hash-object file) &&
658 after=$(git rev-parse --short $after) &&
659 git update-index file &&
660 git commit -m "This is an excessively long subject line for a message due to the habit some projects have of not having a short, one-line subject at the start of the commit message, but rather sticking a whole paragraph right at the start as the only thing in the commit message. It had better not become the filename for the patch." &&
661 git format-patch -o patches/ main..side &&
662 ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
665 test_expect_success
'failure to write cover-letter aborts gracefully' '
666 test_when_finished "rmdir 0000-cover-letter.patch" &&
667 mkdir 0000-cover-letter.patch &&
668 test_must_fail git format-patch --no-renames --cover-letter -1
671 test_expect_success
'cover-letter inherits diff options' '
674 git format-patch --no-renames --cover-letter -1 &&
675 check_patch 0000-cover-letter.patch &&
676 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
677 git format-patch --cover-letter -1 -M &&
678 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
682 This is an excessively long subject line for a message due to the
683 habit some projects have of not having a short, one-line subject at
684 the start of the commit message, but rather sticking a whole
685 paragraph right at the start as the only thing in the commit
686 message. It had better not become the filename for the patch.
691 test_expect_success
'shortlog of cover-letter wraps overly-long onelines' '
692 git format-patch --cover-letter -2 &&
693 sed -e "1,/A U Thor/d" -e "/^\$/q" 0000-cover-letter.patch >output &&
694 test_cmp expect output
698 index $before..$after 100644
709 test_expect_success
'format-patch respects -U' '
710 git format-patch -U4 -2 &&
711 sed -e "1,/^diff/d" -e "/^+5/q" \
712 <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
714 test_cmp expect output
719 diff --git a/file b/file
720 index $before..$after 100644
730 test_expect_success
'format-patch -p suppresses stat' '
731 git format-patch -p -2 &&
732 sed -e "1,/^\$/d" -e "/^+5/q" 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch >output &&
733 test_cmp expect output
736 test_expect_success
'format-patch from a subdirectory (1)' '
747 echo "Oops? $filename"
754 test_expect_success
'format-patch from a subdirectory (2)' '
759 git format-patch -1 -o ..
765 echo "Oops? $filename"
769 basename=$(expr "$filename" : ".*/\(.*\)") &&
770 test -f "sub/$basename"
773 test_expect_success
'format-patch from a subdirectory (3)' '
779 git format-patch -1 -o "$TRASH_DIRECTORY"
781 basename=$(expr "$filename" : ".*/\(.*\)") &&
785 test_expect_success
'format-patch --in-reply-to' '
786 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" >patch8 &&
787 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
788 grep "^References: <baz@foo.bar>" patch8
791 test_expect_success
'format-patch --signoff' '
792 git format-patch -1 --signoff --stdout >out &&
793 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
796 test_expect_success
'format-patch --notes --signoff' '
797 git notes --ref test add -m "test message" HEAD &&
798 git format-patch -1 --signoff --stdout --notes=test >out &&
799 # Three dashes must come after S-o-b
800 ! sed "/^Signed-off-by: /q" out | grep "test message" &&
801 sed "1,/^Signed-off-by: /d" out | grep "test message" &&
802 # Notes message must come after three dashes
803 ! sed "/^---$/q" out | grep "test message" &&
804 sed "1,/^---$/d" out | grep "test message"
807 test_expect_success
'format-patch notes output control' '
808 git notes add -m "notes config message" HEAD &&
809 test_when_finished git notes remove HEAD &&
811 git format-patch -1 --stdout >out &&
812 ! grep "notes config message" out &&
813 git format-patch -1 --stdout --notes >out &&
814 grep "notes config message" out &&
815 git format-patch -1 --stdout --no-notes >out &&
816 ! grep "notes config message" out &&
817 git format-patch -1 --stdout --notes --no-notes >out &&
818 ! grep "notes config message" out &&
819 git format-patch -1 --stdout --no-notes --notes >out &&
820 grep "notes config message" out &&
822 test_config format.notes true &&
823 git format-patch -1 --stdout >out &&
824 grep "notes config message" out &&
825 git format-patch -1 --stdout --notes >out &&
826 grep "notes config message" out &&
827 git format-patch -1 --stdout --no-notes >out &&
828 ! grep "notes config message" out &&
829 git format-patch -1 --stdout --notes --no-notes >out &&
830 ! grep "notes config message" out &&
831 git format-patch -1 --stdout --no-notes --notes >out &&
832 grep "notes config message" out
835 test_expect_success
'format-patch with multiple notes refs' '
836 git notes --ref note1 add -m "this is note 1" HEAD &&
837 test_when_finished git notes --ref note1 remove HEAD &&
838 git notes --ref note2 add -m "this is note 2" HEAD &&
839 test_when_finished git notes --ref note2 remove HEAD &&
841 git format-patch -1 --stdout >out &&
842 ! grep "this is note 1" out &&
843 ! grep "this is note 2" out &&
844 git format-patch -1 --stdout --notes=note1 >out &&
845 grep "this is note 1" out &&
846 ! grep "this is note 2" out &&
847 git format-patch -1 --stdout --notes=note2 >out &&
848 ! grep "this is note 1" out &&
849 grep "this is note 2" out &&
850 git format-patch -1 --stdout --notes=note1 --notes=note2 >out &&
851 grep "this is note 1" out &&
852 grep "this is note 2" out &&
854 test_config format.notes note1 &&
855 git format-patch -1 --stdout >out &&
856 grep "this is note 1" out &&
857 ! grep "this is note 2" out &&
858 git format-patch -1 --stdout --no-notes >out &&
859 ! grep "this is note 1" out &&
860 ! grep "this is note 2" out &&
861 git format-patch -1 --stdout --notes=note2 >out &&
862 grep "this is note 1" out &&
863 grep "this is note 2" out &&
864 git format-patch -1 --stdout --no-notes --notes=note2 >out &&
865 ! grep "this is note 1" out &&
866 grep "this is note 2" out &&
868 git config --add format.notes note2 &&
869 git format-patch -1 --stdout >out &&
870 grep "this is note 1" out &&
871 grep "this is note 2" out &&
872 git format-patch -1 --stdout --no-notes >out &&
873 ! grep "this is note 1" out &&
874 ! grep "this is note 2" out
877 test_expect_success
'format-patch with multiple notes refs in config' '
878 test_when_finished "test_unconfig format.notes" &&
880 git notes --ref note1 add -m "this is note 1" HEAD &&
881 test_when_finished git notes --ref note1 remove HEAD &&
882 git notes --ref note2 add -m "this is note 2" HEAD &&
883 test_when_finished git notes --ref note2 remove HEAD &&
885 git config format.notes note1 &&
886 git format-patch -1 --stdout >out &&
887 grep "this is note 1" out &&
888 ! grep "this is note 2" out &&
889 git config format.notes note2 &&
890 git format-patch -1 --stdout >out &&
891 ! grep "this is note 1" out &&
892 grep "this is note 2" out &&
893 git config --add format.notes note1 &&
894 git format-patch -1 --stdout >out &&
895 grep "this is note 1" out &&
896 grep "this is note 2" out &&
898 git config --replace-all format.notes note1 &&
899 git config --add format.notes false &&
900 git format-patch -1 --stdout >out &&
901 ! grep "this is note 1" out &&
902 ! grep "this is note 2" out &&
903 git config --add format.notes note2 &&
904 git format-patch -1 --stdout >out &&
905 ! grep "this is note 1" out &&
906 grep "this is note 2" out
909 echo "fatal: --name-only does not make sense" >expect.name-only
910 echo "fatal: --name-status does not make sense" >expect.name-status
911 echo "fatal: --check does not make sense" >expect.check
913 test_expect_success
'options no longer allowed for format-patch' '
914 test_must_fail git format-patch --name-only 2>output &&
915 test_cmp expect.name-only output &&
916 test_must_fail git format-patch --name-status 2>output &&
917 test_cmp expect.name-status output &&
918 test_must_fail git format-patch --check 2>output &&
919 test_cmp expect.check output
922 test_expect_success
'format-patch --numstat should produce a patch' '
923 git format-patch --numstat --stdout main..side >output &&
924 grep "^diff --git a/" output >diff &&
925 test_line_count = 5 diff
928 test_expect_success
'format-patch -- <path>' '
930 git checkout -b pathspec main &&
932 echo file_a 1 >file_a &&
933 echo file_b 1 >file_b &&
934 git add file_a file_b &&
935 git commit -m pathspec_initial &&
937 echo file_a 2 >>file_a &&
939 git commit -m pathspec_a &&
941 echo file_b 2 >>file_b &&
943 git commit -m pathspec_b &&
945 echo file_a 3 >>file_a &&
946 echo file_b 3 >>file_b &&
947 git add file_a file_b &&
948 git commit -m pathspec_ab &&
950 cat >expect <<-\EOF &&
951 0001-pathspec_initial.patch
952 0002-pathspec_a.patch
953 0003-pathspec_ab.patch
956 git format-patch main..pathspec -- file_a >output &&
957 test_cmp expect output &&
958 ! grep file_b *.patch
961 test_expect_success
'format-patch --ignore-if-in-upstream HEAD' '
963 git format-patch --ignore-if-in-upstream HEAD
966 test_expect_success
'get git version' '
967 git_version=$(git --version) &&
968 git_version=${git_version##* }
972 printf "%s\n%s\n\n" "-- " "${1:-$git_version}"
975 test_expect_success
'format-patch default signature' '
976 git format-patch --stdout -1 >patch &&
977 tail -n 3 patch >output &&
979 test_cmp expect output
982 test_expect_success
'format-patch --signature' '
983 git format-patch --stdout --signature="my sig" -1 >patch &&
984 tail -n 3 patch >output &&
985 signature "my sig" >expect &&
986 test_cmp expect output
989 test_expect_success
'format-patch with format.signature config' '
990 git config format.signature "config sig" &&
991 git format-patch --stdout -1 >output &&
992 grep "config sig" output
995 test_expect_success
'format-patch --signature overrides format.signature' '
996 git config format.signature "config sig" &&
997 git format-patch --stdout --signature="overrides" -1 >output &&
998 ! grep "config sig" output &&
999 grep "overrides" output
1002 test_expect_success
'format-patch --no-signature ignores format.signature' '
1003 git config format.signature "config sig" &&
1004 git format-patch --stdout --signature="my sig" --no-signature \
1006 check_patch output &&
1007 ! grep "config sig" output &&
1008 ! grep "my sig" output &&
1009 ! grep "^-- \$" output
1012 test_expect_success
'format-patch --signature --cover-letter' '
1013 git config --unset-all format.signature &&
1014 git format-patch --stdout --signature="my sig" --cover-letter \
1016 grep "my sig" output >sig &&
1017 test_line_count = 2 sig
1020 test_expect_success
'format.signature="" suppresses signatures' '
1021 git config format.signature "" &&
1022 git format-patch --stdout -1 >output &&
1023 check_patch output &&
1024 ! grep "^-- \$" output
1027 test_expect_success
'format-patch --no-signature suppresses signatures' '
1028 git config --unset-all format.signature &&
1029 git format-patch --stdout --no-signature -1 >output &&
1030 check_patch output &&
1031 ! grep "^-- \$" output
1034 test_expect_success
'format-patch --signature="" suppresses signatures' '
1035 git format-patch --stdout --signature="" -1 >output &&
1036 check_patch output &&
1037 ! grep "^-- \$" output
1040 test_expect_success
'prepare mail-signature input' '
1041 cat >mail-signature <<-\EOF
1043 Test User <test.email@kernel.org>
1044 http://git.kernel.org/cgit/git/git.git
1046 git.kernel.org/?p=git/git.git;a=summary
1051 test_expect_success
'--signature-file=file works' '
1052 git format-patch --stdout --signature-file=mail-signature -1 >output &&
1053 check_patch output &&
1054 sed -e "1,/^-- \$/d" output >actual &&
1056 cat mail-signature && echo
1058 test_cmp expect actual
1061 test_expect_success
'format.signaturefile works' '
1062 test_config format.signaturefile mail-signature &&
1063 git format-patch --stdout -1 >output &&
1064 check_patch output &&
1065 sed -e "1,/^-- \$/d" output >actual &&
1067 cat mail-signature && echo
1069 test_cmp expect actual
1072 test_expect_success
'--no-signature suppresses format.signaturefile ' '
1073 test_config format.signaturefile mail-signature &&
1074 git format-patch --stdout --no-signature -1 >output &&
1075 check_patch output &&
1076 ! grep "^-- \$" output
1079 test_expect_success
'--signature-file overrides format.signaturefile' '
1080 cat >other-mail-signature <<-\EOF &&
1081 Use this other signature instead of mail-signature.
1083 test_config format.signaturefile mail-signature &&
1084 git format-patch --stdout \
1085 --signature-file=other-mail-signature -1 >output &&
1086 check_patch output &&
1087 sed -e "1,/^-- \$/d" output >actual &&
1089 cat other-mail-signature && echo
1091 test_cmp expect actual
1094 test_expect_success
'--signature overrides format.signaturefile' '
1095 test_config format.signaturefile mail-signature &&
1096 git format-patch --stdout --signature="my sig" -1 >output &&
1097 check_patch output &&
1098 grep "my sig" output
1101 test_expect_success TTY
'format-patch --stdout paginates' '
1103 test_terminal env GIT_PAGER="wc >pager_used" git format-patch --stdout --all &&
1104 test_path_is_file pager_used
1107 test_expect_success TTY
'format-patch --stdout pagination can be disabled' '
1109 test_terminal env GIT_PAGER="wc >pager_used" git --no-pager format-patch --stdout --all &&
1110 test_terminal env GIT_PAGER="wc >pager_used" git -c "pager.format-patch=false" format-patch --stdout --all &&
1111 test_path_is_missing pager_used &&
1112 test_path_is_missing .git/pager_used
1115 test_expect_success
'format-patch handles multi-line subjects' '
1117 echo content >>file &&
1118 test_write_lines one two three >msg &&
1120 git commit -F msg &&
1121 git format-patch -o patches -1 &&
1122 grep ^Subject: patches/0001-one.patch >actual &&
1123 echo "Subject: [PATCH] one two three" >expect &&
1124 test_cmp expect actual
1127 test_expect_success
'format-patch handles multi-line encoded subjects' '
1129 echo content >>file &&
1130 test_write_lines en två tre >msg &&
1132 git commit -F msg &&
1133 git format-patch -o patches -1 &&
1134 grep ^Subject: patches/0001-en.patch >actual &&
1135 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
1136 test_cmp expect actual
1140 M64
=$M8$M8$M8$M8$M8$M8$M8$M8
1141 M512
=$M64$M64$M64$M64$M64$M64$M64$M64
1143 Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1144 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1145 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1146 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1147 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1148 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1149 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1151 test_expect_success
'format-patch wraps extremely long subject (ascii)' '
1152 echo content >>file &&
1154 git commit -m "$M512" &&
1155 git format-patch --stdout -1 >patch &&
1156 sed -n "/^Subject/p; /^ /p; /^$/q" patch >subject &&
1157 test_cmp expect subject
1161 M64
=$M8$M8$M8$M8$M8$M8$M8$M8
1162 M512
=$M64$M64$M64$M64$M64$M64$M64$M64
1164 Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1165 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1166 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1167 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1168 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1169 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1170 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1171 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1172 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1173 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1174 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1175 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1176 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1177 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1178 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1179 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1180 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1181 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1182 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1183 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1184 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1185 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1186 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1189 test_expect_success
'format-patch wraps extremely long subject (rfc2047)' '
1191 echo content >>file &&
1193 git commit -m "$M512" &&
1194 git format-patch --stdout -1 >patch &&
1195 sed -n "/^Subject/p; /^ /p; /^$/q" patch >subject &&
1196 test_cmp expect subject
1200 echo content
>>file &&
1202 GIT_AUTHOR_NAME
=$1 git commit
-m author-check
&&
1203 git format-patch
--stdout -1 >patch &&
1204 sed -n "/^From: /p; /^ /p; /^$/q" patch >actual
&&
1205 test_cmp expect actual
1209 From: "Foo B. Bar" <author@example.com>
1211 test_expect_success
'format-patch quotes dot in from-headers' '
1212 check_author "Foo B. Bar"
1216 From: "Foo \"The Baz\" Bar" <author@example.com>
1218 test_expect_success
'format-patch quotes double-quote in from-headers' '
1219 check_author "Foo \"The Baz\" Bar"
1223 From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
1225 test_expect_success
'format-patch uses rfc2047-encoded from-headers when necessary' '
1226 check_author "Föo Bar"
1230 From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
1232 test_expect_success
'rfc2047-encoded from-headers leave no rfc822 specials' '
1233 check_author "Föo B. Bar"
1237 From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
1238 <author@example.com>
1240 test_expect_success
'format-patch wraps moderately long from-header (ascii)' '
1241 check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
1245 From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1246 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1247 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
1249 test_expect_success
'format-patch wraps extremely long from-header (ascii)' '
1250 check_author "Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar"
1254 From: "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1255 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1256 Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
1258 test_expect_success
'format-patch wraps extremely long from-header (rfc822)' '
1259 check_author "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar"
1263 From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
1264 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
1265 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
1266 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
1267 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
1269 test_expect_success
'format-patch wraps extremely long from-header (rfc2047)' '
1270 check_author "Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar"
1274 From: Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1275 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1276 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
1278 test_expect_success
'format-patch wraps extremely long from-header (non-ASCII without Q-encoding)' '
1279 echo content >>file &&
1281 GIT_AUTHOR_NAME="Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar" \
1282 git commit -m author-check &&
1283 git format-patch --no-encode-email-headers --stdout -1 >patch &&
1284 sed -n "/^From: /p; /^ /p; /^$/q" patch >actual &&
1285 test_cmp expect actual
1289 Subject: [PATCH] Foö
1291 test_expect_success
'subject lines are unencoded with --no-encode-email-headers' '
1292 echo content >>file &&
1294 git commit -m "Foö" &&
1295 git format-patch --no-encode-email-headers -1 --stdout >patch &&
1296 grep ^Subject: patch >actual &&
1297 test_cmp expect actual
1301 Subject: [PATCH] Foö
1303 test_expect_success
'subject lines are unencoded with format.encodeEmailHeaders=false' '
1304 echo content >>file &&
1306 git commit -m "Foö" &&
1307 git config format.encodeEmailHeaders false &&
1308 git format-patch -1 --stdout >patch &&
1309 grep ^Subject: patch >actual &&
1310 test_cmp expect actual
1314 Subject: [PATCH] =?UTF-8?q?Fo=C3=B6?=
1316 test_expect_success
'--encode-email-headers overrides format.encodeEmailHeaders' '
1317 echo content >>file &&
1319 git commit -m "Foö" &&
1320 git config format.encodeEmailHeaders false &&
1321 git format-patch --encode-email-headers -1 --stdout >patch &&
1322 grep ^Subject: patch >actual &&
1323 test_cmp expect actual
1327 Subject: header with . in it
1329 test_expect_success
'subject lines do not have 822 atom-quoting' '
1330 echo content >>file &&
1332 git commit -m "header with . in it" &&
1333 git format-patch -k -1 --stdout >patch &&
1334 grep ^Subject: patch >actual &&
1335 test_cmp expect actual
1339 Subject: [PREFIX 1/1] header with . in it
1341 test_expect_success
'subject prefixes have space prepended' '
1342 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
1343 grep ^Subject: patch >actual &&
1344 test_cmp expect actual
1348 Subject: [1/1] header with . in it
1350 test_expect_success
'empty subject prefix does not have extra space' '
1351 git format-patch -n -1 --stdout --subject-prefix= >patch &&
1352 grep ^Subject: patch >actual &&
1353 test_cmp expect actual
1356 test_expect_success
'--rfc' '
1357 cat >expect <<-\EOF &&
1358 Subject: [RFC PATCH 1/1] header with . in it
1360 git format-patch -n -1 --stdout --rfc >patch &&
1361 grep ^Subject: patch >actual &&
1362 test_cmp expect actual
1365 test_expect_success
'--from=ident notices bogus ident' '
1366 test_must_fail git format-patch -1 --stdout --from=foo >patch
1369 test_expect_success
'--from=ident replaces author' '
1370 git format-patch -1 --stdout --from="Me <me@example.com>" >patch &&
1371 cat >expect <<-\EOF &&
1372 From: Me <me@example.com>
1374 From: A U Thor <author@example.com>
1377 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1378 test_cmp expect patch.head
1381 test_expect_success
'--from uses committer ident' '
1382 git format-patch -1 --stdout --from >patch &&
1383 cat >expect <<-\EOF &&
1384 From: C O Mitter <committer@example.com>
1386 From: A U Thor <author@example.com>
1389 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1390 test_cmp expect patch.head
1393 test_expect_success
'--from omits redundant in-body header' '
1394 git format-patch -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1395 cat >expect <<-\EOF &&
1396 From: A U Thor <author@example.com>
1399 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1400 test_cmp expect patch.head
1403 test_expect_success
'with --force-in-body-from, redundant in-body from is kept' '
1404 git format-patch --force-in-body-from \
1405 -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1406 cat >expect <<-\EOF &&
1407 From: A U Thor <author@example.com>
1409 From: A U Thor <author@example.com>
1412 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1413 test_cmp expect patch.head
1416 test_expect_success
'in-body headers trigger content encoding' '
1417 test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
1418 test_when_finished "git reset --hard HEAD^" &&
1419 git format-patch -1 --stdout --from >patch &&
1420 cat >expect <<-\EOF &&
1421 From: C O Mitter <committer@example.com>
1422 Content-Type: text/plain; charset=UTF-8
1424 From: éxötìc <author@example.com>
1427 sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" patch >patch.head &&
1428 test_cmp expect patch.head
1433 C
=$
(git commit-tree HEAD^^
{tree
} -p HEAD
) &&
1434 git format-patch
--stdout --signoff $C^..
$C >append_signoff.
patch &&
1435 sed -n -e "1,/^---$/p" append_signoff.
patch |
1436 egrep -n "^Subject|Sign|^$"
1439 test_expect_success
'signoff: commit with no body' '
1440 append_signoff </dev/null >actual &&
1441 cat <<-\EOF | sed "s/EOL$//" >expect &&
1442 4:Subject: [PATCH] EOL
1444 9:Signed-off-by: C O Mitter <committer@example.com>
1446 test_cmp expect actual
1449 test_expect_success
'signoff: commit with only subject' '
1450 echo subject | append_signoff >actual &&
1451 cat >expect <<-\EOF &&
1452 4:Subject: [PATCH] subject
1454 9:Signed-off-by: C O Mitter <committer@example.com>
1456 test_cmp expect actual
1459 test_expect_success
'signoff: commit with only subject that does not end with NL' '
1460 printf subject | append_signoff >actual &&
1461 cat >expect <<-\EOF &&
1462 4:Subject: [PATCH] subject
1464 9:Signed-off-by: C O Mitter <committer@example.com>
1466 test_cmp expect actual
1469 test_expect_success
'signoff: no existing signoffs' '
1470 append_signoff <<-\EOF >actual &&
1475 cat >expect <<-\EOF &&
1476 4:Subject: [PATCH] subject
1479 11:Signed-off-by: C O Mitter <committer@example.com>
1481 test_cmp expect actual
1484 test_expect_success
'signoff: no existing signoffs and no trailing NL' '
1485 printf "subject\n\nbody" | append_signoff >actual &&
1486 cat >expect <<-\EOF &&
1487 4:Subject: [PATCH] subject
1490 11:Signed-off-by: C O Mitter <committer@example.com>
1492 test_cmp expect actual
1495 test_expect_success
'signoff: some random signoff' '
1496 append_signoff <<-\EOF >actual &&
1501 Signed-off-by: my@house
1503 cat >expect <<-\EOF &&
1504 4:Subject: [PATCH] subject
1507 11:Signed-off-by: my@house
1508 12:Signed-off-by: C O Mitter <committer@example.com>
1510 test_cmp expect actual
1513 test_expect_success
'signoff: misc conforming footer elements' '
1514 append_signoff <<-\EOF >actual &&
1519 Signed-off-by: my@house
1520 (cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1521 Tested-by: Some One <someone@example.com>
1524 cat >expect <<-\EOF &&
1525 4:Subject: [PATCH] subject
1528 11:Signed-off-by: my@house
1529 15:Signed-off-by: C O Mitter <committer@example.com>
1531 test_cmp expect actual
1534 test_expect_success
'signoff: some random signoff-alike' '
1535 append_signoff <<-\EOF >actual &&
1539 Fooled-by-me: my@house
1541 cat >expect <<-\EOF &&
1542 4:Subject: [PATCH] subject
1545 12:Signed-off-by: C O Mitter <committer@example.com>
1547 test_cmp expect actual
1550 test_expect_success
'signoff: not really a signoff' '
1551 append_signoff <<-\EOF >actual &&
1554 I want to mention about Signed-off-by: here.
1556 cat >expect <<-\EOF &&
1557 4:Subject: [PATCH] subject
1559 9:I want to mention about Signed-off-by: here.
1561 11:Signed-off-by: C O Mitter <committer@example.com>
1563 test_cmp expect actual
1566 test_expect_success
'signoff: not really a signoff (2)' '
1567 append_signoff <<-\EOF >actual &&
1571 Signed-off-by: example happens to be wrapped here.
1573 cat >expect <<-\EOF &&
1574 4:Subject: [PATCH] subject
1576 10:Signed-off-by: example happens to be wrapped here.
1577 11:Signed-off-by: C O Mitter <committer@example.com>
1579 test_cmp expect actual
1582 test_expect_success
'signoff: valid S-o-b paragraph in the middle' '
1583 append_signoff <<-\EOF >actual &&
1586 Signed-off-by: my@house
1587 Signed-off-by: your@house
1591 cat >expect <<-\EOF &&
1592 4:Subject: [PATCH] subject
1594 9:Signed-off-by: my@house
1595 10:Signed-off-by: your@house
1598 14:Signed-off-by: C O Mitter <committer@example.com>
1600 test_cmp expect actual
1603 test_expect_success
'signoff: the same signoff at the end' '
1604 append_signoff <<-\EOF >actual &&
1609 Signed-off-by: C O Mitter <committer@example.com>
1611 cat >expect <<-\EOF &&
1612 4:Subject: [PATCH] subject
1615 11:Signed-off-by: C O Mitter <committer@example.com>
1617 test_cmp expect actual
1620 test_expect_success
'signoff: the same signoff at the end, no trailing NL' '
1621 printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
1622 append_signoff >actual &&
1623 cat >expect <<-\EOF &&
1624 4:Subject: [PATCH] subject
1626 9:Signed-off-by: C O Mitter <committer@example.com>
1628 test_cmp expect actual
1631 test_expect_success
'signoff: the same signoff NOT at the end' '
1632 append_signoff <<-\EOF >actual &&
1637 Signed-off-by: C O Mitter <committer@example.com>
1638 Signed-off-by: my@house
1640 cat >expect <<-\EOF &&
1641 4:Subject: [PATCH] subject
1644 11:Signed-off-by: C O Mitter <committer@example.com>
1645 12:Signed-off-by: my@house
1647 test_cmp expect actual
1650 test_expect_success
'signoff: tolerate garbage in conforming footer' '
1651 append_signoff <<-\EOF >actual &&
1658 Signed-off-by: C O Mitter <committer@example.com>
1660 cat >expect <<-\EOF &&
1661 4:Subject: [PATCH] subject
1664 13:Signed-off-by: C O Mitter <committer@example.com>
1666 test_cmp expect actual
1669 test_expect_success
'signoff: respect trailer config' '
1670 append_signoff <<-\EOF >actual &&
1676 cat >expect <<-\EOF &&
1677 4:Subject: [PATCH] subject
1680 12:Signed-off-by: C O Mitter <committer@example.com>
1682 test_cmp expect actual &&
1684 test_config trailer.Myfooter.ifexists add &&
1685 append_signoff <<-\EOF >actual &&
1691 cat >expect <<-\EOF &&
1692 4:Subject: [PATCH] subject
1694 11:Signed-off-by: C O Mitter <committer@example.com>
1696 test_cmp expect actual
1699 test_expect_success
'signoff: footer begins with non-signoff without @ sign' '
1700 append_signoff <<-\EOF >actual &&
1707 Change-id: Ideadbeef
1708 Signed-off-by: C O Mitter <committer@example.com>
1711 cat >expect <<-\EOF &&
1712 4:Subject: [PATCH] subject
1715 14:Signed-off-by: C O Mitter <committer@example.com>
1717 test_cmp expect actual
1720 test_expect_success
'format patch ignores color.ui' '
1721 test_unconfig color.ui &&
1722 git format-patch --stdout -1 >expect &&
1723 test_config color.ui always &&
1724 git format-patch --stdout -1 >actual &&
1725 test_cmp expect actual
1728 test_expect_success
'format patch respects diff.relative' '
1731 echo other content >subdir/file2 &&
1732 git add subdir/file2 &&
1733 git commit -F msg &&
1734 test_unconfig diff.relative &&
1735 git format-patch --relative=subdir --stdout -1 >expect &&
1736 test_config diff.relative true &&
1737 git -C subdir format-patch --stdout -1 >actual &&
1738 test_cmp expect actual
1741 test_expect_success
'cover letter with invalid --cover-from-description and config' '
1742 test_config branch.rebuild-1.description "config subject
1745 test_must_fail git format-patch --cover-letter --cover-from-description garbage main &&
1746 test_config format.coverFromDescription garbage &&
1747 test_must_fail git format-patch --cover-letter main
1750 test_expect_success
'cover letter with format.coverFromDescription = default' '
1751 test_config branch.rebuild-1.description "config subject
1754 test_config format.coverFromDescription default &&
1755 git checkout rebuild-1 &&
1756 git format-patch --stdout --cover-letter main >actual &&
1757 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1758 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1759 grep "^config subject$" actual &&
1760 grep "^body$" actual
1763 test_expect_success
'cover letter with --cover-from-description default' '
1764 test_config branch.rebuild-1.description "config subject
1767 git checkout rebuild-1 &&
1768 git format-patch --stdout --cover-letter --cover-from-description default main >actual &&
1769 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1770 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1771 grep "^config subject$" actual &&
1772 grep "^body$" actual
1775 test_expect_success
'cover letter with format.coverFromDescription = none' '
1776 test_config branch.rebuild-1.description "config subject
1779 test_config format.coverFromDescription none &&
1780 git checkout rebuild-1 &&
1781 git format-patch --stdout --cover-letter main >actual &&
1782 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1783 grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1784 ! grep "^config subject$" actual &&
1785 ! grep "^body$" actual
1788 test_expect_success
'cover letter with --cover-from-description none' '
1789 test_config branch.rebuild-1.description "config subject
1792 git checkout rebuild-1 &&
1793 git format-patch --stdout --cover-letter --cover-from-description none main >actual &&
1794 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1795 grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1796 ! grep "^config subject$" actual &&
1797 ! grep "^body$" actual
1800 test_expect_success
'cover letter with format.coverFromDescription = message' '
1801 test_config branch.rebuild-1.description "config subject
1804 test_config format.coverFromDescription message &&
1805 git checkout rebuild-1 &&
1806 git format-patch --stdout --cover-letter main >actual &&
1807 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1808 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1809 grep "^config subject$" actual &&
1810 grep "^body$" actual
1813 test_expect_success
'cover letter with --cover-from-description message' '
1814 test_config branch.rebuild-1.description "config subject
1817 git checkout rebuild-1 &&
1818 git format-patch --stdout --cover-letter --cover-from-description message main >actual &&
1819 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1820 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1821 grep "^config subject$" actual &&
1822 grep "^body$" actual
1825 test_expect_success
'cover letter with format.coverFromDescription = subject' '
1826 test_config branch.rebuild-1.description "config subject
1829 test_config format.coverFromDescription subject &&
1830 git checkout rebuild-1 &&
1831 git format-patch --stdout --cover-letter main >actual &&
1832 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1833 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1834 ! grep "^config subject$" actual &&
1835 grep "^body$" actual
1838 test_expect_success
'cover letter with --cover-from-description subject' '
1839 test_config branch.rebuild-1.description "config subject
1842 git checkout rebuild-1 &&
1843 git format-patch --stdout --cover-letter --cover-from-description subject main >actual &&
1844 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1845 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1846 ! grep "^config subject$" actual &&
1847 grep "^body$" actual
1850 test_expect_success
'cover letter with format.coverFromDescription = auto (short subject line)' '
1851 test_config branch.rebuild-1.description "config subject
1854 test_config format.coverFromDescription auto &&
1855 git checkout rebuild-1 &&
1856 git format-patch --stdout --cover-letter main >actual &&
1857 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1858 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1859 ! grep "^config subject$" actual &&
1860 grep "^body$" actual
1863 test_expect_success
'cover letter with --cover-from-description auto (short subject line)' '
1864 test_config branch.rebuild-1.description "config subject
1867 git checkout rebuild-1 &&
1868 git format-patch --stdout --cover-letter --cover-from-description auto main >actual &&
1869 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1870 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1871 ! grep "^config subject$" actual &&
1872 grep "^body$" actual
1875 test_expect_success
'cover letter with format.coverFromDescription = auto (long subject line)' '
1876 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
1879 test_config format.coverFromDescription auto &&
1880 git checkout rebuild-1 &&
1881 git format-patch --stdout --cover-letter main >actual &&
1882 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1883 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1884 grep "^this is a really long first line and it is over 100 characters long which is the threshold for long subjects$" actual &&
1885 grep "^body$" actual
1888 test_expect_success
'cover letter with --cover-from-description auto (long subject line)' '
1889 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
1892 git checkout rebuild-1 &&
1893 git format-patch --stdout --cover-letter --cover-from-description auto main >actual &&
1894 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1895 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1896 grep "^this is a really long first line and it is over 100 characters long which is the threshold for long subjects$" actual &&
1897 grep "^body$" actual
1900 test_expect_success
'cover letter with command-line --cover-from-description overrides config' '
1901 test_config branch.rebuild-1.description "config subject
1904 test_config format.coverFromDescription none &&
1905 git checkout rebuild-1 &&
1906 git format-patch --stdout --cover-letter --cover-from-description subject main >actual &&
1907 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1908 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1909 ! grep "^config subject$" actual &&
1910 grep "^body$" actual
1913 test_expect_success
'cover letter using branch description (1)' '
1914 git checkout rebuild-1 &&
1915 test_config branch.rebuild-1.description hello &&
1916 git format-patch --stdout --cover-letter main >actual &&
1920 test_expect_success
'cover letter using branch description (2)' '
1921 git checkout rebuild-1 &&
1922 test_config branch.rebuild-1.description hello &&
1923 git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
1927 test_expect_success
'cover letter using branch description (3)' '
1928 git checkout rebuild-1 &&
1929 test_config branch.rebuild-1.description hello &&
1930 git format-patch --stdout --cover-letter ^main rebuild-1 >actual &&
1934 test_expect_success
'cover letter using branch description (4)' '
1935 git checkout rebuild-1 &&
1936 test_config branch.rebuild-1.description hello &&
1937 git format-patch --stdout --cover-letter main.. >actual &&
1941 test_expect_success
'cover letter using branch description (5)' '
1942 git checkout rebuild-1 &&
1943 test_config branch.rebuild-1.description hello &&
1944 git format-patch --stdout --cover-letter -2 HEAD >actual &&
1948 test_expect_success
'cover letter using branch description (6)' '
1949 git checkout rebuild-1 &&
1950 test_config branch.rebuild-1.description hello &&
1951 git format-patch --stdout --cover-letter -2 >actual &&
1955 test_expect_success
'cover letter with nothing' '
1956 git format-patch --stdout --cover-letter >actual &&
1957 test_line_count = 0 actual
1960 test_expect_success
'cover letter auto' '
1962 test_when_finished "rm -rf tmp;
1963 git config --unset format.coverletter" &&
1965 git config format.coverletter auto &&
1966 git format-patch -o tmp -1 >list &&
1967 test_line_count = 1 list &&
1968 git format-patch -o tmp -2 >list &&
1969 test_line_count = 3 list
1972 test_expect_success
'cover letter auto user override' '
1974 test_when_finished "rm -rf tmp;
1975 git config --unset format.coverletter" &&
1977 git config format.coverletter auto &&
1978 git format-patch -o tmp --cover-letter -1 >list &&
1979 test_line_count = 2 list &&
1980 git format-patch -o tmp --cover-letter -2 >list &&
1981 test_line_count = 3 list &&
1982 git format-patch -o tmp --no-cover-letter -1 >list &&
1983 test_line_count = 1 list &&
1984 git format-patch -o tmp --no-cover-letter -2 >list &&
1985 test_line_count = 2 list
1988 test_expect_success
'format-patch --zero-commit' '
1989 git format-patch --zero-commit --stdout v2..v1 >patch2 &&
1990 grep "^From " patch2 | sort | uniq >actual &&
1991 echo "From $ZERO_OID Mon Sep 17 00:00:00 2001" >expect &&
1992 test_cmp expect actual
1995 test_expect_success
'From line has expected format' '
1996 git format-patch --stdout v2..v1 >patch2 &&
1997 grep "^From " patch2 >from &&
1998 grep "^From $OID_REGEX Mon Sep 17 00:00:00 2001$" patch2 >filtered &&
1999 test_cmp from filtered
2002 test_expect_success
'format-patch -o with no leading directories' '
2004 git format-patch -o patches main..side &&
2005 count=$(git rev-list --count main..side) &&
2007 test_line_count = $count list
2010 test_expect_success
'format-patch -o with leading existing directories' '
2011 rm -rf existing-dir &&
2012 mkdir existing-dir &&
2013 git format-patch -o existing-dir/patches main..side &&
2014 count=$(git rev-list --count main..side) &&
2015 ls existing-dir/patches >list &&
2016 test_line_count = $count list
2019 test_expect_success
'format-patch -o with leading non-existing directories' '
2020 rm -rf non-existing-dir &&
2021 git format-patch -o non-existing-dir/patches main..side &&
2022 count=$(git rev-list --count main..side) &&
2023 test_path_is_dir non-existing-dir &&
2024 ls non-existing-dir/patches >list &&
2025 test_line_count = $count list
2028 test_expect_success
'format-patch format.outputDirectory option' '
2029 test_config format.outputDirectory patches &&
2031 git format-patch main..side &&
2032 count=$(git rev-list --count main..side) &&
2034 test_line_count = $count list
2037 test_expect_success
'format-patch -o overrides format.outputDirectory' '
2038 test_config format.outputDirectory patches &&
2039 rm -fr patches patchset &&
2040 git format-patch main..side -o patchset &&
2041 test_path_is_missing patches &&
2042 test_path_is_dir patchset
2045 test_expect_success
'format-patch forbids multiple outputs' '
2046 rm -fr outfile outdir &&
2048 git format-patch --stdout --output-directory=outdir &&
2050 git format-patch --stdout --output=outfile &&
2052 git format-patch --output=outfile --output-directory=outdir
2055 test_expect_success
'configured outdir does not conflict with output options' '
2056 rm -fr outfile outdir &&
2057 test_config format.outputDirectory outdir &&
2058 git format-patch --stdout &&
2059 test_path_is_missing outdir &&
2060 git format-patch --output=outfile &&
2061 test_path_is_missing outdir
2064 test_expect_success
'format-patch --output' '
2066 git format-patch -3 --stdout HEAD >expect &&
2067 git format-patch -3 --output=outfile HEAD &&
2068 test_cmp expect outfile
2071 test_expect_success
'format-patch --cover-letter --output' '
2073 git format-patch --cover-letter -3 --stdout HEAD >expect &&
2074 git format-patch --cover-letter -3 --output=outfile HEAD &&
2075 test_cmp expect outfile
2078 test_expect_success
'format-patch --base' '
2079 git checkout patchid &&
2081 git format-patch --stdout --base=HEAD~3 -1 >patch &&
2082 tail -n 7 patch >actual1 &&
2084 git format-patch --stdout --base=HEAD~3 HEAD~.. >patch &&
2085 tail -n 7 patch >actual2 &&
2088 git rev-parse HEAD~3 >commit-id-base &&
2089 echo "base-commit: $(cat commit-id-base)" >>expect &&
2091 git show --patch HEAD~2 >patch &&
2092 git patch-id --stable <patch >patch.id.raw &&
2093 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>expect &&
2095 git show --patch HEAD~1 >patch &&
2096 git patch-id --stable <patch >patch.id.raw &&
2097 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>expect &&
2099 signature >>expect &&
2100 test_cmp expect actual1 &&
2101 test_cmp expect actual2 &&
2104 echo "base-commit: $(cat commit-id-base)" >>fail &&
2106 git show --patch HEAD~2 >patch &&
2107 git patch-id --unstable <patch >patch.id.raw &&
2108 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>fail &&
2110 git show --patch HEAD~1 >patch &&
2111 git patch-id --unstable <patch >patch.id.raw &&
2112 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>fail &&
2115 ! test_cmp fail actual1 &&
2116 ! test_cmp fail actual2
2119 test_expect_success
'format-patch --base errors out when base commit is in revision list' '
2120 test_must_fail git format-patch --base=HEAD -2 &&
2121 test_must_fail git format-patch --base=HEAD~1 -2 &&
2122 git format-patch --stdout --base=HEAD~2 -2 >patch &&
2123 grep "^base-commit:" patch >actual &&
2124 git rev-parse HEAD~2 >commit-id-base &&
2125 echo "base-commit: $(cat commit-id-base)" >expect &&
2126 test_cmp expect actual
2129 test_expect_success
'format-patch --base errors out when base commit is not ancestor of revision list' '
2130 # For history as below:
2132 # ---Q---P---Z---Y---*---X
2136 # If "format-patch Z..X" is given, P and Z can not be specified as the base commit
2137 git checkout -b topic1 main &&
2138 git rev-parse HEAD >commit-id-base &&
2140 git rev-parse HEAD >commit-id-P &&
2142 git rev-parse HEAD >commit-id-Z &&
2144 git checkout -b topic2 main &&
2148 test_must_fail git format-patch --base=$(cat commit-id-P) -3 &&
2149 test_must_fail git format-patch --base=$(cat commit-id-Z) -3 &&
2150 git format-patch --stdout --base=$(cat commit-id-base) -3 >patch &&
2151 grep "^base-commit:" patch >actual &&
2152 echo "base-commit: $(cat commit-id-base)" >expect &&
2153 test_cmp expect actual
2156 test_expect_success
'format-patch --base=auto' '
2157 git checkout -b upstream main &&
2158 git checkout -b local upstream &&
2159 git branch --set-upstream-to=upstream &&
2162 git format-patch --stdout --base=auto -2 >patch &&
2163 grep "^base-commit:" patch >actual &&
2164 git rev-parse upstream >commit-id-base &&
2165 echo "base-commit: $(cat commit-id-base)" >expect &&
2166 test_cmp expect actual
2169 test_expect_success
'format-patch errors out when history involves criss-cross' '
2170 # setup criss-cross history
2178 git checkout main &&
2180 git checkout -b xb main &&
2182 git checkout -b xc main &&
2184 git checkout -b xbc xb -- &&
2186 git checkout -b xcb xc -- &&
2187 git branch --set-upstream-to=xbc &&
2193 test_must_fail git format-patch --base=auto -1
2196 test_expect_success
'format-patch format.useAutoBase whenAble history involves criss-cross' '
2197 test_config format.useAutoBase whenAble &&
2198 git format-patch -1 >patch &&
2199 ! grep "^base-commit:" patch
2202 test_expect_success
'format-patch format.useAutoBase option' '
2203 git checkout local &&
2204 test_config format.useAutoBase true &&
2205 git format-patch --stdout -1 >patch &&
2206 grep "^base-commit:" patch >actual &&
2207 git rev-parse upstream >commit-id-base &&
2208 echo "base-commit: $(cat commit-id-base)" >expect &&
2209 test_cmp expect actual
2212 test_expect_success
'format-patch format.useAutoBase option with whenAble' '
2213 git checkout local &&
2214 test_config format.useAutoBase whenAble &&
2215 git format-patch --stdout -1 >patch &&
2216 grep "^base-commit:" patch >actual &&
2217 git rev-parse upstream >commit-id-base &&
2218 echo "base-commit: $(cat commit-id-base)" >expect &&
2219 test_cmp expect actual
2222 test_expect_success
'format-patch --base overrides format.useAutoBase' '
2223 test_config format.useAutoBase true &&
2224 git format-patch --stdout --base=HEAD~1 -1 >patch &&
2225 grep "^base-commit:" patch >actual &&
2226 git rev-parse HEAD~1 >commit-id-base &&
2227 echo "base-commit: $(cat commit-id-base)" >expect &&
2228 test_cmp expect actual
2231 test_expect_success
'format-patch --no-base overrides format.useAutoBase' '
2232 test_config format.useAutoBase true &&
2233 git format-patch --stdout --no-base -1 >patch &&
2234 ! grep "^base-commit:" patch
2237 test_expect_success
'format-patch --no-base overrides format.useAutoBase whenAble' '
2238 test_config format.useAutoBase whenAble &&
2239 git format-patch --stdout --no-base -1 >patch &&
2240 ! grep "^base-commit:" patch
2243 test_expect_success
'format-patch --base with --attach' '
2244 git format-patch --attach=mimemime --stdout --base=HEAD~ -1 >patch &&
2245 sed -n -e "/^base-commit:/s/.*/1/p" -e "/^---*mimemime--$/s/.*/2/p" \
2247 test_write_lines 1 2 >expect &&
2248 test_cmp expect actual
2250 test_expect_success
'format-patch --attach cover-letter only is non-multipart' '
2251 test_when_finished "rm -fr patches" &&
2252 git format-patch -o patches --cover-letter --attach=mimemime --base=HEAD~ -1 &&
2253 ! egrep "^--+mimemime" patches/0000*.patch &&
2254 egrep "^--+mimemime$" patches/0001*.patch >output &&
2255 test_line_count = 2 output &&
2256 egrep "^--+mimemime--$" patches/0001*.patch >output &&
2257 test_line_count = 1 output
2260 test_expect_success
'format-patch --pretty=mboxrd' '
2262 cat >msg <<-INPUT_END &&
2263 mboxrd should escape the body
2265 From could trip up a loose mbox parser
2266 >From extra escape for reversibility
2267 >>From extra escape for reversibility 2
2268 from lower case not escaped
2269 Fromm bad speling not escaped
2270 From with leading space not escaped
2279 cat >expect <<-INPUT_END &&
2280 >From could trip up a loose mbox parser
2281 >>From extra escape for reversibility
2282 >>>From extra escape for reversibility 2
2283 from lower case not escaped
2284 Fromm bad speling not escaped
2285 From with leading space not escaped
2294 C=$(git commit-tree HEAD^^{tree} -p HEAD <msg) &&
2295 git format-patch --pretty=mboxrd --stdout -1 $C~1..$C >patch &&
2296 git grep -h --no-index -A11 \
2297 "^>From could trip up a loose mbox parser" patch >actual &&
2298 test_cmp expect actual
2301 test_expect_success
'interdiff: setup' '
2302 git checkout -b boop main &&
2303 test_commit fnorp blorp &&
2304 test_commit fleep blorp
2307 test_expect_success
'interdiff: cover-letter' '
2308 sed "y/q/ /" >expect <<-\EOF &&
2312 git format-patch --cover-letter --interdiff=boop~2 -1 boop &&
2313 test_i18ngrep "^Interdiff:$" 0000-cover-letter.patch &&
2314 test_i18ngrep ! "^Interdiff:$" 0001-fleep.patch &&
2315 sed "1,/^@@ /d; /^-- $/q" 0000-cover-letter.patch >actual &&
2316 test_cmp expect actual
2319 test_expect_success
'interdiff: reroll-count' '
2320 git format-patch --cover-letter --interdiff=boop~2 -v2 -1 boop &&
2321 test_i18ngrep "^Interdiff ..* v1:$" v2-0000-cover-letter.patch
2324 test_expect_success
'interdiff: reroll-count with a non-integer' '
2325 git format-patch --cover-letter --interdiff=boop~2 -v2.2 -1 boop &&
2326 test_i18ngrep "^Interdiff:$" v2.2-0000-cover-letter.patch
2329 test_expect_success
'interdiff: reroll-count with a integer' '
2330 git format-patch --cover-letter --interdiff=boop~2 -v2 -1 boop &&
2331 test_i18ngrep "^Interdiff ..* v1:$" v2-0000-cover-letter.patch
2334 test_expect_success
'interdiff: solo-patch' '
2335 cat >expect <<-\EOF &&
2339 git format-patch --interdiff=boop~2 -1 boop &&
2340 test_i18ngrep "^Interdiff:$" 0001-fleep.patch &&
2341 sed "1,/^ @@ /d; /^$/q" 0001-fleep.patch >actual &&
2342 test_cmp expect actual