3 # Copyright (c) 2006 Junio C Hamano
6 test_description='various format-patch tests'
8 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
9 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
12 . "$TEST_DIRECTORY"/lib-terminal.sh
14 test_expect_success setup '
15 for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i"; done >file &&
19 git commit -m Initial &&
20 git checkout -b side &&
22 for i in 1 2 5 6 A B C 7 8 9 10; do echo "$i"; done >file &&
25 git commit -m "Side changes #1" &&
27 for i in D E F; do echo "$i"; done >>file &&
28 git update-index file &&
30 git commit -m "Side changes #2" &&
33 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file &&
34 git update-index file &&
36 git commit -m "Side changes #3 with \\n backslash-n in it." &&
39 git diff-tree -p C2 >patch &&
40 git apply --index <patch &&
42 git commit -m "Main accepts moral equivalent of #2" &&
45 git checkout -b patchid &&
46 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file2 &&
47 for i in 1 2 3 A 4 B C 7 8 9 10 D E F 5 6; do echo "$i"; done >file3 &&
48 for i in 8 9 10; do echo "$i"; done >file &&
49 git add file file2 file3 &&
51 git commit -m "patchid 1" &&
52 for i in 4 A B 7 8 9 10; do echo "$i"; done >file2 &&
53 for i in 8 9 10 5 6; do echo "$i"; done >file3 &&
54 git add file2 file3 &&
56 git commit -m "patchid 2" &&
57 for i in 10 5 6; do echo "$i"; done >file &&
60 git commit -m "patchid 3" &&
65 test_expect_success 'format-patch --ignore-if-in-upstream' '
66 git format-patch --stdout main..side >patch0 &&
67 grep "^From " patch0 >from0 &&
68 test_line_count = 3 from0
71 test_expect_success 'format-patch --ignore-if-in-upstream' '
72 git format-patch --stdout \
73 --ignore-if-in-upstream main..side >patch1 &&
74 grep "^From " patch1 >from1 &&
75 test_line_count = 2 from1
78 test_expect_success 'format-patch --ignore-if-in-upstream handles tags' '
79 git tag -a v1 -m tag side &&
80 git tag -a v2 -m tag main &&
81 git format-patch --stdout --ignore-if-in-upstream v2..v1 >patch1 &&
82 grep "^From " patch1 >from1 &&
83 test_line_count = 2 from1
86 test_expect_success "format-patch doesn't consider merge commits" '
87 git checkout -b feature main &&
88 echo "Another line" >>file &&
90 git commit -am "Feature branch change #1" &&
91 echo "Yet another line" >>file &&
93 git commit -am "Feature branch change #2" &&
94 git checkout -b merger main &&
96 git merge --no-ff feature &&
97 git format-patch -3 --stdout >patch &&
98 grep "^From " patch >from &&
99 test_line_count = 3 from
102 test_expect_success 'format-patch result applies' '
103 git checkout -b rebuild-0 main &&
105 git rev-list main.. >list &&
106 test_line_count = 2 list
109 test_expect_success 'format-patch --ignore-if-in-upstream result applies' '
110 git checkout -b rebuild-1 main &&
112 git rev-list main.. >list &&
113 test_line_count = 2 list
116 test_expect_success 'commit did not screw up the log message' '
117 git cat-file commit side >actual &&
118 grep "^Side .* with .* backslash-n" actual
121 test_expect_success 'format-patch did not screw up the log message' '
122 grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
123 grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
126 test_expect_success 'replay did not screw up the log message' '
127 git cat-file commit rebuild-1 >actual &&
128 grep "^Side .* with .* backslash-n" actual
131 test_expect_success 'extra headers' '
132 git config format.headers "To: R E Cipient <rcipient@example.com>
134 git config --add format.headers "Cc: S E Cipient <scipient@example.com>
136 git format-patch --stdout main..side >patch2 &&
137 sed -e "/^\$/q" patch2 >hdrs2 &&
138 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs2 &&
139 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs2
142 test_expect_success 'extra headers without newlines' '
143 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
144 git config --add format.headers "Cc: S E Cipient <scipient@example.com>" &&
145 git format-patch --stdout main..side >patch3 &&
146 sed -e "/^\$/q" patch3 >hdrs3 &&
147 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs3 &&
148 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs3
151 test_expect_success 'extra headers with multiple To:s' '
152 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
153 git config --add format.headers "To: S E Cipient <scipient@example.com>" &&
154 git format-patch --stdout main..side >patch4 &&
155 sed -e "/^\$/q" patch4 >hdrs4 &&
156 grep "^To: R E Cipient <rcipient@example.com>,\$" hdrs4 &&
157 grep "^ *S E Cipient <scipient@example.com>\$" hdrs4
160 test_expect_success 'additional command line cc (ascii)' '
161 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
162 git format-patch --cc="S E Cipient <scipient@example.com>" --stdout main..side >patch5 &&
163 sed -e "/^\$/q" patch5 >hdrs5 &&
164 grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs5 &&
165 grep "^ *S E Cipient <scipient@example.com>\$" hdrs5
168 test_expect_failure 'additional command line cc (rfc822)' '
169 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
170 git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout main..side >patch5 &&
171 sed -e "/^\$/q" patch5 >hdrs5 &&
172 grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs5 &&
173 grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" hdrs5
176 test_expect_success 'command line headers' '
177 git config --unset-all format.headers &&
178 git format-patch --add-header="Cc: R E Cipient <rcipient@example.com>" --stdout main..side >patch6 &&
179 sed -e "/^\$/q" patch6 >hdrs6 &&
180 grep "^Cc: R E Cipient <rcipient@example.com>\$" hdrs6
183 test_expect_success 'configuration headers and command line headers' '
184 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
185 git format-patch --add-header="Cc: S E Cipient <scipient@example.com>" --stdout main..side >patch7 &&
186 sed -e "/^\$/q" patch7 >hdrs7 &&
187 grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs7 &&
188 grep "^ *S E Cipient <scipient@example.com>\$" hdrs7
191 test_expect_success 'command line To: header (ascii)' '
192 git config --unset-all format.headers &&
193 git format-patch --to="R E Cipient <rcipient@example.com>" --stdout main..side >patch8 &&
194 sed -e "/^\$/q" patch8 >hdrs8 &&
195 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs8
198 test_expect_failure 'command line To: header (rfc822)' '
199 git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout main..side >patch8 &&
200 sed -e "/^\$/q" patch8 >hdrs8 &&
201 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" hdrs8
204 test_expect_failure 'command line To: header (rfc2047)' '
205 git format-patch --to="R Ä Cipient <rcipient@example.com>" --stdout main..side >patch8 &&
206 sed -e "/^\$/q" patch8 >hdrs8 &&
207 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" hdrs8
210 test_expect_success 'configuration To: header (ascii)' '
211 git config format.to "R E Cipient <rcipient@example.com>" &&
212 git format-patch --stdout main..side >patch9 &&
213 sed -e "/^\$/q" patch9 >hdrs9 &&
214 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs9
217 test_expect_failure 'configuration To: header (rfc822)' '
218 git config format.to "R. E. Cipient <rcipient@example.com>" &&
219 git format-patch --stdout main..side >patch9 &&
220 sed -e "/^\$/q" patch9 >hdrs9 &&
221 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" hdrs9
224 test_expect_failure 'configuration To: header (rfc2047)' '
225 git config format.to "R Ä Cipient <rcipient@example.com>" &&
226 git format-patch --stdout main..side >patch9 &&
227 sed -e "/^\$/q" patch9 >hdrs9 &&
228 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" hdrs9
231 # check_patch <patch>: Verify that <patch> looks like a half-sane
232 # patch email to avoid a false positive with !grep
234 grep -e "^From:" "$1" &&
235 grep -e "^Date:" "$1" &&
236 grep -e "^Subject:" "$1"
239 test_expect_success 'format.from=false' '
240 git -c format.from=false format-patch --stdout main..side >patch &&
241 sed -e "/^\$/q" patch >hdrs &&
243 ! grep "^From: C O Mitter <committer@example.com>\$" hdrs
246 test_expect_success 'format.from=true' '
247 git -c format.from=true format-patch --stdout main..side >patch &&
248 sed -e "/^\$/q" patch >hdrs &&
250 grep "^From: C O Mitter <committer@example.com>\$" hdrs
253 test_expect_success 'format.from with address' '
254 git -c format.from="F R Om <from@example.com>" format-patch --stdout main..side >patch &&
255 sed -e "/^\$/q" patch >hdrs &&
257 grep "^From: F R Om <from@example.com>\$" hdrs
260 test_expect_success '--no-from overrides format.from' '
261 git -c format.from="F R Om <from@example.com>" format-patch --no-from --stdout main..side >patch &&
262 sed -e "/^\$/q" patch >hdrs &&
264 ! grep "^From: F R Om <from@example.com>\$" hdrs
267 test_expect_success '--from overrides format.from' '
268 git -c format.from="F R Om <from@example.com>" format-patch --from --stdout main..side >patch &&
269 sed -e "/^\$/q" patch >hdrs &&
271 ! grep "^From: F R Om <from@example.com>\$" hdrs
274 test_expect_success '--no-to overrides config.to' '
275 git config --replace-all format.to \
276 "R E Cipient <rcipient@example.com>" &&
277 git format-patch --no-to --stdout main..side >patch10 &&
278 sed -e "/^\$/q" patch10 >hdrs10 &&
279 check_patch hdrs10 &&
280 ! grep "^To: R E Cipient <rcipient@example.com>\$" hdrs10
283 test_expect_success '--no-to and --to replaces config.to' '
284 git config --replace-all format.to \
285 "Someone <someone@out.there>" &&
286 git format-patch --no-to --to="Someone Else <else@out.there>" \
287 --stdout main..side >patch11 &&
288 sed -e "/^\$/q" patch11 >hdrs11 &&
289 check_patch hdrs11 &&
290 ! grep "^To: Someone <someone@out.there>\$" hdrs11 &&
291 grep "^To: Someone Else <else@out.there>\$" hdrs11
294 test_expect_success '--no-cc overrides config.cc' '
295 git config --replace-all format.cc \
296 "C E Cipient <rcipient@example.com>" &&
297 git format-patch --no-cc --stdout main..side >patch12 &&
298 sed -e "/^\$/q" patch12 >hdrs12 &&
299 check_patch hdrs12 &&
300 ! grep "^Cc: C E Cipient <rcipient@example.com>\$" hdrs12
303 test_expect_success '--no-add-header overrides config.headers' '
304 git config --replace-all format.headers \
305 "Header1: B E Cipient <rcipient@example.com>" &&
306 git format-patch --no-add-header --stdout main..side >patch13 &&
307 sed -e "/^\$/q" patch13 >hdrs13 &&
308 check_patch hdrs13 &&
309 ! grep "^Header1: B E Cipient <rcipient@example.com>\$" hdrs13
312 test_expect_success 'multiple files' '
315 git format-patch -o patches/ main &&
316 ls patches/0001-Side-changes-1.patch patches/0002-Side-changes-2.patch patches/0003-Side-changes-3-with-n-backslash-n-in-it.patch
319 test_expect_success 'reroll count' '
321 git format-patch -o patches --cover-letter --reroll-count 4 main..side >list &&
322 ! grep -v "^patches/v4-000[0-3]-" list &&
323 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
324 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
327 test_expect_success 'reroll count (-v)' '
329 git format-patch -o patches --cover-letter -v4 main..side >list &&
330 ! grep -v "^patches/v4-000[0-3]-" list &&
331 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
332 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
338 git format-patch --stdout "$@" >patch &&
339 # Prints everything between the Message-ID and In-Reply-To,
340 # and replaces all Message-ID-lookalikes by a sequence number
342 if (/^(message-id|references|in-reply-to)/i) {
348 $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
349 for $k (keys %h) {s/$k/$h{$k}/};
352 print "---\n" if /^From /i;
354 test_cmp "$expect" actual
357 cat >>expect.no-threading <<EOF
363 test_expect_success 'no threading' '
365 check_threading expect.no-threading main
368 cat >expect.thread <<EOF
381 test_expect_success 'thread' '
382 check_threading expect.thread --thread main
385 cat >expect.in-reply-to <<EOF
400 test_expect_success 'thread in-reply-to' '
401 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
405 cat >expect.cover-letter <<EOF
422 test_expect_success 'thread cover-letter' '
423 check_threading expect.cover-letter --cover-letter --thread main
426 cat >expect.cl-irt <<EOF
448 test_expect_success 'thread cover-letter in-reply-to' '
449 check_threading expect.cl-irt --cover-letter \
450 --in-reply-to="<test.message>" --thread main
453 test_expect_success 'thread explicit shallow' '
454 check_threading expect.cl-irt --cover-letter \
455 --in-reply-to="<test.message>" --thread=shallow main
458 cat >expect.deep <<EOF
472 test_expect_success 'thread deep' '
473 check_threading expect.deep --thread=deep main
476 cat >expect.deep-irt <<EOF
494 test_expect_success 'thread deep in-reply-to' '
495 check_threading expect.deep-irt --thread=deep \
496 --in-reply-to="<test.message>" main
499 cat >expect.deep-cl <<EOF
519 test_expect_success 'thread deep cover-letter' '
520 check_threading expect.deep-cl --cover-letter --thread=deep main
523 cat >expect.deep-cl-irt <<EOF
548 test_expect_success 'thread deep cover-letter in-reply-to' '
549 check_threading expect.deep-cl-irt --cover-letter \
550 --in-reply-to="<test.message>" --thread=deep main
553 test_expect_success 'thread via config' '
554 test_config format.thread true &&
555 check_threading expect.thread main
558 test_expect_success 'thread deep via config' '
559 test_config format.thread deep &&
560 check_threading expect.deep main
563 test_expect_success 'thread config + override' '
564 test_config format.thread deep &&
565 check_threading expect.thread --thread main
568 test_expect_success 'thread config + --no-thread' '
569 test_config format.thread deep &&
570 check_threading expect.no-threading --no-thread main
573 test_expect_success 'excessive subject' '
576 before=$(git hash-object file) &&
577 before=$(git rev-parse --short $before) &&
578 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
579 after=$(git hash-object file) &&
580 after=$(git rev-parse --short $after) &&
581 git update-index file &&
582 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." &&
583 git format-patch -o patches/ main..side &&
584 ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
587 test_expect_success 'failure to write cover-letter aborts gracefully' '
588 test_when_finished "rmdir 0000-cover-letter.patch" &&
589 mkdir 0000-cover-letter.patch &&
590 test_must_fail git format-patch --no-renames --cover-letter -1
593 test_expect_success 'cover-letter inherits diff options' '
596 git format-patch --no-renames --cover-letter -1 &&
597 check_patch 0000-cover-letter.patch &&
598 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
599 git format-patch --cover-letter -1 -M &&
600 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
604 This is an excessively long subject line for a message due to the
605 habit some projects have of not having a short, one-line subject at
606 the start of the commit message, but rather sticking a whole
607 paragraph right at the start as the only thing in the commit
608 message. It had better not become the filename for the patch.
613 test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
614 git format-patch --cover-letter -2 &&
615 sed -e "1,/A U Thor/d" -e "/^\$/q" 0000-cover-letter.patch >output &&
616 test_cmp expect output
620 index $before..$after 100644
631 test_expect_success 'format-patch respects -U' '
632 git format-patch -U4 -2 &&
633 sed -e "1,/^diff/d" -e "/^+5/q" \
634 <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
636 test_cmp expect output
641 diff --git a/file b/file
642 index $before..$after 100644
652 test_expect_success 'format-patch -p suppresses stat' '
653 git format-patch -p -2 &&
654 sed -e "1,/^\$/d" -e "/^+5/q" 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch >output &&
655 test_cmp expect output
658 test_expect_success 'format-patch from a subdirectory (1)' '
669 echo "Oops? $filename"
676 test_expect_success 'format-patch from a subdirectory (2)' '
681 git format-patch -1 -o ..
687 echo "Oops? $filename"
691 basename=$(expr "$filename" : ".*/\(.*\)") &&
692 test -f "sub/$basename"
695 test_expect_success 'format-patch from a subdirectory (3)' '
701 git format-patch -1 -o "$TRASH_DIRECTORY"
703 basename=$(expr "$filename" : ".*/\(.*\)") &&
707 test_expect_success 'format-patch --in-reply-to' '
708 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" >patch8 &&
709 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
710 grep "^References: <baz@foo.bar>" patch8
713 test_expect_success 'format-patch --signoff' '
714 git format-patch -1 --signoff --stdout >out &&
715 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
718 test_expect_success 'format-patch --notes --signoff' '
719 git notes --ref test add -m "test message" HEAD &&
720 git format-patch -1 --signoff --stdout --notes=test >out &&
721 # Three dashes must come after S-o-b
722 ! sed "/^Signed-off-by: /q" out | grep "test message" &&
723 sed "1,/^Signed-off-by: /d" out | grep "test message" &&
724 # Notes message must come after three dashes
725 ! sed "/^---$/q" out | grep "test message" &&
726 sed "1,/^---$/d" out | grep "test message"
729 test_expect_success 'format-patch notes output control' '
730 git notes add -m "notes config message" HEAD &&
731 test_when_finished git notes remove HEAD &&
733 git format-patch -1 --stdout >out &&
734 ! grep "notes config message" out &&
735 git format-patch -1 --stdout --notes >out &&
736 grep "notes config message" out &&
737 git format-patch -1 --stdout --no-notes >out &&
738 ! grep "notes config message" out &&
739 git format-patch -1 --stdout --notes --no-notes >out &&
740 ! grep "notes config message" out &&
741 git format-patch -1 --stdout --no-notes --notes >out &&
742 grep "notes config message" out &&
744 test_config format.notes true &&
745 git format-patch -1 --stdout >out &&
746 grep "notes config message" out &&
747 git format-patch -1 --stdout --notes >out &&
748 grep "notes config message" out &&
749 git format-patch -1 --stdout --no-notes >out &&
750 ! grep "notes config message" out &&
751 git format-patch -1 --stdout --notes --no-notes >out &&
752 ! grep "notes config message" out &&
753 git format-patch -1 --stdout --no-notes --notes >out &&
754 grep "notes config message" out
757 test_expect_success 'format-patch with multiple notes refs' '
758 git notes --ref note1 add -m "this is note 1" HEAD &&
759 test_when_finished git notes --ref note1 remove HEAD &&
760 git notes --ref note2 add -m "this is note 2" HEAD &&
761 test_when_finished git notes --ref note2 remove HEAD &&
763 git format-patch -1 --stdout >out &&
764 ! grep "this is note 1" out &&
765 ! grep "this is note 2" out &&
766 git format-patch -1 --stdout --notes=note1 >out &&
767 grep "this is note 1" out &&
768 ! grep "this is note 2" out &&
769 git format-patch -1 --stdout --notes=note2 >out &&
770 ! grep "this is note 1" out &&
771 grep "this is note 2" out &&
772 git format-patch -1 --stdout --notes=note1 --notes=note2 >out &&
773 grep "this is note 1" out &&
774 grep "this is note 2" out &&
776 test_config format.notes note1 &&
777 git format-patch -1 --stdout >out &&
778 grep "this is note 1" out &&
779 ! grep "this is note 2" out &&
780 git format-patch -1 --stdout --no-notes >out &&
781 ! grep "this is note 1" out &&
782 ! grep "this is note 2" out &&
783 git format-patch -1 --stdout --notes=note2 >out &&
784 grep "this is note 1" out &&
785 grep "this is note 2" out &&
786 git format-patch -1 --stdout --no-notes --notes=note2 >out &&
787 ! grep "this is note 1" out &&
788 grep "this is note 2" out &&
790 git config --add format.notes note2 &&
791 git format-patch -1 --stdout >out &&
792 grep "this is note 1" out &&
793 grep "this is note 2" out &&
794 git format-patch -1 --stdout --no-notes >out &&
795 ! grep "this is note 1" out &&
796 ! grep "this is note 2" out
799 test_expect_success 'format-patch with multiple notes refs in config' '
800 test_when_finished "test_unconfig format.notes" &&
802 git notes --ref note1 add -m "this is note 1" HEAD &&
803 test_when_finished git notes --ref note1 remove HEAD &&
804 git notes --ref note2 add -m "this is note 2" HEAD &&
805 test_when_finished git notes --ref note2 remove HEAD &&
807 git config format.notes note1 &&
808 git format-patch -1 --stdout >out &&
809 grep "this is note 1" out &&
810 ! grep "this is note 2" out &&
811 git config format.notes note2 &&
812 git format-patch -1 --stdout >out &&
813 ! grep "this is note 1" out &&
814 grep "this is note 2" out &&
815 git config --add format.notes note1 &&
816 git format-patch -1 --stdout >out &&
817 grep "this is note 1" out &&
818 grep "this is note 2" out &&
820 git config --replace-all format.notes note1 &&
821 git config --add format.notes false &&
822 git format-patch -1 --stdout >out &&
823 ! grep "this is note 1" out &&
824 ! grep "this is note 2" out &&
825 git config --add format.notes note2 &&
826 git format-patch -1 --stdout >out &&
827 ! grep "this is note 1" out &&
828 grep "this is note 2" out
831 echo "fatal: --name-only does not make sense" >expect.name-only
832 echo "fatal: --name-status does not make sense" >expect.name-status
833 echo "fatal: --check does not make sense" >expect.check
835 test_expect_success 'options no longer allowed for format-patch' '
836 test_must_fail git format-patch --name-only 2>output &&
837 test_i18ncmp expect.name-only output &&
838 test_must_fail git format-patch --name-status 2>output &&
839 test_i18ncmp expect.name-status output &&
840 test_must_fail git format-patch --check 2>output &&
841 test_i18ncmp expect.check output
844 test_expect_success 'format-patch --numstat should produce a patch' '
845 git format-patch --numstat --stdout main..side >output &&
846 grep "^diff --git a/" output >diff &&
847 test_line_count = 5 diff
850 test_expect_success 'format-patch -- <path>' '
851 git format-patch main..side -- file 2>error &&
852 ! grep "Use .--" error
855 test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
856 git format-patch --ignore-if-in-upstream HEAD
859 test_expect_success 'get git version' '
860 git_version=$(git --version) &&
861 git_version=${git_version##* }
865 printf "%s\n%s\n\n" "-- " "${1:-$git_version}"
868 test_expect_success 'format-patch default signature' '
869 git format-patch --stdout -1 >patch &&
870 tail -n 3 patch >output &&
872 test_cmp expect output
875 test_expect_success 'format-patch --signature' '
876 git format-patch --stdout --signature="my sig" -1 >patch &&
877 tail -n 3 patch >output &&
878 signature "my sig" >expect &&
879 test_cmp expect output
882 test_expect_success 'format-patch with format.signature config' '
883 git config format.signature "config sig" &&
884 git format-patch --stdout -1 >output &&
885 grep "config sig" output
888 test_expect_success 'format-patch --signature overrides format.signature' '
889 git config format.signature "config sig" &&
890 git format-patch --stdout --signature="overrides" -1 >output &&
891 ! grep "config sig" output &&
892 grep "overrides" output
895 test_expect_success 'format-patch --no-signature ignores format.signature' '
896 git config format.signature "config sig" &&
897 git format-patch --stdout --signature="my sig" --no-signature \
899 check_patch output &&
900 ! grep "config sig" output &&
901 ! grep "my sig" output &&
902 ! grep "^-- \$" output
905 test_expect_success 'format-patch --signature --cover-letter' '
906 git config --unset-all format.signature &&
907 git format-patch --stdout --signature="my sig" --cover-letter \
909 grep "my sig" output >sig &&
910 test_line_count = 2 sig
913 test_expect_success 'format.signature="" suppresses signatures' '
914 git config format.signature "" &&
915 git format-patch --stdout -1 >output &&
916 check_patch output &&
917 ! grep "^-- \$" output
920 test_expect_success 'format-patch --no-signature suppresses signatures' '
921 git config --unset-all format.signature &&
922 git format-patch --stdout --no-signature -1 >output &&
923 check_patch output &&
924 ! grep "^-- \$" output
927 test_expect_success 'format-patch --signature="" suppresses signatures' '
928 git format-patch --stdout --signature="" -1 >output &&
929 check_patch output &&
930 ! grep "^-- \$" output
933 test_expect_success 'prepare mail-signature input' '
934 cat >mail-signature <<-\EOF
936 Test User <test.email@kernel.org>
937 http://git.kernel.org/cgit/git/git.git
939 git.kernel.org/?p=git/git.git;a=summary
944 test_expect_success '--signature-file=file works' '
945 git format-patch --stdout --signature-file=mail-signature -1 >output &&
946 check_patch output &&
947 sed -e "1,/^-- \$/d" output >actual &&
949 cat mail-signature && echo
951 test_cmp expect actual
954 test_expect_success 'format.signaturefile works' '
955 test_config format.signaturefile mail-signature &&
956 git format-patch --stdout -1 >output &&
957 check_patch output &&
958 sed -e "1,/^-- \$/d" output >actual &&
960 cat mail-signature && echo
962 test_cmp expect actual
965 test_expect_success '--no-signature suppresses format.signaturefile ' '
966 test_config format.signaturefile mail-signature &&
967 git format-patch --stdout --no-signature -1 >output &&
968 check_patch output &&
969 ! grep "^-- \$" output
972 test_expect_success '--signature-file overrides format.signaturefile' '
973 cat >other-mail-signature <<-\EOF &&
974 Use this other signature instead of mail-signature.
976 test_config format.signaturefile mail-signature &&
977 git format-patch --stdout \
978 --signature-file=other-mail-signature -1 >output &&
979 check_patch output &&
980 sed -e "1,/^-- \$/d" output >actual &&
982 cat other-mail-signature && echo
984 test_cmp expect actual
987 test_expect_success '--signature overrides format.signaturefile' '
988 test_config format.signaturefile mail-signature &&
989 git format-patch --stdout --signature="my sig" -1 >output &&
990 check_patch output &&
994 test_expect_success TTY 'format-patch --stdout paginates' '
996 test_terminal env GIT_PAGER="wc >pager_used" git format-patch --stdout --all &&
997 test_path_is_file pager_used
1000 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
1002 test_terminal env GIT_PAGER="wc >pager_used" git --no-pager format-patch --stdout --all &&
1003 test_terminal env GIT_PAGER="wc >pager_used" git -c "pager.format-patch=false" format-patch --stdout --all &&
1004 test_path_is_missing pager_used &&
1005 test_path_is_missing .git/pager_used
1008 test_expect_success 'format-patch handles multi-line subjects' '
1010 echo content >>file &&
1011 for i in one two three; do echo $i; done >msg &&
1013 git commit -F msg &&
1014 git format-patch -o patches -1 &&
1015 grep ^Subject: patches/0001-one.patch >actual &&
1016 echo "Subject: [PATCH] one two three" >expect &&
1017 test_cmp expect actual
1020 test_expect_success 'format-patch handles multi-line encoded subjects' '
1022 echo content >>file &&
1023 for i in en två tre; do echo $i; done >msg &&
1025 git commit -F msg &&
1026 git format-patch -o patches -1 &&
1027 grep ^Subject: patches/0001-en.patch >actual &&
1028 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
1029 test_cmp expect actual
1033 M64=$M8$M8$M8$M8$M8$M8$M8$M8
1034 M512=$M64$M64$M64$M64$M64$M64$M64$M64
1036 Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1037 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1038 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1039 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1040 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1041 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1042 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1044 test_expect_success 'format-patch wraps extremely long subject (ascii)' '
1045 echo content >>file &&
1047 git commit -m "$M512" &&
1048 git format-patch --stdout -1 >patch &&
1049 sed -n "/^Subject/p; /^ /p; /^$/q" patch >subject &&
1050 test_cmp expect subject
1054 M64=$M8$M8$M8$M8$M8$M8$M8$M8
1055 M512=$M64$M64$M64$M64$M64$M64$M64$M64
1057 Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1058 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1059 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1060 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1061 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1062 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1063 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1064 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1065 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1066 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1067 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1068 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1069 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1070 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1071 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1072 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1073 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1074 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1075 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1076 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1077 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1078 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1079 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1082 test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
1084 echo content >>file &&
1086 git commit -m "$M512" &&
1087 git format-patch --stdout -1 >patch &&
1088 sed -n "/^Subject/p; /^ /p; /^$/q" patch >subject &&
1089 test_cmp expect subject
1093 echo content >>file &&
1095 GIT_AUTHOR_NAME=$1 git commit -m author-check &&
1096 git format-patch --stdout -1 >patch &&
1097 sed -n "/^From: /p; /^ /p; /^$/q" patch >actual &&
1098 test_cmp expect actual
1102 From: "Foo B. Bar" <author@example.com>
1104 test_expect_success 'format-patch quotes dot in from-headers' '
1105 check_author "Foo B. Bar"
1109 From: "Foo \"The Baz\" Bar" <author@example.com>
1111 test_expect_success 'format-patch quotes double-quote in from-headers' '
1112 check_author "Foo \"The Baz\" Bar"
1116 From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
1118 test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
1119 check_author "Föo Bar"
1123 From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
1125 test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
1126 check_author "Föo B. Bar"
1130 From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
1131 <author@example.com>
1133 test_expect_success 'format-patch wraps moderately long from-header (ascii)' '
1134 check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
1138 From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1139 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1140 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
1142 test_expect_success 'format-patch wraps extremely long from-header (ascii)' '
1143 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"
1147 From: "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1148 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1149 Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
1151 test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
1152 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"
1156 From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
1157 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
1158 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
1159 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
1160 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
1162 test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
1163 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"
1167 From: Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1168 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1169 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
1171 test_expect_success 'format-patch wraps extremely long from-header (non-ASCII without Q-encoding)' '
1172 echo content >>file &&
1174 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" \
1175 git commit -m author-check &&
1176 git format-patch --no-encode-email-headers --stdout -1 >patch &&
1177 sed -n "/^From: /p; /^ /p; /^$/q" patch >actual &&
1178 test_cmp expect actual
1182 Subject: [PATCH] Foö
1184 test_expect_success 'subject lines are unencoded with --no-encode-email-headers' '
1185 echo content >>file &&
1187 git commit -m "Foö" &&
1188 git format-patch --no-encode-email-headers -1 --stdout >patch &&
1189 grep ^Subject: patch >actual &&
1190 test_cmp expect actual
1194 Subject: [PATCH] Foö
1196 test_expect_success 'subject lines are unencoded with format.encodeEmailHeaders=false' '
1197 echo content >>file &&
1199 git commit -m "Foö" &&
1200 git config format.encodeEmailHeaders false &&
1201 git format-patch -1 --stdout >patch &&
1202 grep ^Subject: patch >actual &&
1203 test_cmp expect actual
1207 Subject: [PATCH] =?UTF-8?q?Fo=C3=B6?=
1209 test_expect_success '--encode-email-headers overrides format.encodeEmailHeaders' '
1210 echo content >>file &&
1212 git commit -m "Foö" &&
1213 git config format.encodeEmailHeaders false &&
1214 git format-patch --encode-email-headers -1 --stdout >patch &&
1215 grep ^Subject: patch >actual &&
1216 test_cmp expect actual
1220 Subject: header with . in it
1222 test_expect_success 'subject lines do not have 822 atom-quoting' '
1223 echo content >>file &&
1225 git commit -m "header with . in it" &&
1226 git format-patch -k -1 --stdout >patch &&
1227 grep ^Subject: patch >actual &&
1228 test_cmp expect actual
1232 Subject: [PREFIX 1/1] header with . in it
1234 test_expect_success 'subject prefixes have space prepended' '
1235 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
1236 grep ^Subject: patch >actual &&
1237 test_cmp expect actual
1241 Subject: [1/1] header with . in it
1243 test_expect_success 'empty subject prefix does not have extra space' '
1244 git format-patch -n -1 --stdout --subject-prefix= >patch &&
1245 grep ^Subject: patch >actual &&
1246 test_cmp expect actual
1249 test_expect_success '--rfc' '
1250 cat >expect <<-\EOF &&
1251 Subject: [RFC PATCH 1/1] header with . in it
1253 git format-patch -n -1 --stdout --rfc >patch &&
1254 grep ^Subject: patch >actual &&
1255 test_cmp expect actual
1258 test_expect_success '--from=ident notices bogus ident' '
1259 test_must_fail git format-patch -1 --stdout --from=foo >patch
1262 test_expect_success '--from=ident replaces author' '
1263 git format-patch -1 --stdout --from="Me <me@example.com>" >patch &&
1264 cat >expect <<-\EOF &&
1265 From: Me <me@example.com>
1267 From: A U Thor <author@example.com>
1270 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1271 test_cmp expect patch.head
1274 test_expect_success '--from uses committer ident' '
1275 git format-patch -1 --stdout --from >patch &&
1276 cat >expect <<-\EOF &&
1277 From: C O Mitter <committer@example.com>
1279 From: A U Thor <author@example.com>
1282 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1283 test_cmp expect patch.head
1286 test_expect_success '--from omits redundant in-body header' '
1287 git format-patch -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1288 cat >expect <<-\EOF &&
1289 From: A U Thor <author@example.com>
1292 sed -ne "/^From:/p; /^$/p; /^---$/q" patch >patch.head &&
1293 test_cmp expect patch.head
1296 test_expect_success 'in-body headers trigger content encoding' '
1297 test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
1298 test_when_finished "git reset --hard HEAD^" &&
1299 git format-patch -1 --stdout --from >patch &&
1300 cat >expect <<-\EOF &&
1301 From: C O Mitter <committer@example.com>
1302 Content-Type: text/plain; charset=UTF-8
1304 From: éxötìc <author@example.com>
1307 sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" patch >patch.head &&
1308 test_cmp expect patch.head
1313 C=$(git commit-tree HEAD^^{tree} -p HEAD) &&
1314 git format-patch --stdout --signoff $C^..$C >append_signoff.patch &&
1315 sed -n -e "1,/^---$/p" append_signoff.patch |
1316 egrep -n "^Subject|Sign|^$"
1319 test_expect_success 'signoff: commit with no body' '
1320 append_signoff </dev/null >actual &&
1321 cat <<-\EOF | sed "s/EOL$//" >expect &&
1322 4:Subject: [PATCH] EOL
1324 9:Signed-off-by: C O Mitter <committer@example.com>
1326 test_cmp expect actual
1329 test_expect_success 'signoff: commit with only subject' '
1330 echo subject | append_signoff >actual &&
1331 cat >expect <<-\EOF &&
1332 4:Subject: [PATCH] subject
1334 9:Signed-off-by: C O Mitter <committer@example.com>
1336 test_cmp expect actual
1339 test_expect_success 'signoff: commit with only subject that does not end with NL' '
1340 printf subject | append_signoff >actual &&
1341 cat >expect <<-\EOF &&
1342 4:Subject: [PATCH] subject
1344 9:Signed-off-by: C O Mitter <committer@example.com>
1346 test_cmp expect actual
1349 test_expect_success 'signoff: no existing signoffs' '
1350 append_signoff <<-\EOF >actual &&
1355 cat >expect <<-\EOF &&
1356 4:Subject: [PATCH] subject
1359 11:Signed-off-by: C O Mitter <committer@example.com>
1361 test_cmp expect actual
1364 test_expect_success 'signoff: no existing signoffs and no trailing NL' '
1365 printf "subject\n\nbody" | append_signoff >actual &&
1366 cat >expect <<-\EOF &&
1367 4:Subject: [PATCH] subject
1370 11:Signed-off-by: C O Mitter <committer@example.com>
1372 test_cmp expect actual
1375 test_expect_success 'signoff: some random signoff' '
1376 append_signoff <<-\EOF >actual &&
1381 Signed-off-by: my@house
1383 cat >expect <<-\EOF &&
1384 4:Subject: [PATCH] subject
1387 11:Signed-off-by: my@house
1388 12:Signed-off-by: C O Mitter <committer@example.com>
1390 test_cmp expect actual
1393 test_expect_success 'signoff: misc conforming footer elements' '
1394 append_signoff <<-\EOF >actual &&
1399 Signed-off-by: my@house
1400 (cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1401 Tested-by: Some One <someone@example.com>
1404 cat >expect <<-\EOF &&
1405 4:Subject: [PATCH] subject
1408 11:Signed-off-by: my@house
1409 15:Signed-off-by: C O Mitter <committer@example.com>
1411 test_cmp expect actual
1414 test_expect_success 'signoff: some random signoff-alike' '
1415 append_signoff <<-\EOF >actual &&
1419 Fooled-by-me: my@house
1421 cat >expect <<-\EOF &&
1422 4:Subject: [PATCH] subject
1425 12:Signed-off-by: C O Mitter <committer@example.com>
1427 test_cmp expect actual
1430 test_expect_success 'signoff: not really a signoff' '
1431 append_signoff <<-\EOF >actual &&
1434 I want to mention about Signed-off-by: here.
1436 cat >expect <<-\EOF &&
1437 4:Subject: [PATCH] subject
1439 9:I want to mention about Signed-off-by: here.
1441 11:Signed-off-by: C O Mitter <committer@example.com>
1443 test_cmp expect actual
1446 test_expect_success 'signoff: not really a signoff (2)' '
1447 append_signoff <<-\EOF >actual &&
1451 Signed-off-by: example happens to be wrapped here.
1453 cat >expect <<-\EOF &&
1454 4:Subject: [PATCH] subject
1456 10:Signed-off-by: example happens to be wrapped here.
1457 11:Signed-off-by: C O Mitter <committer@example.com>
1459 test_cmp expect actual
1462 test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
1463 append_signoff <<-\EOF >actual &&
1466 Signed-off-by: my@house
1467 Signed-off-by: your@house
1471 cat >expect <<-\EOF &&
1472 4:Subject: [PATCH] subject
1474 9:Signed-off-by: my@house
1475 10:Signed-off-by: your@house
1478 14:Signed-off-by: C O Mitter <committer@example.com>
1480 test_cmp expect actual
1483 test_expect_success 'signoff: the same signoff at the end' '
1484 append_signoff <<-\EOF >actual &&
1489 Signed-off-by: C O Mitter <committer@example.com>
1491 cat >expect <<-\EOF &&
1492 4:Subject: [PATCH] subject
1495 11:Signed-off-by: C O Mitter <committer@example.com>
1497 test_cmp expect actual
1500 test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
1501 printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
1502 append_signoff >actual &&
1503 cat >expect <<-\EOF &&
1504 4:Subject: [PATCH] subject
1506 9:Signed-off-by: C O Mitter <committer@example.com>
1508 test_cmp expect actual
1511 test_expect_success 'signoff: the same signoff NOT at the end' '
1512 append_signoff <<-\EOF >actual &&
1517 Signed-off-by: C O Mitter <committer@example.com>
1518 Signed-off-by: my@house
1520 cat >expect <<-\EOF &&
1521 4:Subject: [PATCH] subject
1524 11:Signed-off-by: C O Mitter <committer@example.com>
1525 12:Signed-off-by: my@house
1527 test_cmp expect actual
1530 test_expect_success 'signoff: tolerate garbage in conforming footer' '
1531 append_signoff <<-\EOF >actual &&
1538 Signed-off-by: C O Mitter <committer@example.com>
1540 cat >expect <<-\EOF &&
1541 4:Subject: [PATCH] subject
1544 13:Signed-off-by: C O Mitter <committer@example.com>
1546 test_cmp expect actual
1549 test_expect_success 'signoff: respect trailer config' '
1550 append_signoff <<-\EOF >actual &&
1556 cat >expect <<-\EOF &&
1557 4:Subject: [PATCH] subject
1560 12:Signed-off-by: C O Mitter <committer@example.com>
1562 test_cmp expect actual &&
1564 test_config trailer.Myfooter.ifexists add &&
1565 append_signoff <<-\EOF >actual &&
1571 cat >expect <<-\EOF &&
1572 4:Subject: [PATCH] subject
1574 11:Signed-off-by: C O Mitter <committer@example.com>
1576 test_cmp expect actual
1579 test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
1580 append_signoff <<-\EOF >actual &&
1587 Change-id: Ideadbeef
1588 Signed-off-by: C O Mitter <committer@example.com>
1591 cat >expect <<-\EOF &&
1592 4:Subject: [PATCH] subject
1595 14:Signed-off-by: C O Mitter <committer@example.com>
1597 test_cmp expect actual
1600 test_expect_success 'format patch ignores color.ui' '
1601 test_unconfig color.ui &&
1602 git format-patch --stdout -1 >expect &&
1603 test_config color.ui always &&
1604 git format-patch --stdout -1 >actual &&
1605 test_cmp expect actual
1608 test_expect_success 'format patch respects diff.relative' '
1611 echo other content >subdir/file2 &&
1612 git add subdir/file2 &&
1613 git commit -F msg &&
1614 test_unconfig diff.relative &&
1615 git format-patch --relative=subdir --stdout -1 >expect &&
1616 test_config diff.relative true &&
1617 git -C subdir format-patch --stdout -1 >actual &&
1618 test_cmp expect actual
1621 test_expect_success 'cover letter with invalid --cover-from-description and config' '
1622 test_config branch.rebuild-1.description "config subject
1625 test_must_fail git format-patch --cover-letter --cover-from-description garbage main &&
1626 test_config format.coverFromDescription garbage &&
1627 test_must_fail git format-patch --cover-letter main
1630 test_expect_success 'cover letter with format.coverFromDescription = default' '
1631 test_config branch.rebuild-1.description "config subject
1634 test_config format.coverFromDescription default &&
1635 git checkout rebuild-1 &&
1636 git format-patch --stdout --cover-letter main >actual &&
1637 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1638 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1639 grep "^config subject$" actual &&
1640 grep "^body$" actual
1643 test_expect_success 'cover letter with --cover-from-description default' '
1644 test_config branch.rebuild-1.description "config subject
1647 git checkout rebuild-1 &&
1648 git format-patch --stdout --cover-letter --cover-from-description default main >actual &&
1649 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1650 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1651 grep "^config subject$" actual &&
1652 grep "^body$" actual
1655 test_expect_success 'cover letter with format.coverFromDescription = none' '
1656 test_config branch.rebuild-1.description "config subject
1659 test_config format.coverFromDescription none &&
1660 git checkout rebuild-1 &&
1661 git format-patch --stdout --cover-letter main >actual &&
1662 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1663 grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1664 ! grep "^config subject$" actual &&
1665 ! grep "^body$" actual
1668 test_expect_success 'cover letter with --cover-from-description none' '
1669 test_config branch.rebuild-1.description "config subject
1672 git checkout rebuild-1 &&
1673 git format-patch --stdout --cover-letter --cover-from-description none main >actual &&
1674 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1675 grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1676 ! grep "^config subject$" actual &&
1677 ! grep "^body$" actual
1680 test_expect_success 'cover letter with format.coverFromDescription = message' '
1681 test_config branch.rebuild-1.description "config subject
1684 test_config format.coverFromDescription message &&
1685 git checkout rebuild-1 &&
1686 git format-patch --stdout --cover-letter main >actual &&
1687 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1688 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1689 grep "^config subject$" actual &&
1690 grep "^body$" actual
1693 test_expect_success 'cover letter with --cover-from-description message' '
1694 test_config branch.rebuild-1.description "config subject
1697 git checkout rebuild-1 &&
1698 git format-patch --stdout --cover-letter --cover-from-description message main >actual &&
1699 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1700 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1701 grep "^config subject$" actual &&
1702 grep "^body$" actual
1705 test_expect_success 'cover letter with format.coverFromDescription = subject' '
1706 test_config branch.rebuild-1.description "config subject
1709 test_config format.coverFromDescription subject &&
1710 git checkout rebuild-1 &&
1711 git format-patch --stdout --cover-letter main >actual &&
1712 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1713 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1714 ! grep "^config subject$" actual &&
1715 grep "^body$" actual
1718 test_expect_success 'cover letter with --cover-from-description subject' '
1719 test_config branch.rebuild-1.description "config subject
1722 git checkout rebuild-1 &&
1723 git format-patch --stdout --cover-letter --cover-from-description subject main >actual &&
1724 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1725 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1726 ! grep "^config subject$" actual &&
1727 grep "^body$" actual
1730 test_expect_success 'cover letter with format.coverFromDescription = auto (short subject line)' '
1731 test_config branch.rebuild-1.description "config subject
1734 test_config format.coverFromDescription auto &&
1735 git checkout rebuild-1 &&
1736 git format-patch --stdout --cover-letter main >actual &&
1737 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1738 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1739 ! grep "^config subject$" actual &&
1740 grep "^body$" actual
1743 test_expect_success 'cover letter with --cover-from-description auto (short subject line)' '
1744 test_config branch.rebuild-1.description "config subject
1747 git checkout rebuild-1 &&
1748 git format-patch --stdout --cover-letter --cover-from-description auto main >actual &&
1749 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1750 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1751 ! grep "^config subject$" actual &&
1752 grep "^body$" actual
1755 test_expect_success 'cover letter with format.coverFromDescription = auto (long subject line)' '
1756 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
1759 test_config format.coverFromDescription auto &&
1760 git checkout rebuild-1 &&
1761 git format-patch --stdout --cover-letter main >actual &&
1762 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1763 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1764 grep "^this is a really long first line and it is over 100 characters long which is the threshold for long subjects$" actual &&
1765 grep "^body$" actual
1768 test_expect_success 'cover letter with --cover-from-description auto (long subject line)' '
1769 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
1772 git checkout rebuild-1 &&
1773 git format-patch --stdout --cover-letter --cover-from-description auto main >actual &&
1774 grep "^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\*$" actual &&
1775 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1776 grep "^this is a really long first line and it is over 100 characters long which is the threshold for long subjects$" actual &&
1777 grep "^body$" actual
1780 test_expect_success 'cover letter with command-line --cover-from-description overrides config' '
1781 test_config branch.rebuild-1.description "config subject
1784 test_config format.coverFromDescription none &&
1785 git checkout rebuild-1 &&
1786 git format-patch --stdout --cover-letter --cover-from-description subject main >actual &&
1787 grep "^Subject: \[PATCH 0/2\] config subject$" actual &&
1788 ! grep "^\*\*\* BLURB HERE \*\*\*$" actual &&
1789 ! grep "^config subject$" actual &&
1790 grep "^body$" actual
1793 test_expect_success 'cover letter using branch description (1)' '
1794 git checkout rebuild-1 &&
1795 test_config branch.rebuild-1.description hello &&
1796 git format-patch --stdout --cover-letter main >actual &&
1800 test_expect_success 'cover letter using branch description (2)' '
1801 git checkout rebuild-1 &&
1802 test_config branch.rebuild-1.description hello &&
1803 git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
1807 test_expect_success 'cover letter using branch description (3)' '
1808 git checkout rebuild-1 &&
1809 test_config branch.rebuild-1.description hello &&
1810 git format-patch --stdout --cover-letter ^main rebuild-1 >actual &&
1814 test_expect_success 'cover letter using branch description (4)' '
1815 git checkout rebuild-1 &&
1816 test_config branch.rebuild-1.description hello &&
1817 git format-patch --stdout --cover-letter main.. >actual &&
1821 test_expect_success 'cover letter using branch description (5)' '
1822 git checkout rebuild-1 &&
1823 test_config branch.rebuild-1.description hello &&
1824 git format-patch --stdout --cover-letter -2 HEAD >actual &&
1828 test_expect_success 'cover letter using branch description (6)' '
1829 git checkout rebuild-1 &&
1830 test_config branch.rebuild-1.description hello &&
1831 git format-patch --stdout --cover-letter -2 >actual &&
1835 test_expect_success 'cover letter with nothing' '
1836 git format-patch --stdout --cover-letter >actual &&
1837 test_line_count = 0 actual
1840 test_expect_success 'cover letter auto' '
1842 test_when_finished "rm -rf tmp;
1843 git config --unset format.coverletter" &&
1845 git config format.coverletter auto &&
1846 git format-patch -o tmp -1 >list &&
1847 test_line_count = 1 list &&
1848 git format-patch -o tmp -2 >list &&
1849 test_line_count = 3 list
1852 test_expect_success 'cover letter auto user override' '
1854 test_when_finished "rm -rf tmp;
1855 git config --unset format.coverletter" &&
1857 git config format.coverletter auto &&
1858 git format-patch -o tmp --cover-letter -1 >list &&
1859 test_line_count = 2 list &&
1860 git format-patch -o tmp --cover-letter -2 >list &&
1861 test_line_count = 3 list &&
1862 git format-patch -o tmp --no-cover-letter -1 >list &&
1863 test_line_count = 1 list &&
1864 git format-patch -o tmp --no-cover-letter -2 >list &&
1865 test_line_count = 2 list
1868 test_expect_success 'format-patch --zero-commit' '
1869 git format-patch --zero-commit --stdout v2..v1 >patch2 &&
1870 grep "^From " patch2 | sort | uniq >actual &&
1871 echo "From $ZERO_OID Mon Sep 17 00:00:00 2001" >expect &&
1872 test_cmp expect actual
1875 test_expect_success 'From line has expected format' '
1876 git format-patch --stdout v2..v1 >patch2 &&
1877 grep "^From " patch2 >from &&
1878 grep "^From $OID_REGEX Mon Sep 17 00:00:00 2001$" patch2 >filtered &&
1879 test_cmp from filtered
1882 test_expect_success 'format-patch -o with no leading directories' '
1884 git format-patch -o patches main..side &&
1885 count=$(git rev-list --count main..side) &&
1887 test_line_count = $count list
1890 test_expect_success 'format-patch -o with leading existing directories' '
1891 rm -rf existing-dir &&
1892 mkdir existing-dir &&
1893 git format-patch -o existing-dir/patches main..side &&
1894 count=$(git rev-list --count main..side) &&
1895 ls existing-dir/patches >list &&
1896 test_line_count = $count list
1899 test_expect_success 'format-patch -o with leading non-existing directories' '
1900 rm -rf non-existing-dir &&
1901 git format-patch -o non-existing-dir/patches main..side &&
1902 count=$(git rev-list --count main..side) &&
1903 test_path_is_dir non-existing-dir &&
1904 ls non-existing-dir/patches >list &&
1905 test_line_count = $count list
1908 test_expect_success 'format-patch format.outputDirectory option' '
1909 test_config format.outputDirectory patches &&
1911 git format-patch main..side &&
1912 count=$(git rev-list --count main..side) &&
1914 test_line_count = $count list
1917 test_expect_success 'format-patch -o overrides format.outputDirectory' '
1918 test_config format.outputDirectory patches &&
1919 rm -fr patches patchset &&
1920 git format-patch main..side -o patchset &&
1921 test_path_is_missing patches &&
1922 test_path_is_dir patchset
1925 test_expect_success 'format-patch forbids multiple outputs' '
1926 rm -fr outfile outdir &&
1928 git format-patch --stdout --output-directory=outdir &&
1930 git format-patch --stdout --output=outfile &&
1932 git format-patch --output=outfile --output-directory=outdir
1935 test_expect_success 'configured outdir does not conflict with output options' '
1936 rm -fr outfile outdir &&
1937 test_config format.outputDirectory outdir &&
1938 git format-patch --stdout &&
1939 test_path_is_missing outdir &&
1940 git format-patch --output=outfile &&
1941 test_path_is_missing outdir
1944 test_expect_success 'format-patch --output' '
1946 git format-patch -3 --stdout HEAD >expect &&
1947 git format-patch -3 --output=outfile HEAD &&
1948 test_cmp expect outfile
1951 test_expect_success 'format-patch --cover-letter --output' '
1953 git format-patch --cover-letter -3 --stdout HEAD >expect &&
1954 git format-patch --cover-letter -3 --output=outfile HEAD &&
1955 test_cmp expect outfile
1958 test_expect_success 'format-patch --base' '
1959 git checkout patchid &&
1961 git format-patch --stdout --base=HEAD~3 -1 >patch &&
1962 tail -n 7 patch >actual1 &&
1964 git format-patch --stdout --base=HEAD~3 HEAD~.. >patch &&
1965 tail -n 7 patch >actual2 &&
1968 git rev-parse HEAD~3 >commit-id-base &&
1969 echo "base-commit: $(cat commit-id-base)" >>expect &&
1971 git show --patch HEAD~2 >patch &&
1972 git patch-id --stable <patch >patch.id.raw &&
1973 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>expect &&
1975 git show --patch HEAD~1 >patch &&
1976 git patch-id --stable <patch >patch.id.raw &&
1977 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>expect &&
1979 signature >>expect &&
1980 test_cmp expect actual1 &&
1981 test_cmp expect actual2 &&
1984 echo "base-commit: $(cat commit-id-base)" >>fail &&
1986 git show --patch HEAD~2 >patch &&
1987 git patch-id --unstable <patch >patch.id.raw &&
1988 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>fail &&
1990 git show --patch HEAD~1 >patch &&
1991 git patch-id --unstable <patch >patch.id.raw &&
1992 awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>fail &&
1995 ! test_cmp fail actual1 &&
1996 ! test_cmp fail actual2
1999 test_expect_success 'format-patch --base errors out when base commit is in revision list' '
2000 test_must_fail git format-patch --base=HEAD -2 &&
2001 test_must_fail git format-patch --base=HEAD~1 -2 &&
2002 git format-patch --stdout --base=HEAD~2 -2 >patch &&
2003 grep "^base-commit:" patch >actual &&
2004 git rev-parse HEAD~2 >commit-id-base &&
2005 echo "base-commit: $(cat commit-id-base)" >expect &&
2006 test_cmp expect actual
2009 test_expect_success 'format-patch --base errors out when base commit is not ancestor of revision list' '
2010 # For history as below:
2012 # ---Q---P---Z---Y---*---X
2016 # If "format-patch Z..X" is given, P and Z can not be specified as the base commit
2017 git checkout -b topic1 main &&
2018 git rev-parse HEAD >commit-id-base &&
2020 git rev-parse HEAD >commit-id-P &&
2022 git rev-parse HEAD >commit-id-Z &&
2024 git checkout -b topic2 main &&
2028 test_must_fail git format-patch --base=$(cat commit-id-P) -3 &&
2029 test_must_fail git format-patch --base=$(cat commit-id-Z) -3 &&
2030 git format-patch --stdout --base=$(cat commit-id-base) -3 >patch &&
2031 grep "^base-commit:" patch >actual &&
2032 echo "base-commit: $(cat commit-id-base)" >expect &&
2033 test_cmp expect actual
2036 test_expect_success 'format-patch --base=auto' '
2037 git checkout -b upstream main &&
2038 git checkout -b local upstream &&
2039 git branch --set-upstream-to=upstream &&
2042 git format-patch --stdout --base=auto -2 >patch &&
2043 grep "^base-commit:" patch >actual &&
2044 git rev-parse upstream >commit-id-base &&
2045 echo "base-commit: $(cat commit-id-base)" >expect &&
2046 test_cmp expect actual
2049 test_expect_success 'format-patch errors out when history involves criss-cross' '
2050 # setup criss-cross history
2058 git checkout main &&
2060 git checkout -b xb main &&
2062 git checkout -b xc main &&
2064 git checkout -b xbc xb -- &&
2066 git checkout -b xcb xc -- &&
2067 git branch --set-upstream-to=xbc &&
2073 test_must_fail git format-patch --base=auto -1
2076 test_expect_success 'format-patch format.useAutoBase whenAble history involves criss-cross' '
2077 test_config format.useAutoBase whenAble &&
2078 git format-patch -1 >patch &&
2079 ! grep "^base-commit:" patch
2082 test_expect_success 'format-patch format.useAutoBase option' '
2083 git checkout local &&
2084 test_config format.useAutoBase true &&
2085 git format-patch --stdout -1 >patch &&
2086 grep "^base-commit:" patch >actual &&
2087 git rev-parse upstream >commit-id-base &&
2088 echo "base-commit: $(cat commit-id-base)" >expect &&
2089 test_cmp expect actual
2092 test_expect_success 'format-patch format.useAutoBase option with whenAble' '
2093 git checkout local &&
2094 test_config format.useAutoBase whenAble &&
2095 git format-patch --stdout -1 >patch &&
2096 grep "^base-commit:" patch >actual &&
2097 git rev-parse upstream >commit-id-base &&
2098 echo "base-commit: $(cat commit-id-base)" >expect &&
2099 test_cmp expect actual
2102 test_expect_success 'format-patch --base overrides format.useAutoBase' '
2103 test_config format.useAutoBase true &&
2104 git format-patch --stdout --base=HEAD~1 -1 >patch &&
2105 grep "^base-commit:" patch >actual &&
2106 git rev-parse HEAD~1 >commit-id-base &&
2107 echo "base-commit: $(cat commit-id-base)" >expect &&
2108 test_cmp expect actual
2111 test_expect_success 'format-patch --no-base overrides format.useAutoBase' '
2112 test_config format.useAutoBase true &&
2113 git format-patch --stdout --no-base -1 >patch &&
2114 ! grep "^base-commit:" patch
2117 test_expect_success 'format-patch --no-base overrides format.useAutoBase whenAble' '
2118 test_config format.useAutoBase whenAble &&
2119 git format-patch --stdout --no-base -1 >patch &&
2120 ! grep "^base-commit:" patch
2123 test_expect_success 'format-patch --base with --attach' '
2124 git format-patch --attach=mimemime --stdout --base=HEAD~ -1 >patch &&
2125 sed -n -e "/^base-commit:/s/.*/1/p" -e "/^---*mimemime--$/s/.*/2/p" \
2127 test_write_lines 1 2 >expect &&
2128 test_cmp expect actual
2130 test_expect_success 'format-patch --attach cover-letter only is non-multipart' '
2131 test_when_finished "rm -fr patches" &&
2132 git format-patch -o patches --cover-letter --attach=mimemime --base=HEAD~ -1 &&
2133 ! egrep "^--+mimemime" patches/0000*.patch &&
2134 egrep "^--+mimemime$" patches/0001*.patch >output &&
2135 test_line_count = 2 output &&
2136 egrep "^--+mimemime--$" patches/0001*.patch >output &&
2137 test_line_count = 1 output
2140 test_expect_success 'format-patch --pretty=mboxrd' '
2142 cat >msg <<-INPUT_END &&
2143 mboxrd should escape the body
2145 From could trip up a loose mbox parser
2146 >From extra escape for reversibility
2147 >>From extra escape for reversibility 2
2148 from lower case not escaped
2149 Fromm bad speling not escaped
2150 From with leading space not escaped
2159 cat >expect <<-INPUT_END &&
2160 >From could trip up a loose mbox parser
2161 >>From extra escape for reversibility
2162 >>>From extra escape for reversibility 2
2163 from lower case not escaped
2164 Fromm bad speling not escaped
2165 From with leading space not escaped
2174 C=$(git commit-tree HEAD^^{tree} -p HEAD <msg) &&
2175 git format-patch --pretty=mboxrd --stdout -1 $C~1..$C >patch &&
2176 git grep -h --no-index -A11 \
2177 "^>From could trip up a loose mbox parser" patch >actual &&
2178 test_cmp expect actual
2181 test_expect_success 'interdiff: setup' '
2182 git checkout -b boop main &&
2183 test_commit fnorp blorp &&
2184 test_commit fleep blorp
2187 test_expect_success 'interdiff: cover-letter' '
2188 sed "y/q/ /" >expect <<-\EOF &&
2192 git format-patch --cover-letter --interdiff=boop~2 -1 boop &&
2193 test_i18ngrep "^Interdiff:$" 0000-cover-letter.patch &&
2194 test_i18ngrep ! "^Interdiff:$" 0001-fleep.patch &&
2195 sed "1,/^@@ /d; /^-- $/q" 0000-cover-letter.patch >actual &&
2196 test_cmp expect actual
2199 test_expect_success 'interdiff: reroll-count' '
2200 git format-patch --cover-letter --interdiff=boop~2 -v2 -1 boop &&
2201 test_i18ngrep "^Interdiff ..* v1:$" v2-0000-cover-letter.patch
2204 test_expect_success 'interdiff: solo-patch' '
2205 cat >expect <<-\EOF &&
2209 git format-patch --interdiff=boop~2 -1 boop &&
2210 test_i18ngrep "^Interdiff:$" 0001-fleep.patch &&
2211 sed "1,/^ @@ /d; /^$/q" 0001-fleep.patch >actual &&
2212 test_cmp expect actual