3 # Copyright (c) 2006 Junio C Hamano
6 test_description='various format-patch tests'
9 . "$TEST_DIRECTORY"/lib-terminal.sh
11 test_expect_success setup '
12 for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i"; done >file &&
16 git commit -m Initial &&
17 git checkout -b side &&
19 for i in 1 2 5 6 A B C 7 8 9 10; do echo "$i"; done >file &&
22 git commit -m "Side changes #1" &&
24 for i in D E F; do echo "$i"; done >>file &&
25 git update-index file &&
27 git commit -m "Side changes #2" &&
30 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file &&
31 git update-index file &&
33 git commit -m "Side changes #3 with \\n backslash-n in it." &&
35 git checkout master &&
36 git diff-tree -p C2 >patch &&
37 git apply --index <patch &&
39 git commit -m "Master accepts moral equivalent of #2" &&
42 git checkout -b patchid &&
43 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file2 &&
44 for i in 1 2 3 A 4 B C 7 8 9 10 D E F 5 6; do echo "$i"; done >file3 &&
45 for i in 8 9 10; do echo "$i"; done >file &&
46 git add file file2 file3 &&
48 git commit -m "patchid 1" &&
49 for i in 4 A B 7 8 9 10; do echo "$i"; done >file2 &&
50 for i in 8 9 10 5 6; do echo "$i"; done >file3 &&
51 git add file2 file3 &&
53 git commit -m "patchid 2" &&
54 for i in 10 5 6; do echo "$i"; done >file &&
57 git commit -m "patchid 3" &&
62 test_expect_success 'format-patch --ignore-if-in-upstream' '
63 git format-patch --stdout master..side >patch0 &&
64 grep "^From " patch0 >from0 &&
65 test_line_count = 3 from0
68 test_expect_success 'format-patch --ignore-if-in-upstream' '
69 git format-patch --stdout \
70 --ignore-if-in-upstream master..side >patch1 &&
71 grep "^From " patch1 >from1 &&
72 test_line_count = 2 from1
75 test_expect_success 'format-patch --ignore-if-in-upstream handles tags' '
76 git tag -a v1 -m tag side &&
77 git tag -a v2 -m tag master &&
78 git format-patch --stdout --ignore-if-in-upstream v2..v1 >patch1 &&
79 grep "^From " patch1 >from1 &&
80 test_line_count = 2 from1
83 test_expect_success "format-patch doesn't consider merge commits" '
84 git checkout -b slave master &&
85 echo "Another line" >>file &&
87 git commit -am "Slave change #1" &&
88 echo "Yet another line" >>file &&
90 git commit -am "Slave change #2" &&
91 git checkout -b merger master &&
93 git merge --no-ff slave &&
94 git format-patch -3 --stdout >patch &&
95 grep "^From " patch >from &&
96 test_line_count = 3 from
99 test_expect_success 'format-patch result applies' '
100 git checkout -b rebuild-0 master &&
102 git rev-list master.. >list &&
103 test_line_count = 2 list
106 test_expect_success 'format-patch --ignore-if-in-upstream result applies' '
107 git checkout -b rebuild-1 master &&
109 git rev-list master.. >list &&
110 test_line_count = 2 list
113 test_expect_success 'commit did not screw up the log message' '
114 git cat-file commit side >actual &&
115 grep "^Side .* with .* backslash-n" actual
118 test_expect_success 'format-patch did not screw up the log message' '
119 grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
120 grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
123 test_expect_success 'replay did not screw up the log message' '
124 git cat-file commit rebuild-1 >actual &&
125 grep "^Side .* with .* backslash-n" actual
128 test_expect_success 'extra headers' '
129 git config format.headers "To: R E Cipient <rcipient@example.com>
131 git config --add format.headers "Cc: S E Cipient <scipient@example.com>
133 git format-patch --stdout master..side >patch2 &&
134 sed -e "/^\$/q" patch2 >hdrs2 &&
135 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs2 &&
136 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs2
139 test_expect_success 'extra headers without newlines' '
140 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
141 git config --add format.headers "Cc: S E Cipient <scipient@example.com>" &&
142 git format-patch --stdout master..side >patch3 &&
143 sed -e "/^\$/q" patch3 >hdrs3 &&
144 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs3 &&
145 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs3
148 test_expect_success 'extra headers with multiple To:s' '
149 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
150 git config --add format.headers "To: S E Cipient <scipient@example.com>" &&
151 git format-patch --stdout master..side >patch4 &&
152 sed -e "/^\$/q" patch4 >hdrs4 &&
153 grep "^To: R E Cipient <rcipient@example.com>,\$" hdrs4 &&
154 grep "^ *S E Cipient <scipient@example.com>\$" hdrs4
157 test_expect_success 'additional command line cc (ascii)' '
158 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
159 git format-patch --cc="S E Cipient <scipient@example.com>" --stdout master..side >patch5 &&
160 sed -e "/^\$/q" patch5 >hdrs5 &&
161 grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs5 &&
162 grep "^ *S E Cipient <scipient@example.com>\$" hdrs5
165 test_expect_failure 'additional command line cc (rfc822)' '
166 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
167 git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side >patch5 &&
168 sed -e "/^\$/q" patch5 >hdrs5 &&
169 grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs5 &&
170 grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" hdrs5
173 test_expect_success 'command line headers' '
174 git config --unset-all format.headers &&
175 git format-patch --add-header="Cc: R E Cipient <rcipient@example.com>" --stdout master..side >patch6 &&
176 sed -e "/^\$/q" patch6 >hdrs6 &&
177 grep "^Cc: R E Cipient <rcipient@example.com>\$" hdrs6
180 test_expect_success 'configuration headers and command line headers' '
181 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
182 git format-patch --add-header="Cc: S E Cipient <scipient@example.com>" --stdout master..side >patch7 &&
183 sed -e "/^\$/q" patch7 >hdrs7 &&
184 grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs7 &&
185 grep "^ *S E Cipient <scipient@example.com>\$" hdrs7
188 test_expect_success 'command line To: header (ascii)' '
189 git config --unset-all format.headers &&
190 git format-patch --to="R E Cipient <rcipient@example.com>" --stdout master..side >patch8 &&
191 sed -e "/^\$/q" patch8 >hdrs8 &&
192 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs8
195 test_expect_failure 'command line To: header (rfc822)' '
196 git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side >patch8 &&
197 sed -e "/^\$/q" patch8 >hdrs8 &&
198 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" hdrs8
201 test_expect_failure 'command line To: header (rfc2047)' '
202 git format-patch --to="R Ä Cipient <rcipient@example.com>" --stdout master..side >patch8 &&
203 sed -e "/^\$/q" patch8 >hdrs8 &&
204 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" hdrs8
207 test_expect_success 'configuration To: header (ascii)' '
208 git config format.to "R E Cipient <rcipient@example.com>" &&
209 git format-patch --stdout master..side >patch9 &&
210 sed -e "/^\$/q" patch9 >hdrs9 &&
211 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs9
214 test_expect_failure 'configuration To: header (rfc822)' '
215 git config format.to "R. E. Cipient <rcipient@example.com>" &&
216 git format-patch --stdout master..side >patch9 &&
217 sed -e "/^\$/q" patch9 >hdrs9 &&
218 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" hdrs9
221 test_expect_failure 'configuration To: header (rfc2047)' '
222 git config format.to "R Ä Cipient <rcipient@example.com>" &&
223 git format-patch --stdout master..side >patch9 &&
224 sed -e "/^\$/q" patch9 >hdrs9 &&
225 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" hdrs9
228 # check_patch <patch>: Verify that <patch> looks like a half-sane
229 # patch email to avoid a false positive with !grep
231 grep -e "^From:" "$1" &&
232 grep -e "^Date:" "$1" &&
233 grep -e "^Subject:" "$1"
236 test_expect_success 'format.from=false' '
237 git -c format.from=false format-patch --stdout master..side >patch &&
238 sed -e "/^\$/q" patch >hdrs &&
240 ! grep "^From: C O Mitter <committer@example.com>\$" hdrs
243 test_expect_success 'format.from=true' '
244 git -c format.from=true format-patch --stdout master..side >patch &&
245 sed -e "/^\$/q" patch >hdrs &&
247 grep "^From: C O Mitter <committer@example.com>\$" hdrs
250 test_expect_success 'format.from with address' '
251 git -c format.from="F R Om <from@example.com>" format-patch --stdout master..side >patch &&
252 sed -e "/^\$/q" patch >hdrs &&
254 grep "^From: F R Om <from@example.com>\$" hdrs
257 test_expect_success '--no-from overrides format.from' '
258 git -c format.from="F R Om <from@example.com>" format-patch --no-from --stdout master..side >patch &&
259 sed -e "/^\$/q" patch >hdrs &&
261 ! grep "^From: F R Om <from@example.com>\$" hdrs
264 test_expect_success '--from overrides format.from' '
265 git -c format.from="F R Om <from@example.com>" format-patch --from --stdout master..side >patch &&
266 sed -e "/^\$/q" patch >hdrs &&
268 ! grep "^From: F R Om <from@example.com>\$" hdrs
271 test_expect_success '--no-to overrides config.to' '
272 git config --replace-all format.to \
273 "R E Cipient <rcipient@example.com>" &&
274 git format-patch --no-to --stdout master..side >patch10 &&
275 sed -e "/^\$/q" patch10 >hdrs10 &&
276 check_patch hdrs10 &&
277 ! grep "^To: R E Cipient <rcipient@example.com>\$" hdrs10
280 test_expect_success '--no-to and --to replaces config.to' '
281 git config --replace-all format.to \
282 "Someone <someone@out.there>" &&
283 git format-patch --no-to --to="Someone Else <else@out.there>" \
284 --stdout master..side >patch11 &&
285 sed -e "/^\$/q" patch11 >hdrs11 &&
286 check_patch hdrs11 &&
287 ! grep "^To: Someone <someone@out.there>\$" hdrs11 &&
288 grep "^To: Someone Else <else@out.there>\$" hdrs11
291 test_expect_success '--no-cc overrides config.cc' '
292 git config --replace-all format.cc \
293 "C E Cipient <rcipient@example.com>" &&
294 git format-patch --no-cc --stdout master..side >patch12 &&
295 sed -e "/^\$/q" patch12 >hdrs12 &&
296 check_patch hdrs12 &&
297 ! grep "^Cc: C E Cipient <rcipient@example.com>\$" hdrs12
300 test_expect_success '--no-add-header overrides config.headers' '
301 git config --replace-all format.headers \
302 "Header1: B E Cipient <rcipient@example.com>" &&
303 git format-patch --no-add-header --stdout master..side >patch13 &&
304 sed -e "/^\$/q" patch13 >hdrs13 &&
305 check_patch hdrs13 &&
306 ! grep "^Header1: B E Cipient <rcipient@example.com>\$" hdrs13
309 test_expect_success 'multiple files' '
312 git format-patch -o patches/ master &&
313 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
316 test_expect_success 'reroll count' '
318 git format-patch -o patches --cover-letter --reroll-count 4 master..side >list &&
319 ! grep -v "^patches/v4-000[0-3]-" list &&
320 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
321 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
324 test_expect_success 'reroll count (-v)' '
326 git format-patch -o patches --cover-letter -v4 master..side >list &&
327 ! grep -v "^patches/v4-000[0-3]-" list &&
328 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
329 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
335 git format-patch --stdout "$@" >patch &&
336 # Prints everything between the Message-ID and In-Reply-To,
337 # and replaces all Message-ID-lookalikes by a sequence number
339 if (/^(message-id|references|in-reply-to)/i) {
345 $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
346 for $k (keys %h) {s/$k/$h{$k}/};
349 print "---\n" if /^From /i;
351 test_cmp "$expect" actual
354 cat >>expect.no-threading <<EOF
360 test_expect_success 'no threading' '
362 check_threading expect.no-threading master
365 cat >expect.thread <<EOF
378 test_expect_success 'thread' '
379 check_threading expect.thread --thread master
382 cat >expect.in-reply-to <<EOF
397 test_expect_success 'thread in-reply-to' '
398 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
402 cat >expect.cover-letter <<EOF
419 test_expect_success 'thread cover-letter' '
420 check_threading expect.cover-letter --cover-letter --thread master
423 cat >expect.cl-irt <<EOF
445 test_expect_success 'thread cover-letter in-reply-to' '
446 check_threading expect.cl-irt --cover-letter \
447 --in-reply-to="<test.message>" --thread master
450 test_expect_success 'thread explicit shallow' '
451 check_threading expect.cl-irt --cover-letter \
452 --in-reply-to="<test.message>" --thread=shallow master
455 cat >expect.deep <<EOF
469 test_expect_success 'thread deep' '
470 check_threading expect.deep --thread=deep master
473 cat >expect.deep-irt <<EOF
491 test_expect_success 'thread deep in-reply-to' '
492 check_threading expect.deep-irt --thread=deep \
493 --in-reply-to="<test.message>" master
496 cat >expect.deep-cl <<EOF
516 test_expect_success 'thread deep cover-letter' '
517 check_threading expect.deep-cl --cover-letter --thread=deep master
520 cat >expect.deep-cl-irt <<EOF
545 test_expect_success 'thread deep cover-letter in-reply-to' '
546 check_threading expect.deep-cl-irt --cover-letter \
547 --in-reply-to="<test.message>" --thread=deep master
550 test_expect_success 'thread via config' '
551 test_config format.thread true &&
552 check_threading expect.thread master
555 test_expect_success 'thread deep via config' '
556 test_config format.thread deep &&
557 check_threading expect.deep master
560 test_expect_success 'thread config + override' '
561 test_config format.thread deep &&
562 check_threading expect.thread --thread master
565 test_expect_success 'thread config + --no-thread' '
566 test_config format.thread deep &&
567 check_threading expect.no-threading --no-thread master
570 test_expect_success 'excessive subject' '
573 before=$(git hash-object file) &&
574 before=$(git rev-parse --short $before) &&
575 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
576 after=$(git hash-object file) &&
577 after=$(git rev-parse --short $after) &&
578 git update-index file &&
579 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." &&
580 git format-patch -o patches/ master..side &&
581 ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
584 test_expect_success 'failure to write cover-letter aborts gracefully' '
585 test_when_finished "rmdir 0000-cover-letter.patch" &&
586 mkdir 0000-cover-letter.patch &&
587 test_must_fail git format-patch --no-renames --cover-letter -1
590 test_expect_success 'cover-letter inherits diff options' '
593 git format-patch --no-renames --cover-letter -1 &&
594 check_patch 0000-cover-letter.patch &&
595 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
596 git format-patch --cover-letter -1 -M &&
597 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
601 This is an excessively long subject line for a message due to the
602 habit some projects have of not having a short, one-line subject at
603 the start of the commit message, but rather sticking a whole
604 paragraph right at the start as the only thing in the commit
605 message. It had better not become the filename for the patch.
610 test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
611 git format-patch --cover-letter -2 &&
612 sed -e "1,/A U Thor/d" -e "/^\$/q" 0000-cover-letter.patch >output &&
613 test_cmp expect output
617 index $before..$after 100644
628 test_expect_success 'format-patch respects -U' '
629 git format-patch -U4 -2 &&
630 sed -e "1,/^diff/d" -e "/^+5/q" \
631 <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
633 test_cmp expect output
638 diff --git a/file b/file
639 index $before..$after 100644
649 test_expect_success 'format-patch -p suppresses stat' '
650 git format-patch -p -2 &&
651 sed -e "1,/^\$/d" -e "/^+5/q" 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch >output &&
652 test_cmp expect output
655 test_expect_success 'format-patch from a subdirectory (1)' '
666 echo "Oops? $filename"
673 test_expect_success 'format-patch from a subdirectory (2)' '
678 git format-patch -1 -o ..
684 echo "Oops? $filename"
688 basename=$(expr "$filename" : ".*/\(.*\)") &&
689 test -f "sub/$basename"
692 test_expect_success 'format-patch from a subdirectory (3)' '
698 git format-patch -1 -o "$TRASH_DIRECTORY"
700 basename=$(expr "$filename" : ".*/\(.*\)") &&
704 test_expect_success 'format-patch --in-reply-to' '
705 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" >patch8 &&
706 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
707 grep "^References: <baz@foo.bar>" patch8
710 test_expect_success 'format-patch --signoff' '
711 git format-patch -1 --signoff --stdout >out &&
712 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
715 test_expect_success 'format-patch --notes --signoff' '
716 git notes --ref test add -m "test message" HEAD &&
717 git format-patch -1 --signoff --stdout --notes=test >out &&
718 # Three dashes must come after S-o-b
719 ! sed "/^Signed-off-by: /q" out | grep "test message" &&
720 sed "1,/^Signed-off-by: /d" out | grep "test message" &&
721 # Notes message must come after three dashes
722 ! sed "/^---$/q" out | grep "test message" &&
723 sed "1,/^---$/d" out | grep "test message"
726 test_expect_success 'format-patch notes output control' '
727 git notes add -m "notes config message" HEAD &&
728 test_when_finished git notes remove HEAD &&
730 git format-patch -1 --stdout >out &&
731 ! grep "notes config message" out &&
732 git format-patch -1 --stdout --notes >out &&
733 grep "notes config message" out &&
734 git format-patch -1 --stdout --no-notes >out &&
735 ! grep "notes config message" out &&
736 git format-patch -1 --stdout --notes --no-notes >out &&
737 ! grep "notes config message" out &&
738 git format-patch -1 --stdout --no-notes --notes >out &&
739 grep "notes config message" out &&
741 test_config format.notes true &&
742 git format-patch -1 --stdout >out &&
743 grep "notes config message" out &&
744 git format-patch -1 --stdout --notes >out &&
745 grep "notes config message" out &&
746 git format-patch -1 --stdout --no-notes >out &&
747 ! grep "notes config message" out &&
748 git format-patch -1 --stdout --notes --no-notes >out &&
749 ! grep "notes config message" out &&
750 git format-patch -1 --stdout --no-notes --notes >out &&
751 grep "notes config message" out
754 test_expect_success 'format-patch with multiple notes refs' '
755 git notes --ref note1 add -m "this is note 1" HEAD &&
756 test_when_finished git notes --ref note1 remove HEAD &&
757 git notes --ref note2 add -m "this is note 2" HEAD &&
758 test_when_finished git notes --ref note2 remove HEAD &&
760 git format-patch -1 --stdout >out &&
761 ! grep "this is note 1" out &&
762 ! grep "this is note 2" out &&
763 git format-patch -1 --stdout --notes=note1 >out &&
764 grep "this is note 1" out &&
765 ! grep "this is note 2" out &&
766 git format-patch -1 --stdout --notes=note2 >out &&
767 ! grep "this is note 1" out &&
768 grep "this is note 2" out &&
769 git format-patch -1 --stdout --notes=note1 --notes=note2 >out &&
770 grep "this is note 1" out &&
771 grep "this is note 2" out &&
773 test_config format.notes note1 &&
774 git format-patch -1 --stdout >out &&
775 grep "this is note 1" out &&
776 ! grep "this is note 2" out &&
777 git format-patch -1 --stdout --no-notes >out &&
778 ! grep "this is note 1" out &&
779 ! grep "this is note 2" out &&
780 git format-patch -1 --stdout --notes=note2 >out &&
781 grep "this is note 1" out &&
782 grep "this is note 2" out &&
783 git format-patch -1 --stdout --no-notes --notes=note2 >out &&
784 ! grep "this is note 1" out &&
785 grep "this is note 2" out &&
787 git config --add format.notes note2 &&
788 git format-patch -1 --stdout >out &&
789 grep "this is note 1" out &&
790 grep "this is note 2" out &&
791 git format-patch -1 --stdout --no-notes >out &&
792 ! grep "this is note 1" out &&
793 ! grep "this is note 2" out
796 echo "fatal: --name-only does not make sense" >expect.name-only
797 echo "fatal: --name-status does not make sense" >expect.name-status
798 echo "fatal: --check does not make sense" >expect.check
800 test_expect_success 'options no longer allowed for format-patch' '
801 test_must_fail git format-patch --name-only 2>output &&
802 test_i18ncmp expect.name-only output &&
803 test_must_fail git format-patch --name-status 2>output &&
804 test_i18ncmp expect.name-status output &&
805 test_must_fail git format-patch --check 2>output &&
806 test_i18ncmp expect.check output
809 test_expect_success 'format-patch --numstat should produce a patch' '
810 git format-patch --numstat --stdout master..side >output &&
811 grep "^diff --git a/" output >diff &&
812 test_line_count = 5 diff
815 test_expect_success 'format-patch -- <path>' '
816 git format-patch master..side -- file 2>error &&
817 ! grep "Use .--" error
820 test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
821 git format-patch --ignore-if-in-upstream HEAD
824 test_expect_success 'get git version' '
825 git_version=$(git --version) &&
826 git_version=${git_version##* }
830 printf "%s\n%s\n\n" "-- " "${1:-$git_version}"
833 test_expect_success 'format-patch default signature' '
834 git format-patch --stdout -1 >patch &&
835 tail -n 3 patch >output &&
837 test_cmp expect output
840 test_expect_success 'format-patch --signature' '
841 git format-patch --stdout --signature="my sig" -1 >patch &&
842 tail -n 3 patch >output &&
843 signature "my sig" >expect &&
844 test_cmp expect output
847 test_expect_success 'format-patch with format.signature config' '
848 git config format.signature "config sig" &&
849 git format-patch --stdout -1 >output &&
850 grep "config sig" output
853 test_expect_success 'format-patch --signature overrides format.signature' '
854 git config format.signature "config sig" &&
855 git format-patch --stdout --signature="overrides" -1 >output &&
856 ! grep "config sig" output &&
857 grep "overrides" output
860 test_expect_success 'format-patch --no-signature ignores format.signature' '
861 git config format.signature "config sig" &&
862 git format-patch --stdout --signature="my sig" --no-signature \
864 check_patch output &&
865 ! grep "config sig" output &&
866 ! grep "my sig" output &&
867 ! grep "^-- \$" output
870 test_expect_success 'format-patch --signature --cover-letter' '
871 git config --unset-all format.signature &&
872 git format-patch --stdout --signature="my sig" --cover-letter \
874 grep "my sig" output >sig &&
875 test_line_count = 2 sig
878 test_expect_success 'format.signature="" suppresses signatures' '
879 git config format.signature "" &&
880 git format-patch --stdout -1 >output &&
881 check_patch output &&
882 ! grep "^-- \$" output
885 test_expect_success 'format-patch --no-signature suppresses signatures' '
886 git config --unset-all format.signature &&
887 git format-patch --stdout --no-signature -1 >output &&
888 check_patch output &&
889 ! grep "^-- \$" output
892 test_expect_success 'format-patch --signature="" suppresses signatures' '
893 git format-patch --stdout --signature="" -1 >output &&
894 check_patch output &&
895 ! grep "^-- \$" output
898 test_expect_success 'prepare mail-signature input' '
899 cat >mail-signature <<-\EOF
901 Test User <test.email@kernel.org>
902 http://git.kernel.org/cgit/git/git.git
904 git.kernel.org/?p=git/git.git;a=summary
909 test_expect_success '--signature-file=file works' '
910 git format-patch --stdout --signature-file=mail-signature -1 >output &&
911 check_patch output &&
912 sed -e "1,/^-- \$/d" output >actual &&
914 cat mail-signature && echo
916 test_cmp expect actual
919 test_expect_success 'format.signaturefile works' '
920 test_config format.signaturefile mail-signature &&
921 git format-patch --stdout -1 >output &&
922 check_patch output &&
923 sed -e "1,/^-- \$/d" output >actual &&
925 cat mail-signature && echo
927 test_cmp expect actual
930 test_expect_success '--no-signature suppresses format.signaturefile ' '
931 test_config format.signaturefile mail-signature &&
932 git format-patch --stdout --no-signature -1 >output &&
933 check_patch output &&
934 ! grep "^-- \$" output
937 test_expect_success '--signature-file overrides format.signaturefile' '
938 cat >other-mail-signature <<-\EOF &&
939 Use this other signature instead of mail-signature.
941 test_config format.signaturefile mail-signature &&
942 git format-patch --stdout \
943 --signature-file=other-mail-signature -1 >output &&
944 check_patch output &&
945 sed -e "1,/^-- \$/d" output >actual &&
947 cat other-mail-signature && echo
949 test_cmp expect actual
952 test_expect_success '--signature overrides format.signaturefile' '
953 test_config format.signaturefile mail-signature &&
954 git format-patch --stdout --signature="my sig" -1 >output &&
955 check_patch output &&
959 test_expect_success TTY 'format-patch --stdout paginates' '
961 test_terminal env GIT_PAGER="wc >pager_used" git format-patch --stdout --all &&
962 test_path_is_file pager_used
965 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
967 test_terminal env GIT_PAGER="wc >pager_used" git --no-pager format-patch --stdout --all &&
968 test_terminal env GIT_PAGER="wc >pager_used" git -c "pager.format-patch=false" format-patch --stdout --all &&
969 test_path_is_missing pager_used &&
970 test_path_is_missing .git/pager_used
973 test_expect_success 'format-patch handles multi-line subjects' '
975 echo content >>file &&
976 for i in one two three; do echo $i; done >msg &&
979 git format-patch -o patches -1 &&
980 grep ^Subject: patches/0001-one.patch >actual &&
981 echo "Subject: [PATCH] one two three" >expect &&
982 test_cmp expect actual
985 test_expect_success 'format-patch handles multi-line encoded subjects' '
987 echo content >>file &&
988 for i in en två tre; do echo $i; done >msg &&
991 git format-patch -o patches -1 &&
992 grep ^Subject: patches/0001-en.patch >actual &&
993 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
994 test_cmp expect actual
998 M64=$M8$M8$M8$M8$M8$M8$M8$M8
999 M512=$M64$M64$M64$M64$M64$M64$M64$M64
1001 Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1002 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1003 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1004 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1005 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1006 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1007 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1009 test_expect_success 'format-patch wraps extremely long subject (ascii)' '
1010 echo content >>file &&
1012 git commit -m "$M512" &&
1013 git format-patch --stdout -1 >patch &&
1014 sed -n "/^Subject/p; /^ /p; /^$/q" patch >subject &&
1015 test_cmp expect subject
1019 M64=$M8$M8$M8$M8$M8$M8$M8$M8
1020 M512=$M64$M64$M64$M64$M64$M64$M64$M64
1022 Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1023 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1024 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1025 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1026 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1027 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1028 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1029 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1030 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1031 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1032 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1033 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1034 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1035 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1036 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1037 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1038 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1039 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1040 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1041 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1042 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1043 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1044 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1047 test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
1049 echo content >>file &&
1051 git commit -m "$M512" &&
1052 git format-patch --stdout -1 >patch &&
1053 sed -n "/^Subject/p; /^ /p; /^$/q" patch >subject &&
1054 test_cmp expect subject
1058 echo content >>file &&
1060 GIT_AUTHOR_NAME=$1 git commit -m author-check &&
1061 git format-patch --stdout -1 >patch &&
1062 sed -n "/^From: /p; /^ /p; /^$/q" patch >actual &&
1063 test_cmp expect actual
1067 From: "Foo B. Bar" <author@example.com>
1069 test_expect_success 'format-patch quotes dot in from-headers' '
1070 check_author "Foo B. Bar"
1074 From: "Foo \"The Baz\" Bar" <author@example.com>
1076 test_expect_success 'format-patch quotes double-quote in from-headers' '
1077 check_author "Foo \"The Baz\" Bar"
1081 From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
1083 test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
1084 check_author "Föo Bar"
1088 From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
1090 test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
1091 check_author "Föo B. Bar"
1095 From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
1096 <author@example.com>
1098 test_expect_success 'format-patch wraps moderately long from-header (ascii)' '
1099 check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
1103 From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1104 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1105 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
1107 test_expect_success 'format-patch wraps extremely long from-header (ascii)' '
1108 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"
1112 From: "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1113 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1114 Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
1116 test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
1117 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"
1121 From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
1122 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
1123 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
1124 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
1125 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
1127 test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
1128 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"
1132 Subject: header with . in it
1134 test_expect_success 'subject lines do not have 822 atom-quoting' '
1135 echo content >>file &&
1137 git commit -m "header with . in it" &&
1138 git format-patch -k -1 --stdout >patch &&
1139 grep ^Subject: patch >actual &&
1140 test_cmp expect actual
1144 Subject: [PREFIX 1/1] header with . in it
1146 test_expect_success 'subject prefixes have space prepended' '
1147 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
1148 grep ^Subject: patch >actual &&
1149 test_cmp expect actual
1153 Subject: [1/1] header with . in it
1155 test_expect_success 'empty subject prefix does not have extra space' '
1156 git format-patch -n -1 --stdout --subject-prefix= >patch &&
1157 grep ^Subject: patch >actual &&
1158 test_cmp expect actual
1161 test_expect_success '--rfc' '
1162 cat >expect <<-\EOF &&
1163 Subject: [RFC PATCH 1/1] header with . in it
1165 git format-patch -n -1 --stdout --rfc >patch &&
1166 grep ^Subject: patch >actual &&
1167 test_cmp expect actual
1170 test_expect_success '--from=ident notices bogus ident' '
1171 test_must_fail git format-patch -1 --stdout --from=foo >patch
1174 test_expect_success '--from=ident replaces author' '
1175 git format-patch -1 --stdout --from="Me <me@example.com>" >patch &&
1176 cat >expect <<-\EOF &&
1177 From: Me <me@example.com>
1179 From: A U Thor <author@example.com>
1182 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1183 test_cmp expect patch.head
1186 test_expect_success '--from uses committer ident' '
1187 git format-patch -1 --stdout --from >patch &&
1188 cat >expect <<-\EOF &&
1189 From: C O Mitter <committer@example.com>
1191 From: A U Thor <author@example.com>
1194 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1195 test_cmp expect patch.head
1198 test_expect_success '--from omits redundant in-body header' '
1199 git format-patch -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1200 cat >expect <<-\EOF &&
1201 From: A U Thor <author@example.com>
1204 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1205 test_cmp expect patch.head
1208 test_expect_success 'in-body headers trigger content encoding' '
1209 test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
1210 test_when_finished "git reset --hard HEAD^" &&
1211 git format-patch -1 --stdout --from >patch &&
1212 cat >expect <<-\EOF &&
1213 From: C O Mitter <committer@example.com>
1214 Content-Type: text/plain; charset=UTF-8
1216 From: éxötìc <author@example.com>
1219 sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" patch >patch.head &&
1220 test_cmp expect patch.head
1225 C=$(git commit-tree HEAD^^{tree} -p HEAD) &&
1226 git format-patch --stdout --signoff $C^..$C >append_signoff.patch &&
1227 sed -n -e "1,/^---$/p" append_signoff.patch |
1228 egrep -n "^Subject|Sign|^$"
1231 test_expect_success 'signoff: commit with no body' '
1232 append_signoff </dev/null >actual &&
1233 cat <<-\EOF | sed "s/EOL$//" >expect &&
1234 4:Subject: [PATCH] EOL
1236 9:Signed-off-by: C O Mitter <committer@example.com>
1238 test_cmp expect actual
1241 test_expect_success 'signoff: commit with only subject' '
1242 echo subject | append_signoff >actual &&
1243 cat >expect <<-\EOF &&
1244 4:Subject: [PATCH] subject
1246 9:Signed-off-by: C O Mitter <committer@example.com>
1248 test_cmp expect actual
1251 test_expect_success 'signoff: commit with only subject that does not end with NL' '
1252 printf subject | append_signoff >actual &&
1253 cat >expect <<-\EOF &&
1254 4:Subject: [PATCH] subject
1256 9:Signed-off-by: C O Mitter <committer@example.com>
1258 test_cmp expect actual
1261 test_expect_success 'signoff: no existing signoffs' '
1262 append_signoff <<-\EOF >actual &&
1267 cat >expect <<-\EOF &&
1268 4:Subject: [PATCH] subject
1271 11:Signed-off-by: C O Mitter <committer@example.com>
1273 test_cmp expect actual
1276 test_expect_success 'signoff: no existing signoffs and no trailing NL' '
1277 printf "subject\n\nbody" | append_signoff >actual &&
1278 cat >expect <<-\EOF &&
1279 4:Subject: [PATCH] subject
1282 11:Signed-off-by: C O Mitter <committer@example.com>
1284 test_cmp expect actual
1287 test_expect_success 'signoff: some random signoff' '
1288 append_signoff <<-\EOF >actual &&
1293 Signed-off-by: my@house
1295 cat >expect <<-\EOF &&
1296 4:Subject: [PATCH] subject
1299 11:Signed-off-by: my@house
1300 12:Signed-off-by: C O Mitter <committer@example.com>
1302 test_cmp expect actual
1305 test_expect_success 'signoff: misc conforming footer elements' '
1306 append_signoff <<-\EOF >actual &&
1311 Signed-off-by: my@house
1312 (cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1313 Tested-by: Some One <someone@example.com>
1316 cat >expect <<-\EOF &&
1317 4:Subject: [PATCH] subject
1320 11:Signed-off-by: my@house
1321 15:Signed-off-by: C O Mitter <committer@example.com>
1323 test_cmp expect actual
1326 test_expect_success 'signoff: some random signoff-alike' '
1327 append_signoff <<-\EOF >actual &&
1331 Fooled-by-me: my@house
1333 cat >expect <<-\EOF &&
1334 4:Subject: [PATCH] subject
1337 12:Signed-off-by: C O Mitter <committer@example.com>
1339 test_cmp expect actual
1342 test_expect_success 'signoff: not really a signoff' '
1343 append_signoff <<-\EOF >actual &&
1346 I want to mention about Signed-off-by: here.
1348 cat >expect <<-\EOF &&
1349 4:Subject: [PATCH] subject
1351 9:I want to mention about Signed-off-by: here.
1353 11:Signed-off-by: C O Mitter <committer@example.com>
1355 test_cmp expect actual
1358 test_expect_success 'signoff: not really a signoff (2)' '
1359 append_signoff <<-\EOF >actual &&
1363 Signed-off-by: example happens to be wrapped here.
1365 cat >expect <<-\EOF &&
1366 4:Subject: [PATCH] subject
1368 10:Signed-off-by: example happens to be wrapped here.
1369 11:Signed-off-by: C O Mitter <committer@example.com>
1371 test_cmp expect actual
1374 test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
1375 append_signoff <<-\EOF >actual &&
1378 Signed-off-by: my@house
1379 Signed-off-by: your@house
1383 cat >expect <<-\EOF &&
1384 4:Subject: [PATCH] subject
1386 9:Signed-off-by: my@house
1387 10:Signed-off-by: your@house
1390 14:Signed-off-by: C O Mitter <committer@example.com>
1392 test_cmp expect actual
1395 test_expect_success 'signoff: the same signoff at the end' '
1396 append_signoff <<-\EOF >actual &&
1401 Signed-off-by: C O Mitter <committer@example.com>
1403 cat >expect <<-\EOF &&
1404 4:Subject: [PATCH] subject
1407 11:Signed-off-by: C O Mitter <committer@example.com>
1409 test_cmp expect actual
1412 test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
1413 printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
1414 append_signoff >actual &&
1415 cat >expect <<-\EOF &&
1416 4:Subject: [PATCH] subject
1418 9:Signed-off-by: C O Mitter <committer@example.com>
1420 test_cmp expect actual
1423 test_expect_success 'signoff: the same signoff NOT at the end' '
1424 append_signoff <<-\EOF >actual &&
1429 Signed-off-by: C O Mitter <committer@example.com>
1430 Signed-off-by: my@house
1432 cat >expect <<-\EOF &&
1433 4:Subject: [PATCH] subject
1436 11:Signed-off-by: C O Mitter <committer@example.com>
1437 12:Signed-off-by: my@house
1439 test_cmp expect actual
1442 test_expect_success 'signoff: tolerate garbage in conforming footer' '
1443 append_signoff <<-\EOF >actual &&
1450 Signed-off-by: C O Mitter <committer@example.com>
1452 cat >expect <<-\EOF &&
1453 4:Subject: [PATCH] subject
1456 13:Signed-off-by: C O Mitter <committer@example.com>
1458 test_cmp expect actual
1461 test_expect_success 'signoff: respect trailer config' '
1462 append_signoff <<-\EOF >actual &&
1468 cat >expect <<-\EOF &&
1469 4:Subject: [PATCH] subject
1472 12:Signed-off-by: C O Mitter <committer@example.com>
1474 test_cmp expect actual &&
1476 test_config trailer.Myfooter.ifexists add &&
1477 append_signoff <<-\EOF >actual &&
1483 cat >expect <<-\EOF &&
1484 4:Subject: [PATCH] subject
1486 11:Signed-off-by: C O Mitter <committer@example.com>
1488 test_cmp expect actual
1491 test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
1492 append_signoff <<-\EOF >actual &&
1499 Change-id: Ideadbeef
1500 Signed-off-by: C O Mitter <committer@example.com>
1503 cat >expect <<-\EOF &&
1504 4:Subject: [PATCH] subject
1507 14:Signed-off-by: C O Mitter <committer@example.com>
1509 test_cmp expect actual
1512 test_expect_success 'format patch ignores color.ui' '
1513 test_unconfig color.ui &&
1514 git format-patch --stdout -1 >expect &&
1515 test_config color.ui always &&
1516 git format-patch --stdout -1 >actual &&
1517 test_cmp expect actual
1520 test_expect_success 'cover letter using branch description (1)' '
1521 git checkout rebuild-1 &&
1522 test_config branch.rebuild-1.description hello &&
1523 git format-patch --stdout --cover-letter master >actual &&
1527 test_expect_success 'cover letter using branch description (2)' '
1528 git checkout rebuild-1 &&
1529 test_config branch.rebuild-1.description hello &&
1530 git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
1534 test_expect_success 'cover letter using branch description (3)' '
1535 git checkout rebuild-1 &&
1536 test_config branch.rebuild-1.description hello &&
1537 git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
1541 test_expect_success 'cover letter using branch description (4)' '
1542 git checkout rebuild-1 &&
1543 test_config branch.rebuild-1.description hello &&
1544 git format-patch --stdout --cover-letter master.. >actual &&
1548 test_expect_success 'cover letter using branch description (5)' '
1549 git checkout rebuild-1 &&
1550 test_config branch.rebuild-1.description hello &&
1551 git format-patch --stdout --cover-letter -2 HEAD >actual &&
1555 test_expect_success 'cover letter using branch description (6)' '
1556 git checkout rebuild-1 &&
1557 test_config branch.rebuild-1.description hello &&
1558 git format-patch --stdout --cover-letter -2 >actual &&
1562 test_expect_success 'cover letter with nothing' '
1563 git format-patch --stdout --cover-letter >actual &&
1564 test_line_count = 0 actual
1567 test_expect_success 'cover letter auto' '
1569 test_when_finished "rm -rf tmp;
1570 git config --unset format.coverletter" &&
1572 git config format.coverletter auto &&
1573 git format-patch -o tmp -1 >list &&
1574 test_line_count = 1 list &&
1575 git format-patch -o tmp -2 >list &&
1576 test_line_count = 3 list
1579 test_expect_success 'cover letter auto user override' '
1581 test_when_finished "rm -rf tmp;
1582 git config --unset format.coverletter" &&
1584 git config format.coverletter auto &&
1585 git format-patch -o tmp --cover-letter -1 >list &&
1586 test_line_count = 2 list &&
1587 git format-patch -o tmp --cover-letter -2 >list &&
1588 test_line_count = 3 list &&
1589 git format-patch -o tmp --no-cover-letter -1 >list &&
1590 test_line_count = 1 list &&
1591 git format-patch -o tmp --no-cover-letter -2 >list &&
1592 test_line_count = 2 list
1595 test_expect_success 'format-patch --zero-commit' '
1596 git format-patch --zero-commit --stdout v2..v1 >patch2 &&
1597 grep "^From " patch2 | sort | uniq >actual &&
1598 echo "From $ZERO_OID Mon Sep 17 00:00:00 2001" >expect &&
1599 test_cmp expect actual
1602 test_expect_success 'From line has expected format' '
1603 git format-patch --stdout v2..v1 >patch2 &&
1604 grep "^From " patch2 >from &&
1605 grep "^From $OID_REGEX Mon Sep 17 00:00:00 2001$" patch2 >filtered &&
1606 test_cmp from filtered
1609 test_expect_success 'format-patch -o with no leading directories' '
1611 git format-patch -o patches master..side &&
1612 count=$(git rev-list --count master..side) &&
1614 test_line_count = $count list
1617 test_expect_success 'format-patch -o with leading existing directories' '
1618 rm -rf existing-dir &&
1619 mkdir existing-dir &&
1620 git format-patch -o existing-dir/patches master..side &&
1621 count=$(git rev-list --count master..side) &&
1622 ls existing-dir/patches >list &&
1623 test_line_count = $count list
1626 test_expect_success 'format-patch -o with leading non-existing directories' '
1627 rm -rf non-existing-dir &&
1628 git format-patch -o non-existing-dir/patches master..side &&
1629 count=$(git rev-list --count master..side) &&
1630 test_path_is_dir non-existing-dir &&
1631 ls non-existing-dir/patches >list &&
1632 test_line_count = $count list
1635 test_expect_success 'format-patch format.outputDirectory option' '
1636 test_config format.outputDirectory patches &&
1638 git format-patch master..side &&
1639 count=$(git rev-list --count master..side) &&
1641 test_line_count = $count list
1644 test_expect_success 'format-patch -o overrides format.outputDirectory' '
1645 test_config format.outputDirectory patches &&
1646 rm -fr patches patchset &&
1647 git format-patch master..side -o patchset &&
1648 test_path_is_missing patches &&
1649 test_path_is_dir patchset
1652 test_expect_success 'format-patch --base' '
1653 git checkout patchid &&
1655 git format-patch --stdout --base=HEAD~3 -1 >patch &&
1656 tail -n 7 patch >actual1 &&
1658 git format-patch --stdout --base=HEAD~3 HEAD~.. >patch &&
1659 tail -n 7 patch >actual2 &&
1662 git rev-parse HEAD~3 >commit-id-base &&
1663 echo "base-commit: $(cat commit-id-base)" >>expect &&
1665 git show --patch HEAD~2 >patch &&
1666 git patch-id --stable <patch >patch.id.raw &&
1667 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>expect &&
1669 git show --patch HEAD~1 >patch &&
1670 git patch-id --stable <patch >patch.id.raw &&
1671 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>expect &&
1673 signature >>expect &&
1674 test_cmp expect actual1 &&
1675 test_cmp expect actual2 &&
1678 echo "base-commit: $(cat commit-id-base)" >>fail &&
1680 git show --patch HEAD~2 >patch &&
1681 git patch-id --unstable <patch >patch.id.raw &&
1682 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>fail &&
1684 git show --patch HEAD~1 >patch &&
1685 git patch-id --unstable <patch >patch.id.raw &&
1686 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>fail &&
1689 ! test_cmp fail actual1 &&
1690 ! test_cmp fail actual2
1693 test_expect_success 'format-patch --base errors out when base commit is in revision list' '
1694 test_must_fail git format-patch --base=HEAD -2 &&
1695 test_must_fail git format-patch --base=HEAD~1 -2 &&
1696 git format-patch --stdout --base=HEAD~2 -2 >patch &&
1697 grep "^base-commit:" patch >actual &&
1698 git rev-parse HEAD~2 >commit-id-base &&
1699 echo "base-commit: $(cat commit-id-base)" >expect &&
1700 test_cmp expect actual
1703 test_expect_success 'format-patch --base errors out when base commit is not ancestor of revision list' '
1704 # For history as below:
1706 # ---Q---P---Z---Y---*---X
1710 # If "format-patch Z..X" is given, P and Z can not be specified as the base commit
1711 git checkout -b topic1 master &&
1712 git rev-parse HEAD >commit-id-base &&
1714 git rev-parse HEAD >commit-id-P &&
1716 git rev-parse HEAD >commit-id-Z &&
1718 git checkout -b topic2 master &&
1722 test_must_fail git format-patch --base=$(cat commit-id-P) -3 &&
1723 test_must_fail git format-patch --base=$(cat commit-id-Z) -3 &&
1724 git format-patch --stdout --base=$(cat commit-id-base) -3 >patch &&
1725 grep "^base-commit:" patch >actual &&
1726 echo "base-commit: $(cat commit-id-base)" >expect &&
1727 test_cmp expect actual
1730 test_expect_success 'format-patch --base=auto' '
1731 git checkout -b upstream master &&
1732 git checkout -b local upstream &&
1733 git branch --set-upstream-to=upstream &&
1736 git format-patch --stdout --base=auto -2 >patch &&
1737 grep "^base-commit:" patch >actual &&
1738 git rev-parse upstream >commit-id-base &&
1739 echo "base-commit: $(cat commit-id-base)" >expect &&
1740 test_cmp expect actual
1743 test_expect_success 'format-patch errors out when history involves criss-cross' '
1744 # setup criss-cross history
1752 git checkout master &&
1754 git checkout -b xb master &&
1756 git checkout -b xc master &&
1758 git checkout -b xbc xb -- &&
1760 git checkout -b xcb xc -- &&
1761 git branch --set-upstream-to=xbc &&
1767 test_must_fail git format-patch --base=auto -1
1770 test_expect_success 'format-patch format.useAutoBaseoption' '
1771 test_when_finished "git config --unset format.useAutoBase" &&
1772 git checkout local &&
1773 git config format.useAutoBase true &&
1774 git format-patch --stdout -1 >patch &&
1775 grep "^base-commit:" patch >actual &&
1776 git rev-parse upstream >commit-id-base &&
1777 echo "base-commit: $(cat commit-id-base)" >expect &&
1778 test_cmp expect actual
1781 test_expect_success 'format-patch --base overrides format.useAutoBase' '
1782 test_when_finished "git config --unset format.useAutoBase" &&
1783 git config format.useAutoBase true &&
1784 git format-patch --stdout --base=HEAD~1 -1 >patch &&
1785 grep "^base-commit:" patch >actual &&
1786 git rev-parse HEAD~1 >commit-id-base &&
1787 echo "base-commit: $(cat commit-id-base)" >expect &&
1788 test_cmp expect actual
1791 test_expect_success 'format-patch --base with --attach' '
1792 git format-patch --attach=mimemime --stdout --base=HEAD~ -1 >patch &&
1793 sed -n -e "/^base-commit:/s/.*/1/p" -e "/^---*mimemime--$/s/.*/2/p" \
1795 test_write_lines 1 2 >expect &&
1796 test_cmp expect actual
1798 test_expect_success 'format-patch --attach cover-letter only is non-multipart' '
1799 test_when_finished "rm -fr patches" &&
1800 git format-patch -o patches --cover-letter --attach=mimemime --base=HEAD~ -1 &&
1801 ! egrep "^--+mimemime" patches/0000*.patch &&
1802 egrep "^--+mimemime$" patches/0001*.patch >output &&
1803 test_line_count = 2 output &&
1804 egrep "^--+mimemime--$" patches/0001*.patch >output &&
1805 test_line_count = 1 output
1808 test_expect_success 'format-patch --pretty=mboxrd' '
1810 cat >msg <<-INPUT_END &&
1811 mboxrd should escape the body
1813 From could trip up a loose mbox parser
1814 >From extra escape for reversibility
1815 >>From extra escape for reversibility 2
1816 from lower case not escaped
1817 Fromm bad speling not escaped
1818 From with leading space not escaped
1827 cat >expect <<-INPUT_END &&
1828 >From could trip up a loose mbox parser
1829 >>From extra escape for reversibility
1830 >>>From extra escape for reversibility 2
1831 from lower case not escaped
1832 Fromm bad speling not escaped
1833 From with leading space not escaped
1842 C=$(git commit-tree HEAD^^{tree} -p HEAD <msg) &&
1843 git format-patch --pretty=mboxrd --stdout -1 $C~1..$C >patch &&
1844 git grep -h --no-index -A11 \
1845 "^>From could trip up a loose mbox parser" patch >actual &&
1846 test_cmp expect actual
1849 test_expect_success 'interdiff: setup' '
1850 git checkout -b boop master &&
1851 test_commit fnorp blorp &&
1852 test_commit fleep blorp
1855 test_expect_success 'interdiff: cover-letter' '
1856 sed "y/q/ /" >expect <<-\EOF &&
1860 git format-patch --cover-letter --interdiff=boop~2 -1 boop &&
1861 test_i18ngrep "^Interdiff:$" 0000-cover-letter.patch &&
1862 test_i18ngrep ! "^Interdiff:$" 0001-fleep.patch &&
1863 sed "1,/^@@ /d; /^-- $/q" 0000-cover-letter.patch >actual &&
1864 test_cmp expect actual
1867 test_expect_success 'interdiff: reroll-count' '
1868 git format-patch --cover-letter --interdiff=boop~2 -v2 -1 boop &&
1869 test_i18ngrep "^Interdiff ..* v1:$" v2-0000-cover-letter.patch
1872 test_expect_success 'interdiff: solo-patch' '
1873 cat >expect <<-\EOF &&
1877 git format-patch --interdiff=boop~2 -1 boop &&
1878 test_i18ngrep "^Interdiff:$" 0001-fleep.patch &&
1879 sed "1,/^ @@ /d; /^$/q" 0001-fleep.patch >actual &&
1880 test_cmp expect actual