3 # Copyright (c) 2006 Junio C Hamano
6 test_description='various format-patch tests'
9 . "$TEST_DIRECTORY"/lib-terminal.sh
11 test_expect_success setup '
13 for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i"; done >file &&
17 git commit -m Initial &&
18 git checkout -b side &&
20 for i in 1 2 5 6 A B C 7 8 9 10; do echo "$i"; done >file &&
23 git commit -m "Side changes #1" &&
25 for i in D E F; do echo "$i"; done >>file &&
26 git update-index file &&
28 git commit -m "Side changes #2" &&
31 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file &&
32 git update-index file &&
34 git commit -m "Side changes #3 with \\n backslash-n in it." &&
36 git checkout master &&
37 git diff-tree -p C2 | git apply --index &&
39 git commit -m "Master accepts moral equivalent of #2"
43 test_expect_success "format-patch --ignore-if-in-upstream" '
45 git format-patch --stdout master..side >patch0 &&
46 cnt=`grep "^From " patch0 | wc -l` &&
51 test_expect_success "format-patch --ignore-if-in-upstream" '
53 git format-patch --stdout \
54 --ignore-if-in-upstream master..side >patch1 &&
55 cnt=`grep "^From " patch1 | wc -l` &&
60 test_expect_success "format-patch doesn't consider merge commits" '
62 git checkout -b slave master &&
63 echo "Another line" >>file &&
65 git commit -am "Slave change #1" &&
66 echo "Yet another line" >>file &&
68 git commit -am "Slave change #2" &&
69 git checkout -b merger master &&
71 git merge --no-ff slave &&
72 cnt=`git format-patch -3 --stdout | grep "^From " | wc -l` &&
76 test_expect_success "format-patch result applies" '
78 git checkout -b rebuild-0 master &&
80 cnt=`git rev-list master.. | wc -l` &&
84 test_expect_success "format-patch --ignore-if-in-upstream result applies" '
86 git checkout -b rebuild-1 master &&
88 cnt=`git rev-list master.. | wc -l` &&
92 test_expect_success 'commit did not screw up the log message' '
94 git cat-file commit side | grep "^Side .* with .* backslash-n"
98 test_expect_success 'format-patch did not screw up the log message' '
100 grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
101 grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
105 test_expect_success 'replay did not screw up the log message' '
107 git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
111 test_expect_success 'extra headers' '
113 git config format.headers "To: R E Cipient <rcipient@example.com>
115 git config --add format.headers "Cc: S E Cipient <scipient@example.com>
117 git format-patch --stdout master..side > patch2 &&
118 sed -e "/^\$/q" patch2 > hdrs2 &&
119 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs2 &&
120 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs2
124 test_expect_success 'extra headers without newlines' '
126 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
127 git config --add format.headers "Cc: S E Cipient <scipient@example.com>" &&
128 git format-patch --stdout master..side >patch3 &&
129 sed -e "/^\$/q" patch3 > hdrs3 &&
130 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs3 &&
131 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs3
135 test_expect_success 'extra headers with multiple To:s' '
137 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
138 git config --add format.headers "To: S E Cipient <scipient@example.com>" &&
139 git format-patch --stdout master..side > patch4 &&
140 sed -e "/^\$/q" patch4 > hdrs4 &&
141 grep "^To: R E Cipient <rcipient@example.com>,\$" hdrs4 &&
142 grep "^ *S E Cipient <scipient@example.com>\$" hdrs4
145 test_expect_success 'additional command line cc (ascii)' '
147 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
148 git format-patch --cc="S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
149 grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
150 grep "^ *S E Cipient <scipient@example.com>\$" patch5
153 test_expect_failure 'additional command line cc (rfc822)' '
155 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
156 git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
157 grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
158 grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" patch5
161 test_expect_success 'command line headers' '
163 git config --unset-all format.headers &&
164 git format-patch --add-header="Cc: R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 &&
165 grep "^Cc: R E Cipient <rcipient@example.com>\$" patch6
168 test_expect_success 'configuration headers and command line headers' '
170 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
171 git format-patch --add-header="Cc: S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 &&
172 grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch7 &&
173 grep "^ *S E Cipient <scipient@example.com>\$" patch7
176 test_expect_success 'command line To: header (ascii)' '
178 git config --unset-all format.headers &&
179 git format-patch --to="R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
180 grep "^To: R E Cipient <rcipient@example.com>\$" patch8
183 test_expect_failure 'command line To: header (rfc822)' '
185 git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
186 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch8
189 test_expect_failure 'command line To: header (rfc2047)' '
191 git format-patch --to="R Ä Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
192 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch8
195 test_expect_success 'configuration To: header (ascii)' '
197 git config format.to "R E Cipient <rcipient@example.com>" &&
198 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
199 grep "^To: R E Cipient <rcipient@example.com>\$" patch9
202 test_expect_failure 'configuration To: header (rfc822)' '
204 git config format.to "R. E. Cipient <rcipient@example.com>" &&
205 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
206 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch9
209 test_expect_failure 'configuration To: header (rfc2047)' '
211 git config format.to "R Ä Cipient <rcipient@example.com>" &&
212 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
213 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch9
216 # check_patch <patch>: Verify that <patch> looks like a half-sane
217 # patch email to avoid a false positive with !grep
219 grep -e "^From:" "$1" &&
220 grep -e "^Date:" "$1" &&
221 grep -e "^Subject:" "$1"
224 test_expect_success '--no-to overrides config.to' '
226 git config --replace-all format.to \
227 "R E Cipient <rcipient@example.com>" &&
228 git format-patch --no-to --stdout master..side |
229 sed -e "/^\$/q" >patch10 &&
230 check_patch patch10 &&
231 ! grep "^To: R E Cipient <rcipient@example.com>\$" patch10
234 test_expect_success '--no-to and --to replaces config.to' '
236 git config --replace-all format.to \
237 "Someone <someone@out.there>" &&
238 git format-patch --no-to --to="Someone Else <else@out.there>" \
239 --stdout master..side |
240 sed -e "/^\$/q" >patch11 &&
241 check_patch patch11 &&
242 ! grep "^To: Someone <someone@out.there>\$" patch11 &&
243 grep "^To: Someone Else <else@out.there>\$" patch11
246 test_expect_success '--no-cc overrides config.cc' '
248 git config --replace-all format.cc \
249 "C E Cipient <rcipient@example.com>" &&
250 git format-patch --no-cc --stdout master..side |
251 sed -e "/^\$/q" >patch12 &&
252 check_patch patch12 &&
253 ! grep "^Cc: C E Cipient <rcipient@example.com>\$" patch12
256 test_expect_success '--no-add-header overrides config.headers' '
258 git config --replace-all format.headers \
259 "Header1: B E Cipient <rcipient@example.com>" &&
260 git format-patch --no-add-header --stdout master..side |
261 sed -e "/^\$/q" >patch13 &&
262 check_patch patch13 &&
263 ! grep "^Header1: B E Cipient <rcipient@example.com>\$" patch13
266 test_expect_success 'multiple files' '
270 git format-patch -o patches/ master &&
271 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
274 test_expect_success 'reroll count' '
276 git format-patch -o patches --cover-letter --reroll-count 4 master..side >list &&
277 ! grep -v "^patches/v4-000[0-3]-" list &&
278 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
279 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
282 test_expect_success 'reroll count (-v)' '
284 git format-patch -o patches --cover-letter -v4 master..side >list &&
285 ! grep -v "^patches/v4-000[0-3]-" list &&
286 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
287 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
293 (git format-patch --stdout "$@"; echo $? > status.out) |
294 # Prints everything between the Message-ID and In-Reply-To,
295 # and replaces all Message-ID-lookalikes by a sequence number
297 if (/^(message-id|references|in-reply-to)/i) {
303 $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
304 for $k (keys %h) {s/$k/$h{$k}/};
307 print "---\n" if /^From /i;
309 test 0 = "$(cat status.out)" &&
310 test_cmp "$expect" actual
313 cat >> expect.no-threading <<EOF
319 test_expect_success 'no threading' '
321 check_threading expect.no-threading master
324 cat > expect.thread <<EOF
337 test_expect_success 'thread' '
338 check_threading expect.thread --thread master
341 cat > expect.in-reply-to <<EOF
356 test_expect_success 'thread in-reply-to' '
357 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
361 cat > expect.cover-letter <<EOF
378 test_expect_success 'thread cover-letter' '
379 check_threading expect.cover-letter --cover-letter --thread master
382 cat > expect.cl-irt <<EOF
404 test_expect_success 'thread cover-letter in-reply-to' '
405 check_threading expect.cl-irt --cover-letter \
406 --in-reply-to="<test.message>" --thread master
409 test_expect_success 'thread explicit shallow' '
410 check_threading expect.cl-irt --cover-letter \
411 --in-reply-to="<test.message>" --thread=shallow master
414 cat > expect.deep <<EOF
428 test_expect_success 'thread deep' '
429 check_threading expect.deep --thread=deep master
432 cat > expect.deep-irt <<EOF
450 test_expect_success 'thread deep in-reply-to' '
451 check_threading expect.deep-irt --thread=deep \
452 --in-reply-to="<test.message>" master
455 cat > expect.deep-cl <<EOF
475 test_expect_success 'thread deep cover-letter' '
476 check_threading expect.deep-cl --cover-letter --thread=deep master
479 cat > expect.deep-cl-irt <<EOF
504 test_expect_success 'thread deep cover-letter in-reply-to' '
505 check_threading expect.deep-cl-irt --cover-letter \
506 --in-reply-to="<test.message>" --thread=deep master
509 test_expect_success 'thread via config' '
510 test_config format.thread true &&
511 check_threading expect.thread master
514 test_expect_success 'thread deep via config' '
515 test_config format.thread deep &&
516 check_threading expect.deep master
519 test_expect_success 'thread config + override' '
520 test_config format.thread deep &&
521 check_threading expect.thread --thread master
524 test_expect_success 'thread config + --no-thread' '
525 test_config format.thread deep &&
526 check_threading expect.no-threading --no-thread master
529 test_expect_success 'excessive subject' '
533 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
534 git update-index file &&
535 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." &&
536 git format-patch -o patches/ master..side &&
537 ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
540 test_expect_success 'cover-letter inherits diff options' '
544 git format-patch --cover-letter -1 &&
545 check_patch 0000-cover-letter.patch &&
546 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
547 git format-patch --cover-letter -1 -M &&
548 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
553 This is an excessively long subject line for a message due to the
554 habit some projects have of not having a short, one-line subject at
555 the start of the commit message, but rather sticking a whole
556 paragraph right at the start as the only thing in the commit
557 message. It had better not become the filename for the patch.
562 test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
564 git format-patch --cover-letter -2 &&
565 sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
566 test_cmp expect output
571 index 40f36c6..2dc5c23 100644
582 test_expect_success 'format-patch respects -U' '
584 git format-patch -U4 -2 &&
585 sed -e "1,/^diff/d" -e "/^+5/q" \
586 <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
588 test_cmp expect output
594 diff --git a/file b/file
595 index 40f36c6..2dc5c23 100644
605 test_expect_success 'format-patch -p suppresses stat' '
607 git format-patch -p -2 &&
608 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
609 test_cmp expect output
613 test_expect_success 'format-patch from a subdirectory (1)' '
624 echo "Oops? $filename"
631 test_expect_success 'format-patch from a subdirectory (2)' '
636 git format-patch -1 -o ..
642 echo "Oops? $filename"
646 basename=$(expr "$filename" : ".*/\(.*\)") &&
647 test -f "sub/$basename"
650 test_expect_success 'format-patch from a subdirectory (3)' '
656 git format-patch -1 -o "$TRASH_DIRECTORY"
658 basename=$(expr "$filename" : ".*/\(.*\)") &&
662 test_expect_success 'format-patch --in-reply-to' '
663 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
664 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
665 grep "^References: <baz@foo.bar>" patch8
668 test_expect_success 'format-patch --signoff' '
669 git format-patch -1 --signoff --stdout >out &&
670 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
673 test_expect_success 'format-patch --notes --signoff' '
674 git notes --ref test add -m "test message" HEAD &&
675 git format-patch -1 --signoff --stdout --notes=test >out &&
676 # Three dashes must come after S-o-b
677 ! sed "/^Signed-off-by: /q" out | grep "test message" &&
678 sed "1,/^Signed-off-by: /d" out | grep "test message" &&
679 # Notes message must come after three dashes
680 ! sed "/^---$/q" out | grep "test message" &&
681 sed "1,/^---$/d" out | grep "test message"
684 echo "fatal: --name-only does not make sense" > expect.name-only
685 echo "fatal: --name-status does not make sense" > expect.name-status
686 echo "fatal: --check does not make sense" > expect.check
688 test_expect_success 'options no longer allowed for format-patch' '
689 test_must_fail git format-patch --name-only 2> output &&
690 test_i18ncmp expect.name-only output &&
691 test_must_fail git format-patch --name-status 2> output &&
692 test_i18ncmp expect.name-status output &&
693 test_must_fail git format-patch --check 2> output &&
694 test_i18ncmp expect.check output'
696 test_expect_success 'format-patch --numstat should produce a patch' '
697 git format-patch --numstat --stdout master..side > output &&
698 test 6 = $(grep "^diff --git a/" output | wc -l)'
700 test_expect_success 'format-patch -- <path>' '
701 git format-patch master..side -- file 2>error &&
702 ! grep "Use .--" error
705 test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
706 git format-patch --ignore-if-in-upstream HEAD
709 test_expect_success 'format-patch --signature' '
710 git format-patch --stdout --signature="my sig" -1 >output &&
714 test_expect_success 'format-patch with format.signature config' '
715 git config format.signature "config sig" &&
716 git format-patch --stdout -1 >output &&
717 grep "config sig" output
720 test_expect_success 'format-patch --signature overrides format.signature' '
721 git config format.signature "config sig" &&
722 git format-patch --stdout --signature="overrides" -1 >output &&
723 ! grep "config sig" output &&
724 grep "overrides" output
727 test_expect_success 'format-patch --no-signature ignores format.signature' '
728 git config format.signature "config sig" &&
729 git format-patch --stdout --signature="my sig" --no-signature \
731 check_patch output &&
732 ! grep "config sig" output &&
733 ! grep "my sig" output &&
734 ! grep "^-- \$" output
737 test_expect_success 'format-patch --signature --cover-letter' '
738 git config --unset-all format.signature &&
739 git format-patch --stdout --signature="my sig" --cover-letter \
741 grep "my sig" output &&
742 test 2 = $(grep "my sig" output | wc -l)
745 test_expect_success 'format.signature="" suppresses signatures' '
746 git config format.signature "" &&
747 git format-patch --stdout -1 >output &&
748 check_patch output &&
749 ! grep "^-- \$" output
752 test_expect_success 'format-patch --no-signature suppresses signatures' '
753 git config --unset-all format.signature &&
754 git format-patch --stdout --no-signature -1 >output &&
755 check_patch output &&
756 ! grep "^-- \$" output
759 test_expect_success 'format-patch --signature="" suppresses signatures' '
760 git format-patch --stdout --signature="" -1 >output &&
761 check_patch output &&
762 ! grep "^-- \$" output
765 test_expect_success TTY 'format-patch --stdout paginates' '
768 GIT_PAGER="wc >pager_used" &&
770 test_terminal git format-patch --stdout --all
772 test_path_is_file pager_used
775 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
778 GIT_PAGER="wc >pager_used" &&
780 test_terminal git --no-pager format-patch --stdout --all &&
781 test_terminal git -c "pager.format-patch=false" format-patch --stdout --all
783 test_path_is_missing pager_used &&
784 test_path_is_missing .git/pager_used
787 test_expect_success 'format-patch handles multi-line subjects' '
789 echo content >>file &&
790 for i in one two three; do echo $i; done >msg &&
793 git format-patch -o patches -1 &&
794 grep ^Subject: patches/0001-one.patch >actual &&
795 echo "Subject: [PATCH] one two three" >expect &&
796 test_cmp expect actual
799 test_expect_success 'format-patch handles multi-line encoded subjects' '
801 echo content >>file &&
802 for i in en två tre; do echo $i; done >msg &&
805 git format-patch -o patches -1 &&
806 grep ^Subject: patches/0001-en.patch >actual &&
807 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
808 test_cmp expect actual
812 M64=$M8$M8$M8$M8$M8$M8$M8$M8
813 M512=$M64$M64$M64$M64$M64$M64$M64$M64
815 Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
816 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
817 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
818 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
819 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
820 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
821 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
823 test_expect_success 'format-patch wraps extremely long subject (ascii)' '
824 echo content >>file &&
826 git commit -m "$M512" &&
827 git format-patch --stdout -1 >patch &&
828 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
829 test_cmp expect subject
833 M64=$M8$M8$M8$M8$M8$M8$M8$M8
834 M512=$M64$M64$M64$M64$M64$M64$M64$M64
836 Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
837 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
838 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
839 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
840 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
841 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
842 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
843 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
844 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
845 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
846 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
847 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
848 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
849 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
850 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
851 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
852 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
853 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
854 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
855 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
856 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
857 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
858 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
861 test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
863 echo content >>file &&
865 git commit -m "$M512" &&
866 git format-patch --stdout -1 >patch &&
867 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
868 test_cmp expect subject
872 echo content >>file &&
874 GIT_AUTHOR_NAME=$1 git commit -m author-check &&
875 git format-patch --stdout -1 >patch &&
876 sed -n "/^From: /p; /^ /p; /^$/q" <patch >actual &&
877 test_cmp expect actual
881 From: "Foo B. Bar" <author@example.com>
883 test_expect_success 'format-patch quotes dot in from-headers' '
884 check_author "Foo B. Bar"
888 From: "Foo \"The Baz\" Bar" <author@example.com>
890 test_expect_success 'format-patch quotes double-quote in from-headers' '
891 check_author "Foo \"The Baz\" Bar"
895 From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
897 test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
898 check_author "Föo Bar"
902 From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
904 test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
905 check_author "Föo B. Bar"
909 From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
912 test_expect_success 'format-patch wraps moderately long from-header (ascii)' '
913 check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
917 From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
918 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
919 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
921 test_expect_success 'format-patch wraps extremely long from-header (ascii)' '
922 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"
926 From: "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
927 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
928 Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
930 test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
931 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"
935 From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
936 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
937 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
938 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
939 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
941 test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
942 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"
946 Subject: header with . in it
948 test_expect_success 'subject lines do not have 822 atom-quoting' '
949 echo content >>file &&
951 git commit -m "header with . in it" &&
952 git format-patch -k -1 --stdout >patch &&
953 grep ^Subject: patch >actual &&
954 test_cmp expect actual
958 Subject: [PREFIX 1/1] header with . in it
960 test_expect_success 'subject prefixes have space prepended' '
961 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
962 grep ^Subject: patch >actual &&
963 test_cmp expect actual
967 Subject: [1/1] header with . in it
969 test_expect_success 'empty subject prefix does not have extra space' '
970 git format-patch -n -1 --stdout --subject-prefix= >patch &&
971 grep ^Subject: patch >actual &&
972 test_cmp expect actual
975 test_expect_success '--from=ident notices bogus ident' '
976 test_must_fail git format-patch -1 --stdout --from=foo >patch
979 test_expect_success '--from=ident replaces author' '
980 git format-patch -1 --stdout --from="Me <me@example.com>" >patch &&
981 cat >expect <<-\EOF &&
982 From: Me <me@example.com>
984 From: A U Thor <author@example.com>
987 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
988 test_cmp expect patch.head
991 test_expect_success '--from uses committer ident' '
992 git format-patch -1 --stdout --from >patch &&
993 cat >expect <<-\EOF &&
994 From: C O Mitter <committer@example.com>
996 From: A U Thor <author@example.com>
999 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1000 test_cmp expect patch.head
1003 test_expect_success 'in-body headers trigger content encoding' '
1004 GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
1005 test_when_finished "git reset --hard HEAD^" &&
1006 git format-patch -1 --stdout --from >patch &&
1007 cat >expect <<-\EOF &&
1008 From: C O Mitter <committer@example.com>
1009 Content-Type: text/plain; charset=UTF-8
1011 From: éxötìc <author@example.com>
1014 sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" <patch >patch.head &&
1015 test_cmp expect patch.head
1020 C=$(git commit-tree HEAD^^{tree} -p HEAD) &&
1021 git format-patch --stdout --signoff $C^..$C >append_signoff.patch &&
1022 sed -n -e "1,/^---$/p" append_signoff.patch |
1023 egrep -n "^Subject|Sign|^$"
1026 test_expect_success 'signoff: commit with no body' '
1027 append_signoff </dev/null >actual &&
1028 cat <<\EOF | sed "s/EOL$//" >expected &&
1029 4:Subject: [PATCH] EOL
1031 9:Signed-off-by: C O Mitter <committer@example.com>
1033 test_cmp expected actual
1036 test_expect_success 'signoff: commit with only subject' '
1037 echo subject | append_signoff >actual &&
1038 cat >expected <<\EOF &&
1039 4:Subject: [PATCH] subject
1041 9:Signed-off-by: C O Mitter <committer@example.com>
1043 test_cmp expected actual
1046 test_expect_success 'signoff: commit with only subject that does not end with NL' '
1047 printf subject | append_signoff >actual &&
1048 cat >expected <<\EOF &&
1049 4:Subject: [PATCH] subject
1051 9:Signed-off-by: C O Mitter <committer@example.com>
1053 test_cmp expected actual
1056 test_expect_success 'signoff: no existing signoffs' '
1057 append_signoff <<\EOF >actual &&
1062 cat >expected <<\EOF &&
1063 4:Subject: [PATCH] subject
1066 11:Signed-off-by: C O Mitter <committer@example.com>
1068 test_cmp expected actual
1071 test_expect_success 'signoff: no existing signoffs and no trailing NL' '
1072 printf "subject\n\nbody" | append_signoff >actual &&
1073 cat >expected <<\EOF &&
1074 4:Subject: [PATCH] subject
1077 11:Signed-off-by: C O Mitter <committer@example.com>
1079 test_cmp expected actual
1082 test_expect_success 'signoff: some random signoff' '
1083 append_signoff <<\EOF >actual &&
1088 Signed-off-by: my@house
1090 cat >expected <<\EOF &&
1091 4:Subject: [PATCH] subject
1094 11:Signed-off-by: my@house
1095 12:Signed-off-by: C O Mitter <committer@example.com>
1097 test_cmp expected actual
1100 test_expect_success 'signoff: misc conforming footer elements' '
1101 append_signoff <<\EOF >actual &&
1106 Signed-off-by: my@house
1107 (cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1108 Tested-by: Some One <someone@example.com>
1111 cat >expected <<\EOF &&
1112 4:Subject: [PATCH] subject
1115 11:Signed-off-by: my@house
1116 15:Signed-off-by: C O Mitter <committer@example.com>
1118 test_cmp expected actual
1121 test_expect_success 'signoff: some random signoff-alike' '
1122 append_signoff <<\EOF >actual &&
1126 Fooled-by-me: my@house
1128 cat >expected <<\EOF &&
1129 4:Subject: [PATCH] subject
1132 12:Signed-off-by: C O Mitter <committer@example.com>
1134 test_cmp expected actual
1137 test_expect_success 'signoff: not really a signoff' '
1138 append_signoff <<\EOF >actual &&
1141 I want to mention about Signed-off-by: here.
1143 cat >expected <<\EOF &&
1144 4:Subject: [PATCH] subject
1146 9:I want to mention about Signed-off-by: here.
1148 11:Signed-off-by: C O Mitter <committer@example.com>
1150 test_cmp expected actual
1153 test_expect_success 'signoff: not really a signoff (2)' '
1154 append_signoff <<\EOF >actual &&
1158 Signed-off-by: example happens to be wrapped here.
1160 cat >expected <<\EOF &&
1161 4:Subject: [PATCH] subject
1163 10:Signed-off-by: example happens to be wrapped here.
1165 12:Signed-off-by: C O Mitter <committer@example.com>
1167 test_cmp expected actual
1170 test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
1171 append_signoff <<\EOF >actual &&
1174 Signed-off-by: my@house
1175 Signed-off-by: your@house
1179 cat >expected <<\EOF &&
1180 4:Subject: [PATCH] subject
1182 9:Signed-off-by: my@house
1183 10:Signed-off-by: your@house
1186 14:Signed-off-by: C O Mitter <committer@example.com>
1188 test_cmp expected actual
1191 test_expect_success 'signoff: the same signoff at the end' '
1192 append_signoff <<\EOF >actual &&
1197 Signed-off-by: C O Mitter <committer@example.com>
1199 cat >expected <<\EOF &&
1200 4:Subject: [PATCH] subject
1203 11:Signed-off-by: C O Mitter <committer@example.com>
1205 test_cmp expected actual
1208 test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
1209 printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
1210 append_signoff >actual &&
1211 cat >expected <<\EOF &&
1212 4:Subject: [PATCH] subject
1214 9:Signed-off-by: C O Mitter <committer@example.com>
1216 test_cmp expected actual
1219 test_expect_success 'signoff: the same signoff NOT at the end' '
1220 append_signoff <<\EOF >actual &&
1225 Signed-off-by: C O Mitter <committer@example.com>
1226 Signed-off-by: my@house
1228 cat >expected <<\EOF &&
1229 4:Subject: [PATCH] subject
1232 11:Signed-off-by: C O Mitter <committer@example.com>
1233 12:Signed-off-by: my@house
1235 test_cmp expected actual
1238 test_expect_success 'signoff: detect garbage in non-conforming footer' '
1239 append_signoff <<\EOF >actual &&
1246 Signed-off-by: C O Mitter <committer@example.com>
1248 cat >expected <<\EOF &&
1249 4:Subject: [PATCH] subject
1252 13:Signed-off-by: C O Mitter <committer@example.com>
1254 15:Signed-off-by: C O Mitter <committer@example.com>
1256 test_cmp expected actual
1259 test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
1260 append_signoff <<\EOF >actual &&
1267 Change-id: Ideadbeef
1268 Signed-off-by: C O Mitter <committer@example.com>
1271 cat >expected <<\EOF &&
1272 4:Subject: [PATCH] subject
1275 14:Signed-off-by: C O Mitter <committer@example.com>
1277 test_cmp expected actual
1280 test_expect_success 'format patch ignores color.ui' '
1281 test_unconfig color.ui &&
1282 git format-patch --stdout -1 >expect &&
1283 test_config color.ui always &&
1284 git format-patch --stdout -1 >actual &&
1285 test_cmp expect actual
1288 test_expect_success 'cover letter using branch description (1)' '
1289 git checkout rebuild-1 &&
1290 test_config branch.rebuild-1.description hello &&
1291 git format-patch --stdout --cover-letter master >actual &&
1292 grep hello actual >/dev/null
1295 test_expect_success 'cover letter using branch description (2)' '
1296 git checkout rebuild-1 &&
1297 test_config branch.rebuild-1.description hello &&
1298 git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
1299 grep hello actual >/dev/null
1302 test_expect_success 'cover letter using branch description (3)' '
1303 git checkout rebuild-1 &&
1304 test_config branch.rebuild-1.description hello &&
1305 git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
1306 grep hello actual >/dev/null
1309 test_expect_success 'cover letter using branch description (4)' '
1310 git checkout rebuild-1 &&
1311 test_config branch.rebuild-1.description hello &&
1312 git format-patch --stdout --cover-letter master.. >actual &&
1313 grep hello actual >/dev/null
1316 test_expect_success 'cover letter using branch description (5)' '
1317 git checkout rebuild-1 &&
1318 test_config branch.rebuild-1.description hello &&
1319 git format-patch --stdout --cover-letter -2 HEAD >actual &&
1320 grep hello actual >/dev/null
1323 test_expect_success 'cover letter using branch description (6)' '
1324 git checkout rebuild-1 &&
1325 test_config branch.rebuild-1.description hello &&
1326 git format-patch --stdout --cover-letter -2 >actual &&
1327 grep hello actual >/dev/null
1330 test_expect_success 'cover letter with nothing' '
1331 git format-patch --stdout --cover-letter >actual &&
1332 test_line_count = 0 actual
1335 test_expect_success 'cover letter auto' '
1337 test_when_finished "rm -rf tmp;
1338 git config --unset format.coverletter" &&
1340 git config format.coverletter auto &&
1341 git format-patch -o tmp -1 >list &&
1342 test_line_count = 1 list &&
1343 git format-patch -o tmp -2 >list &&
1344 test_line_count = 3 list
1347 test_expect_success 'cover letter auto user override' '
1349 test_when_finished "rm -rf tmp;
1350 git config --unset format.coverletter" &&
1352 git config format.coverletter auto &&
1353 git format-patch -o tmp --cover-letter -1 >list &&
1354 test_line_count = 2 list &&
1355 git format-patch -o tmp --cover-letter -2 >list &&
1356 test_line_count = 3 list &&
1357 git format-patch -o tmp --no-cover-letter -1 >list &&
1358 test_line_count = 1 list &&
1359 git format-patch -o tmp --no-cover-letter -2 >list &&
1360 test_line_count = 2 list