format-patch: add "--rfc" for the common case of [RFC PATCH]
[git/debian.git] / t / t4014-format-patch.sh
blobed4d3c2e59a63bd25478f7654bab20bcb35fd29c
1 #!/bin/sh
3 # Copyright (c) 2006 Junio C Hamano
6 test_description='various format-patch tests'
8 . ./test-lib.sh
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 &&
14 cat file >elif &&
15 git add file elif &&
16 test_tick &&
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 &&
21 test_chmod +x elif &&
22 test_tick &&
23 git commit -m "Side changes #1" &&
25 for i in D E F; do echo "$i"; done >>file &&
26 git update-index file &&
27 test_tick &&
28 git commit -m "Side changes #2" &&
29 git tag C2 &&
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 &&
33 test_tick &&
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 &&
38 test_tick &&
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) &&
47 test $cnt = 3
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) &&
56 test $cnt = 2
60 test_expect_success "format-patch --ignore-if-in-upstream handles tags" '
61 git tag -a v1 -m tag side &&
62 git tag -a v2 -m tag master &&
63 git format-patch --stdout --ignore-if-in-upstream v2..v1 >patch1 &&
64 cnt=$(grep "^From " patch1 | wc -l) &&
65 test $cnt = 2
68 test_expect_success "format-patch doesn't consider merge commits" '
70 git checkout -b slave master &&
71 echo "Another line" >>file &&
72 test_tick &&
73 git commit -am "Slave change #1" &&
74 echo "Yet another line" >>file &&
75 test_tick &&
76 git commit -am "Slave change #2" &&
77 git checkout -b merger master &&
78 test_tick &&
79 git merge --no-ff slave &&
80 cnt=$(git format-patch -3 --stdout | grep "^From " | wc -l) &&
81 test $cnt = 3
84 test_expect_success "format-patch result applies" '
86 git checkout -b rebuild-0 master &&
87 git am -3 patch0 &&
88 cnt=$(git rev-list master.. | wc -l) &&
89 test $cnt = 2
92 test_expect_success "format-patch --ignore-if-in-upstream result applies" '
94 git checkout -b rebuild-1 master &&
95 git am -3 patch1 &&
96 cnt=$(git rev-list master.. | wc -l) &&
97 test $cnt = 2
100 test_expect_success 'commit did not screw up the log message' '
102 git cat-file commit side | grep "^Side .* with .* backslash-n"
106 test_expect_success 'format-patch did not screw up the log message' '
108 grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
109 grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
113 test_expect_success 'replay did not screw up the log message' '
115 git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
119 test_expect_success 'extra headers' '
121 git config format.headers "To: R E Cipient <rcipient@example.com>
122 " &&
123 git config --add format.headers "Cc: S E Cipient <scipient@example.com>
124 " &&
125 git format-patch --stdout master..side > patch2 &&
126 sed -e "/^\$/q" patch2 > hdrs2 &&
127 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs2 &&
128 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs2
132 test_expect_success 'extra headers without newlines' '
134 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
135 git config --add format.headers "Cc: S E Cipient <scipient@example.com>" &&
136 git format-patch --stdout master..side >patch3 &&
137 sed -e "/^\$/q" patch3 > hdrs3 &&
138 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs3 &&
139 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs3
143 test_expect_success 'extra headers with multiple To:s' '
145 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
146 git config --add format.headers "To: S E Cipient <scipient@example.com>" &&
147 git format-patch --stdout master..side > patch4 &&
148 sed -e "/^\$/q" patch4 > hdrs4 &&
149 grep "^To: R E Cipient <rcipient@example.com>,\$" hdrs4 &&
150 grep "^ *S E Cipient <scipient@example.com>\$" hdrs4
153 test_expect_success 'additional command line cc (ascii)' '
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_failure 'additional command line cc (rfc822)' '
163 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
164 git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
165 grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
166 grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" patch5
169 test_expect_success 'command line headers' '
171 git config --unset-all format.headers &&
172 git format-patch --add-header="Cc: R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 &&
173 grep "^Cc: R E Cipient <rcipient@example.com>\$" patch6
176 test_expect_success 'configuration headers and command line headers' '
178 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
179 git format-patch --add-header="Cc: S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 &&
180 grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch7 &&
181 grep "^ *S E Cipient <scipient@example.com>\$" patch7
184 test_expect_success 'command line To: header (ascii)' '
186 git config --unset-all format.headers &&
187 git format-patch --to="R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
188 grep "^To: R E Cipient <rcipient@example.com>\$" patch8
191 test_expect_failure 'command line To: header (rfc822)' '
193 git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
194 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch8
197 test_expect_failure 'command line To: header (rfc2047)' '
199 git format-patch --to="R Ä Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
200 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch8
203 test_expect_success 'configuration To: header (ascii)' '
205 git config format.to "R E Cipient <rcipient@example.com>" &&
206 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
207 grep "^To: R E Cipient <rcipient@example.com>\$" patch9
210 test_expect_failure 'configuration To: header (rfc822)' '
212 git config format.to "R. E. Cipient <rcipient@example.com>" &&
213 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
214 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch9
217 test_expect_failure 'configuration To: header (rfc2047)' '
219 git config format.to "R Ä Cipient <rcipient@example.com>" &&
220 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
221 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch9
224 # check_patch <patch>: Verify that <patch> looks like a half-sane
225 # patch email to avoid a false positive with !grep
226 check_patch () {
227 grep -e "^From:" "$1" &&
228 grep -e "^Date:" "$1" &&
229 grep -e "^Subject:" "$1"
232 test_expect_success 'format.from=false' '
234 git -c format.from=false format-patch --stdout master..side |
235 sed -e "/^\$/q" >patch &&
236 check_patch patch &&
237 ! grep "^From: C O Mitter <committer@example.com>\$" patch
240 test_expect_success 'format.from=true' '
242 git -c format.from=true format-patch --stdout master..side |
243 sed -e "/^\$/q" >patch &&
244 check_patch patch &&
245 grep "^From: C O Mitter <committer@example.com>\$" patch
248 test_expect_success 'format.from with address' '
250 git -c format.from="F R Om <from@example.com>" format-patch --stdout master..side |
251 sed -e "/^\$/q" >patch &&
252 check_patch patch &&
253 grep "^From: F R Om <from@example.com>\$" patch
256 test_expect_success '--no-from overrides format.from' '
258 git -c format.from="F R Om <from@example.com>" format-patch --no-from --stdout master..side |
259 sed -e "/^\$/q" >patch &&
260 check_patch patch &&
261 ! grep "^From: F R Om <from@example.com>\$" patch
264 test_expect_success '--from overrides format.from' '
266 git -c format.from="F R Om <from@example.com>" format-patch --from --stdout master..side |
267 sed -e "/^\$/q" >patch &&
268 check_patch patch &&
269 ! grep "^From: F R Om <from@example.com>\$" patch
272 test_expect_success '--no-to overrides config.to' '
274 git config --replace-all format.to \
275 "R E Cipient <rcipient@example.com>" &&
276 git format-patch --no-to --stdout master..side |
277 sed -e "/^\$/q" >patch10 &&
278 check_patch patch10 &&
279 ! grep "^To: R E Cipient <rcipient@example.com>\$" patch10
282 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 master..side |
288 sed -e "/^\$/q" >patch11 &&
289 check_patch patch11 &&
290 ! grep "^To: Someone <someone@out.there>\$" patch11 &&
291 grep "^To: Someone Else <else@out.there>\$" patch11
294 test_expect_success '--no-cc overrides config.cc' '
296 git config --replace-all format.cc \
297 "C E Cipient <rcipient@example.com>" &&
298 git format-patch --no-cc --stdout master..side |
299 sed -e "/^\$/q" >patch12 &&
300 check_patch patch12 &&
301 ! grep "^Cc: C E Cipient <rcipient@example.com>\$" patch12
304 test_expect_success '--no-add-header overrides config.headers' '
306 git config --replace-all format.headers \
307 "Header1: B E Cipient <rcipient@example.com>" &&
308 git format-patch --no-add-header --stdout master..side |
309 sed -e "/^\$/q" >patch13 &&
310 check_patch patch13 &&
311 ! grep "^Header1: B E Cipient <rcipient@example.com>\$" patch13
314 test_expect_success 'multiple files' '
316 rm -rf patches/ &&
317 git checkout side &&
318 git format-patch -o patches/ master &&
319 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
322 test_expect_success 'reroll count' '
323 rm -fr patches &&
324 git format-patch -o patches --cover-letter --reroll-count 4 master..side >list &&
325 ! grep -v "^patches/v4-000[0-3]-" list &&
326 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
327 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
330 test_expect_success 'reroll count (-v)' '
331 rm -fr patches &&
332 git format-patch -o patches --cover-letter -v4 master..side >list &&
333 ! grep -v "^patches/v4-000[0-3]-" list &&
334 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
335 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
338 check_threading () {
339 expect="$1" &&
340 shift &&
341 (git format-patch --stdout "$@"; echo $? > status.out) |
342 # Prints everything between the Message-ID and In-Reply-To,
343 # and replaces all Message-ID-lookalikes by a sequence number
344 perl -ne '
345 if (/^(message-id|references|in-reply-to)/i) {
346 $printing = 1;
347 } elsif (/^\S/) {
348 $printing = 0;
350 if ($printing) {
351 $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
352 for $k (keys %h) {s/$k/$h{$k}/};
353 print;
355 print "---\n" if /^From /i;
356 ' > actual &&
357 test 0 = "$(cat status.out)" &&
358 test_cmp "$expect" actual
361 cat >> expect.no-threading <<EOF
367 test_expect_success 'no threading' '
368 git checkout side &&
369 check_threading expect.no-threading master
372 cat > expect.thread <<EOF
374 Message-Id: <0>
376 Message-Id: <1>
377 In-Reply-To: <0>
378 References: <0>
380 Message-Id: <2>
381 In-Reply-To: <0>
382 References: <0>
385 test_expect_success 'thread' '
386 check_threading expect.thread --thread master
389 cat > expect.in-reply-to <<EOF
391 Message-Id: <0>
392 In-Reply-To: <1>
393 References: <1>
395 Message-Id: <2>
396 In-Reply-To: <1>
397 References: <1>
399 Message-Id: <3>
400 In-Reply-To: <1>
401 References: <1>
404 test_expect_success 'thread in-reply-to' '
405 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
406 --thread master
409 cat > expect.cover-letter <<EOF
411 Message-Id: <0>
413 Message-Id: <1>
414 In-Reply-To: <0>
415 References: <0>
417 Message-Id: <2>
418 In-Reply-To: <0>
419 References: <0>
421 Message-Id: <3>
422 In-Reply-To: <0>
423 References: <0>
426 test_expect_success 'thread cover-letter' '
427 check_threading expect.cover-letter --cover-letter --thread master
430 cat > expect.cl-irt <<EOF
432 Message-Id: <0>
433 In-Reply-To: <1>
434 References: <1>
436 Message-Id: <2>
437 In-Reply-To: <0>
438 References: <1>
441 Message-Id: <3>
442 In-Reply-To: <0>
443 References: <1>
446 Message-Id: <4>
447 In-Reply-To: <0>
448 References: <1>
452 test_expect_success 'thread cover-letter in-reply-to' '
453 check_threading expect.cl-irt --cover-letter \
454 --in-reply-to="<test.message>" --thread master
457 test_expect_success 'thread explicit shallow' '
458 check_threading expect.cl-irt --cover-letter \
459 --in-reply-to="<test.message>" --thread=shallow master
462 cat > expect.deep <<EOF
464 Message-Id: <0>
466 Message-Id: <1>
467 In-Reply-To: <0>
468 References: <0>
470 Message-Id: <2>
471 In-Reply-To: <1>
472 References: <0>
476 test_expect_success 'thread deep' '
477 check_threading expect.deep --thread=deep master
480 cat > expect.deep-irt <<EOF
482 Message-Id: <0>
483 In-Reply-To: <1>
484 References: <1>
486 Message-Id: <2>
487 In-Reply-To: <0>
488 References: <1>
491 Message-Id: <3>
492 In-Reply-To: <2>
493 References: <1>
498 test_expect_success 'thread deep in-reply-to' '
499 check_threading expect.deep-irt --thread=deep \
500 --in-reply-to="<test.message>" master
503 cat > expect.deep-cl <<EOF
505 Message-Id: <0>
507 Message-Id: <1>
508 In-Reply-To: <0>
509 References: <0>
511 Message-Id: <2>
512 In-Reply-To: <1>
513 References: <0>
516 Message-Id: <3>
517 In-Reply-To: <2>
518 References: <0>
523 test_expect_success 'thread deep cover-letter' '
524 check_threading expect.deep-cl --cover-letter --thread=deep master
527 cat > expect.deep-cl-irt <<EOF
529 Message-Id: <0>
530 In-Reply-To: <1>
531 References: <1>
533 Message-Id: <2>
534 In-Reply-To: <0>
535 References: <1>
538 Message-Id: <3>
539 In-Reply-To: <2>
540 References: <1>
544 Message-Id: <4>
545 In-Reply-To: <3>
546 References: <1>
552 test_expect_success 'thread deep cover-letter in-reply-to' '
553 check_threading expect.deep-cl-irt --cover-letter \
554 --in-reply-to="<test.message>" --thread=deep master
557 test_expect_success 'thread via config' '
558 test_config format.thread true &&
559 check_threading expect.thread master
562 test_expect_success 'thread deep via config' '
563 test_config format.thread deep &&
564 check_threading expect.deep master
567 test_expect_success 'thread config + override' '
568 test_config format.thread deep &&
569 check_threading expect.thread --thread master
572 test_expect_success 'thread config + --no-thread' '
573 test_config format.thread deep &&
574 check_threading expect.no-threading --no-thread master
577 test_expect_success 'excessive subject' '
579 rm -rf patches/ &&
580 git checkout side &&
581 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
582 git update-index file &&
583 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." &&
584 git format-patch -o patches/ master..side &&
585 ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
588 test_expect_success 'cover-letter inherits diff options' '
590 git mv file foo &&
591 git commit -m foo &&
592 git format-patch --no-renames --cover-letter -1 &&
593 check_patch 0000-cover-letter.patch &&
594 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
595 git format-patch --cover-letter -1 -M &&
596 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
600 cat > expect << EOF
601 This is an excessively long subject line for a message due to the
602 habit some projects have of not having a short, one-line subject at
603 the start of the commit message, but rather sticking a whole
604 paragraph right at the start as the only thing in the commit
605 message. It had better not become the filename for the patch.
610 test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
612 git format-patch --cover-letter -2 &&
613 sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
614 test_cmp expect output
618 cat > expect << EOF
619 index 40f36c6..2dc5c23 100644
620 --- a/file
621 +++ b/file
622 @@ -13,4 +13,20 @@ C
630 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 \
635 >output &&
636 test_cmp expect output
640 cat > expect << EOF
642 diff --git a/file b/file
643 index 40f36c6..2dc5c23 100644
644 --- a/file
645 +++ b/file
646 @@ -14,3 +14,19 @@ C
653 test_expect_success 'format-patch -p suppresses stat' '
655 git format-patch -p -2 &&
656 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
657 test_cmp expect output
661 test_expect_success 'format-patch from a subdirectory (1)' '
662 filename=$(
663 rm -rf sub &&
664 mkdir -p sub/dir &&
665 cd sub/dir &&
666 git format-patch -1
667 ) &&
668 case "$filename" in
670 ;; # ok
672 echo "Oops? $filename"
673 false
675 esac &&
676 test -f "$filename"
679 test_expect_success 'format-patch from a subdirectory (2)' '
680 filename=$(
681 rm -rf sub &&
682 mkdir -p sub/dir &&
683 cd sub/dir &&
684 git format-patch -1 -o ..
685 ) &&
686 case "$filename" in
687 ../0*)
688 ;; # ok
690 echo "Oops? $filename"
691 false
693 esac &&
694 basename=$(expr "$filename" : ".*/\(.*\)") &&
695 test -f "sub/$basename"
698 test_expect_success 'format-patch from a subdirectory (3)' '
699 rm -f 0* &&
700 filename=$(
701 rm -rf sub &&
702 mkdir -p sub/dir &&
703 cd sub/dir &&
704 git format-patch -1 -o "$TRASH_DIRECTORY"
705 ) &&
706 basename=$(expr "$filename" : ".*/\(.*\)") &&
707 test -f "$basename"
710 test_expect_success 'format-patch --in-reply-to' '
711 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
712 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
713 grep "^References: <baz@foo.bar>" patch8
716 test_expect_success 'format-patch --signoff' '
717 git format-patch -1 --signoff --stdout >out &&
718 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
721 test_expect_success 'format-patch --notes --signoff' '
722 git notes --ref test add -m "test message" HEAD &&
723 git format-patch -1 --signoff --stdout --notes=test >out &&
724 # Three dashes must come after S-o-b
725 ! sed "/^Signed-off-by: /q" out | grep "test message" &&
726 sed "1,/^Signed-off-by: /d" out | grep "test message" &&
727 # Notes message must come after three dashes
728 ! sed "/^---$/q" out | grep "test message" &&
729 sed "1,/^---$/d" out | grep "test message"
732 echo "fatal: --name-only does not make sense" > expect.name-only
733 echo "fatal: --name-status does not make sense" > expect.name-status
734 echo "fatal: --check does not make sense" > expect.check
736 test_expect_success 'options no longer allowed for format-patch' '
737 test_must_fail git format-patch --name-only 2> output &&
738 test_i18ncmp expect.name-only output &&
739 test_must_fail git format-patch --name-status 2> output &&
740 test_i18ncmp expect.name-status output &&
741 test_must_fail git format-patch --check 2> output &&
742 test_i18ncmp expect.check output'
744 test_expect_success 'format-patch --numstat should produce a patch' '
745 git format-patch --numstat --stdout master..side > output &&
746 test 5 = $(grep "^diff --git a/" output | wc -l)'
748 test_expect_success 'format-patch -- <path>' '
749 git format-patch master..side -- file 2>error &&
750 ! grep "Use .--" error
753 test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
754 git format-patch --ignore-if-in-upstream HEAD
757 test_expect_success 'format-patch --signature' '
758 git format-patch --stdout --signature="my sig" -1 >output &&
759 grep "my sig" output
762 test_expect_success 'format-patch with format.signature config' '
763 git config format.signature "config sig" &&
764 git format-patch --stdout -1 >output &&
765 grep "config sig" output
768 test_expect_success 'format-patch --signature overrides format.signature' '
769 git config format.signature "config sig" &&
770 git format-patch --stdout --signature="overrides" -1 >output &&
771 ! grep "config sig" output &&
772 grep "overrides" output
775 test_expect_success 'format-patch --no-signature ignores format.signature' '
776 git config format.signature "config sig" &&
777 git format-patch --stdout --signature="my sig" --no-signature \
778 -1 >output &&
779 check_patch output &&
780 ! grep "config sig" output &&
781 ! grep "my sig" output &&
782 ! grep "^-- \$" output
785 test_expect_success 'format-patch --signature --cover-letter' '
786 git config --unset-all format.signature &&
787 git format-patch --stdout --signature="my sig" --cover-letter \
788 -1 >output &&
789 grep "my sig" output &&
790 test 2 = $(grep "my sig" output | wc -l)
793 test_expect_success 'format.signature="" suppresses signatures' '
794 git config format.signature "" &&
795 git format-patch --stdout -1 >output &&
796 check_patch output &&
797 ! grep "^-- \$" output
800 test_expect_success 'format-patch --no-signature suppresses signatures' '
801 git config --unset-all format.signature &&
802 git format-patch --stdout --no-signature -1 >output &&
803 check_patch output &&
804 ! grep "^-- \$" output
807 test_expect_success 'format-patch --signature="" suppresses signatures' '
808 git format-patch --stdout --signature="" -1 >output &&
809 check_patch output &&
810 ! grep "^-- \$" output
813 test_expect_success 'prepare mail-signature input' '
814 cat >mail-signature <<-\EOF
816 Test User <test.email@kernel.org>
817 http://git.kernel.org/cgit/git/git.git
819 git.kernel.org/?p=git/git.git;a=summary
824 test_expect_success '--signature-file=file works' '
825 git format-patch --stdout --signature-file=mail-signature -1 >output &&
826 check_patch output &&
827 sed -e "1,/^-- \$/d" <output >actual &&
829 cat mail-signature && echo
830 } >expect &&
831 test_cmp expect actual
834 test_expect_success 'format.signaturefile works' '
835 test_config format.signaturefile mail-signature &&
836 git format-patch --stdout -1 >output &&
837 check_patch output &&
838 sed -e "1,/^-- \$/d" <output >actual &&
840 cat mail-signature && echo
841 } >expect &&
842 test_cmp expect actual
845 test_expect_success '--no-signature suppresses format.signaturefile ' '
846 test_config format.signaturefile mail-signature &&
847 git format-patch --stdout --no-signature -1 >output &&
848 check_patch output &&
849 ! grep "^-- \$" output
852 test_expect_success '--signature-file overrides format.signaturefile' '
853 cat >other-mail-signature <<-\EOF &&
854 Use this other signature instead of mail-signature.
856 test_config format.signaturefile mail-signature &&
857 git format-patch --stdout \
858 --signature-file=other-mail-signature -1 >output &&
859 check_patch output &&
860 sed -e "1,/^-- \$/d" <output >actual &&
862 cat other-mail-signature && echo
863 } >expect &&
864 test_cmp expect actual
867 test_expect_success '--signature overrides format.signaturefile' '
868 test_config format.signaturefile mail-signature &&
869 git format-patch --stdout --signature="my sig" -1 >output &&
870 check_patch output &&
871 grep "my sig" output
874 test_expect_success TTY 'format-patch --stdout paginates' '
875 rm -f pager_used &&
876 test_terminal env GIT_PAGER="wc >pager_used" git format-patch --stdout --all &&
877 test_path_is_file pager_used
880 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
881 rm -f pager_used &&
882 test_terminal env GIT_PAGER="wc >pager_used" git --no-pager format-patch --stdout --all &&
883 test_terminal env GIT_PAGER="wc >pager_used" git -c "pager.format-patch=false" format-patch --stdout --all &&
884 test_path_is_missing pager_used &&
885 test_path_is_missing .git/pager_used
888 test_expect_success 'format-patch handles multi-line subjects' '
889 rm -rf patches/ &&
890 echo content >>file &&
891 for i in one two three; do echo $i; done >msg &&
892 git add file &&
893 git commit -F msg &&
894 git format-patch -o patches -1 &&
895 grep ^Subject: patches/0001-one.patch >actual &&
896 echo "Subject: [PATCH] one two three" >expect &&
897 test_cmp expect actual
900 test_expect_success 'format-patch handles multi-line encoded subjects' '
901 rm -rf patches/ &&
902 echo content >>file &&
903 for i in en två tre; do echo $i; done >msg &&
904 git add file &&
905 git commit -F msg &&
906 git format-patch -o patches -1 &&
907 grep ^Subject: patches/0001-en.patch >actual &&
908 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
909 test_cmp expect actual
912 M8="foo bar "
913 M64=$M8$M8$M8$M8$M8$M8$M8$M8
914 M512=$M64$M64$M64$M64$M64$M64$M64$M64
915 cat >expect <<'EOF'
916 Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
917 bar 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 foo bar foo bar foo bar foo bar foo bar foo bar
920 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
921 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
922 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
924 test_expect_success 'format-patch wraps extremely long subject (ascii)' '
925 echo content >>file &&
926 git add file &&
927 git commit -m "$M512" &&
928 git format-patch --stdout -1 >patch &&
929 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
930 test_cmp expect subject
933 M8="föö bar "
934 M64=$M8$M8$M8$M8$M8$M8$M8$M8
935 M512=$M64$M64$M64$M64$M64$M64$M64$M64
936 cat >expect <<'EOF'
937 Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
938 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
939 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
940 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
941 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
942 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
943 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
944 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
945 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
946 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
947 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
948 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
949 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
950 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
951 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
952 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
953 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
954 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
955 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
956 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
957 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
958 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
959 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
960 =?UTF-8?q?bar?=
962 test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
963 rm -rf patches/ &&
964 echo content >>file &&
965 git add file &&
966 git commit -m "$M512" &&
967 git format-patch --stdout -1 >patch &&
968 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
969 test_cmp expect subject
972 check_author() {
973 echo content >>file &&
974 git add file &&
975 GIT_AUTHOR_NAME=$1 git commit -m author-check &&
976 git format-patch --stdout -1 >patch &&
977 sed -n "/^From: /p; /^ /p; /^$/q" <patch >actual &&
978 test_cmp expect actual
981 cat >expect <<'EOF'
982 From: "Foo B. Bar" <author@example.com>
984 test_expect_success 'format-patch quotes dot in from-headers' '
985 check_author "Foo B. Bar"
988 cat >expect <<'EOF'
989 From: "Foo \"The Baz\" Bar" <author@example.com>
991 test_expect_success 'format-patch quotes double-quote in from-headers' '
992 check_author "Foo \"The Baz\" Bar"
995 cat >expect <<'EOF'
996 From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
998 test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
999 check_author "Föo Bar"
1002 cat >expect <<'EOF'
1003 From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
1005 test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
1006 check_author "Föo B. Bar"
1009 cat >expect <<EOF
1010 From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
1011 <author@example.com>
1013 test_expect_success 'format-patch wraps moderately long from-header (ascii)' '
1014 check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
1017 cat >expect <<'EOF'
1018 From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1019 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1020 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
1022 test_expect_success 'format-patch wraps extremely long from-header (ascii)' '
1023 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"
1026 cat >expect <<'EOF'
1027 From: "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1028 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1029 Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
1031 test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
1032 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"
1035 cat >expect <<'EOF'
1036 From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
1037 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
1038 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
1039 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
1040 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
1042 test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
1043 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"
1046 cat >expect <<'EOF'
1047 Subject: header with . in it
1049 test_expect_success 'subject lines do not have 822 atom-quoting' '
1050 echo content >>file &&
1051 git add file &&
1052 git commit -m "header with . in it" &&
1053 git format-patch -k -1 --stdout >patch &&
1054 grep ^Subject: patch >actual &&
1055 test_cmp expect actual
1058 cat >expect <<'EOF'
1059 Subject: [PREFIX 1/1] header with . in it
1061 test_expect_success 'subject prefixes have space prepended' '
1062 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
1063 grep ^Subject: patch >actual &&
1064 test_cmp expect actual
1067 cat >expect <<'EOF'
1068 Subject: [1/1] header with . in it
1070 test_expect_success 'empty subject prefix does not have extra space' '
1071 git format-patch -n -1 --stdout --subject-prefix= >patch &&
1072 grep ^Subject: patch >actual &&
1073 test_cmp expect actual
1076 test_expect_success '--rfc' '
1077 cat >expect <<-\EOF &&
1078 Subject: [RFC PATCH 1/1] header with . in it
1080 git format-patch -n -1 --stdout --rfc >patch &&
1081 grep ^Subject: patch >actual &&
1082 test_cmp expect actual
1085 test_expect_success '--from=ident notices bogus ident' '
1086 test_must_fail git format-patch -1 --stdout --from=foo >patch
1089 test_expect_success '--from=ident replaces author' '
1090 git format-patch -1 --stdout --from="Me <me@example.com>" >patch &&
1091 cat >expect <<-\EOF &&
1092 From: Me <me@example.com>
1094 From: A U Thor <author@example.com>
1097 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1098 test_cmp expect patch.head
1101 test_expect_success '--from uses committer ident' '
1102 git format-patch -1 --stdout --from >patch &&
1103 cat >expect <<-\EOF &&
1104 From: C O Mitter <committer@example.com>
1106 From: A U Thor <author@example.com>
1109 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1110 test_cmp expect patch.head
1113 test_expect_success '--from omits redundant in-body header' '
1114 git format-patch -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1115 cat >expect <<-\EOF &&
1116 From: A U Thor <author@example.com>
1119 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1120 test_cmp expect patch.head
1123 test_expect_success 'in-body headers trigger content encoding' '
1124 test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
1125 test_when_finished "git reset --hard HEAD^" &&
1126 git format-patch -1 --stdout --from >patch &&
1127 cat >expect <<-\EOF &&
1128 From: C O Mitter <committer@example.com>
1129 Content-Type: text/plain; charset=UTF-8
1131 From: éxötìc <author@example.com>
1134 sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" <patch >patch.head &&
1135 test_cmp expect patch.head
1138 append_signoff()
1140 C=$(git commit-tree HEAD^^{tree} -p HEAD) &&
1141 git format-patch --stdout --signoff $C^..$C >append_signoff.patch &&
1142 sed -n -e "1,/^---$/p" append_signoff.patch |
1143 egrep -n "^Subject|Sign|^$"
1146 test_expect_success 'signoff: commit with no body' '
1147 append_signoff </dev/null >actual &&
1148 cat <<\EOF | sed "s/EOL$//" >expected &&
1149 4:Subject: [PATCH] EOL
1151 9:Signed-off-by: C O Mitter <committer@example.com>
1153 test_cmp expected actual
1156 test_expect_success 'signoff: commit with only subject' '
1157 echo subject | append_signoff >actual &&
1158 cat >expected <<\EOF &&
1159 4:Subject: [PATCH] subject
1161 9:Signed-off-by: C O Mitter <committer@example.com>
1163 test_cmp expected actual
1166 test_expect_success 'signoff: commit with only subject that does not end with NL' '
1167 printf subject | append_signoff >actual &&
1168 cat >expected <<\EOF &&
1169 4:Subject: [PATCH] subject
1171 9:Signed-off-by: C O Mitter <committer@example.com>
1173 test_cmp expected actual
1176 test_expect_success 'signoff: no existing signoffs' '
1177 append_signoff <<\EOF >actual &&
1178 subject
1180 body
1182 cat >expected <<\EOF &&
1183 4:Subject: [PATCH] subject
1186 11:Signed-off-by: C O Mitter <committer@example.com>
1188 test_cmp expected actual
1191 test_expect_success 'signoff: no existing signoffs and no trailing NL' '
1192 printf "subject\n\nbody" | append_signoff >actual &&
1193 cat >expected <<\EOF &&
1194 4:Subject: [PATCH] subject
1197 11:Signed-off-by: C O Mitter <committer@example.com>
1199 test_cmp expected actual
1202 test_expect_success 'signoff: some random signoff' '
1203 append_signoff <<\EOF >actual &&
1204 subject
1206 body
1208 Signed-off-by: my@house
1210 cat >expected <<\EOF &&
1211 4:Subject: [PATCH] subject
1214 11:Signed-off-by: my@house
1215 12:Signed-off-by: C O Mitter <committer@example.com>
1217 test_cmp expected actual
1220 test_expect_success 'signoff: misc conforming footer elements' '
1221 append_signoff <<\EOF >actual &&
1222 subject
1224 body
1226 Signed-off-by: my@house
1227 (cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1228 Tested-by: Some One <someone@example.com>
1229 Bug: 1234
1231 cat >expected <<\EOF &&
1232 4:Subject: [PATCH] subject
1235 11:Signed-off-by: my@house
1236 15:Signed-off-by: C O Mitter <committer@example.com>
1238 test_cmp expected actual
1241 test_expect_success 'signoff: some random signoff-alike' '
1242 append_signoff <<\EOF >actual &&
1243 subject
1245 body
1246 Fooled-by-me: my@house
1248 cat >expected <<\EOF &&
1249 4:Subject: [PATCH] subject
1252 12:Signed-off-by: C O Mitter <committer@example.com>
1254 test_cmp expected actual
1257 test_expect_success 'signoff: not really a signoff' '
1258 append_signoff <<\EOF >actual &&
1259 subject
1261 I want to mention about Signed-off-by: here.
1263 cat >expected <<\EOF &&
1264 4:Subject: [PATCH] subject
1266 9:I want to mention about Signed-off-by: here.
1268 11:Signed-off-by: C O Mitter <committer@example.com>
1270 test_cmp expected actual
1273 test_expect_success 'signoff: not really a signoff (2)' '
1274 append_signoff <<\EOF >actual &&
1275 subject
1277 My unfortunate
1278 Signed-off-by: example happens to be wrapped here.
1280 cat >expected <<\EOF &&
1281 4:Subject: [PATCH] subject
1283 10:Signed-off-by: example happens to be wrapped here.
1285 12:Signed-off-by: C O Mitter <committer@example.com>
1287 test_cmp expected actual
1290 test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
1291 append_signoff <<\EOF >actual &&
1292 subject
1294 Signed-off-by: my@house
1295 Signed-off-by: your@house
1297 A lot of houses.
1299 cat >expected <<\EOF &&
1300 4:Subject: [PATCH] subject
1302 9:Signed-off-by: my@house
1303 10:Signed-off-by: your@house
1306 14:Signed-off-by: C O Mitter <committer@example.com>
1308 test_cmp expected actual
1311 test_expect_success 'signoff: the same signoff at the end' '
1312 append_signoff <<\EOF >actual &&
1313 subject
1315 body
1317 Signed-off-by: C O Mitter <committer@example.com>
1319 cat >expected <<\EOF &&
1320 4:Subject: [PATCH] subject
1323 11:Signed-off-by: C O Mitter <committer@example.com>
1325 test_cmp expected actual
1328 test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
1329 printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
1330 append_signoff >actual &&
1331 cat >expected <<\EOF &&
1332 4:Subject: [PATCH] subject
1334 9:Signed-off-by: C O Mitter <committer@example.com>
1336 test_cmp expected actual
1339 test_expect_success 'signoff: the same signoff NOT at the end' '
1340 append_signoff <<\EOF >actual &&
1341 subject
1343 body
1345 Signed-off-by: C O Mitter <committer@example.com>
1346 Signed-off-by: my@house
1348 cat >expected <<\EOF &&
1349 4:Subject: [PATCH] subject
1352 11:Signed-off-by: C O Mitter <committer@example.com>
1353 12:Signed-off-by: my@house
1355 test_cmp expected actual
1358 test_expect_success 'signoff: detect garbage in non-conforming footer' '
1359 append_signoff <<\EOF >actual &&
1360 subject
1362 body
1364 Tested-by: my@house
1365 Some Trash
1366 Signed-off-by: C O Mitter <committer@example.com>
1368 cat >expected <<\EOF &&
1369 4:Subject: [PATCH] subject
1372 13:Signed-off-by: C O Mitter <committer@example.com>
1374 15:Signed-off-by: C O Mitter <committer@example.com>
1376 test_cmp expected actual
1379 test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
1380 append_signoff <<\EOF >actual &&
1381 subject
1383 body
1385 Reviewed-id: Noone
1386 Tested-by: my@house
1387 Change-id: Ideadbeef
1388 Signed-off-by: C O Mitter <committer@example.com>
1389 Bug: 1234
1391 cat >expected <<\EOF &&
1392 4:Subject: [PATCH] subject
1395 14:Signed-off-by: C O Mitter <committer@example.com>
1397 test_cmp expected actual
1400 test_expect_success 'format patch ignores color.ui' '
1401 test_unconfig color.ui &&
1402 git format-patch --stdout -1 >expect &&
1403 test_config color.ui always &&
1404 git format-patch --stdout -1 >actual &&
1405 test_cmp expect actual
1408 test_expect_success 'cover letter using branch description (1)' '
1409 git checkout rebuild-1 &&
1410 test_config branch.rebuild-1.description hello &&
1411 git format-patch --stdout --cover-letter master >actual &&
1412 grep hello actual >/dev/null
1415 test_expect_success 'cover letter using branch description (2)' '
1416 git checkout rebuild-1 &&
1417 test_config branch.rebuild-1.description hello &&
1418 git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
1419 grep hello actual >/dev/null
1422 test_expect_success 'cover letter using branch description (3)' '
1423 git checkout rebuild-1 &&
1424 test_config branch.rebuild-1.description hello &&
1425 git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
1426 grep hello actual >/dev/null
1429 test_expect_success 'cover letter using branch description (4)' '
1430 git checkout rebuild-1 &&
1431 test_config branch.rebuild-1.description hello &&
1432 git format-patch --stdout --cover-letter master.. >actual &&
1433 grep hello actual >/dev/null
1436 test_expect_success 'cover letter using branch description (5)' '
1437 git checkout rebuild-1 &&
1438 test_config branch.rebuild-1.description hello &&
1439 git format-patch --stdout --cover-letter -2 HEAD >actual &&
1440 grep hello actual >/dev/null
1443 test_expect_success 'cover letter using branch description (6)' '
1444 git checkout rebuild-1 &&
1445 test_config branch.rebuild-1.description hello &&
1446 git format-patch --stdout --cover-letter -2 >actual &&
1447 grep hello actual >/dev/null
1450 test_expect_success 'cover letter with nothing' '
1451 git format-patch --stdout --cover-letter >actual &&
1452 test_line_count = 0 actual
1455 test_expect_success 'cover letter auto' '
1456 mkdir -p tmp &&
1457 test_when_finished "rm -rf tmp;
1458 git config --unset format.coverletter" &&
1460 git config format.coverletter auto &&
1461 git format-patch -o tmp -1 >list &&
1462 test_line_count = 1 list &&
1463 git format-patch -o tmp -2 >list &&
1464 test_line_count = 3 list
1467 test_expect_success 'cover letter auto user override' '
1468 mkdir -p tmp &&
1469 test_when_finished "rm -rf tmp;
1470 git config --unset format.coverletter" &&
1472 git config format.coverletter auto &&
1473 git format-patch -o tmp --cover-letter -1 >list &&
1474 test_line_count = 2 list &&
1475 git format-patch -o tmp --cover-letter -2 >list &&
1476 test_line_count = 3 list &&
1477 git format-patch -o tmp --no-cover-letter -1 >list &&
1478 test_line_count = 1 list &&
1479 git format-patch -o tmp --no-cover-letter -2 >list &&
1480 test_line_count = 2 list
1483 test_expect_success 'format-patch --zero-commit' '
1484 git format-patch --zero-commit --stdout v2..v1 >patch2 &&
1485 grep "^From " patch2 | sort | uniq >actual &&
1486 echo "From $_z40 Mon Sep 17 00:00:00 2001" >expect &&
1487 test_cmp expect actual
1490 test_expect_success 'From line has expected format' '
1491 git format-patch --stdout v2..v1 >patch2 &&
1492 grep "^From " patch2 >from &&
1493 grep "^From $_x40 Mon Sep 17 00:00:00 2001$" patch2 >filtered &&
1494 test_cmp from filtered
1497 test_expect_success 'format-patch format.outputDirectory option' '
1498 test_config format.outputDirectory patches &&
1499 rm -fr patches &&
1500 git format-patch master..side &&
1501 test $(git rev-list master..side | wc -l) -eq $(ls patches | wc -l)
1504 test_expect_success 'format-patch -o overrides format.outputDirectory' '
1505 test_config format.outputDirectory patches &&
1506 rm -fr patches patchset &&
1507 git format-patch master..side -o patchset &&
1508 test_path_is_missing patches &&
1509 test_path_is_dir patchset
1512 test_expect_success 'format-patch --base' '
1513 git checkout side &&
1514 git format-patch --stdout --base=HEAD~3 -1 >patch &&
1515 grep "^base-commit:" patch >actual &&
1516 grep "^prerequisite-patch-id:" patch >>actual &&
1517 echo "base-commit: $(git rev-parse HEAD~3)" >expected &&
1518 echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1519 echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1520 test_cmp expected actual
1523 test_expect_success 'format-patch --base errors out when base commit is in revision list' '
1524 test_must_fail git format-patch --base=HEAD -2 &&
1525 test_must_fail git format-patch --base=HEAD~1 -2 &&
1526 git format-patch --stdout --base=HEAD~2 -2 >patch &&
1527 grep "^base-commit:" patch >actual &&
1528 echo "base-commit: $(git rev-parse HEAD~2)" >expected &&
1529 test_cmp expected actual
1532 test_expect_success 'format-patch --base errors out when base commit is not ancestor of revision list' '
1533 # For history as below:
1535 # ---Q---P---Z---Y---*---X
1536 # \ /
1537 # ------------W
1539 # If "format-patch Z..X" is given, P and Z can not be specified as the base commit
1540 git checkout -b topic1 master &&
1541 git rev-parse HEAD >commit-id-base &&
1542 test_commit P &&
1543 git rev-parse HEAD >commit-id-P &&
1544 test_commit Z &&
1545 git rev-parse HEAD >commit-id-Z &&
1546 test_commit Y &&
1547 git checkout -b topic2 master &&
1548 test_commit W &&
1549 git merge topic1 &&
1550 test_commit X &&
1551 test_must_fail git format-patch --base=$(cat commit-id-P) -3 &&
1552 test_must_fail git format-patch --base=$(cat commit-id-Z) -3 &&
1553 git format-patch --stdout --base=$(cat commit-id-base) -3 >patch &&
1554 grep "^base-commit:" patch >actual &&
1555 echo "base-commit: $(cat commit-id-base)" >expected &&
1556 test_cmp expected actual
1559 test_expect_success 'format-patch --base=auto' '
1560 git checkout -b upstream master &&
1561 git checkout -b local upstream &&
1562 git branch --set-upstream-to=upstream &&
1563 test_commit N1 &&
1564 test_commit N2 &&
1565 git format-patch --stdout --base=auto -2 >patch &&
1566 grep "^base-commit:" patch >actual &&
1567 echo "base-commit: $(git rev-parse upstream)" >expected &&
1568 test_cmp expected actual
1571 test_expect_success 'format-patch errors out when history involves criss-cross' '
1572 # setup criss-cross history
1574 # B---M1---D
1575 # / \ /
1576 # A X
1577 # \ / \
1578 # C---M2---E
1580 git checkout master &&
1581 test_commit A &&
1582 git checkout -b xb master &&
1583 test_commit B &&
1584 git checkout -b xc master &&
1585 test_commit C &&
1586 git checkout -b xbc xb -- &&
1587 git merge xc &&
1588 git checkout -b xcb xc -- &&
1589 git branch --set-upstream-to=xbc &&
1590 git merge xb &&
1591 git checkout xbc &&
1592 test_commit D &&
1593 git checkout xcb &&
1594 test_commit E &&
1595 test_must_fail git format-patch --base=auto -1
1598 test_expect_success 'format-patch format.useAutoBaseoption' '
1599 test_when_finished "git config --unset format.useAutoBase" &&
1600 git checkout local &&
1601 git config format.useAutoBase true &&
1602 git format-patch --stdout -1 >patch &&
1603 grep "^base-commit:" patch >actual &&
1604 echo "base-commit: $(git rev-parse upstream)" >expected &&
1605 test_cmp expected actual
1608 test_expect_success 'format-patch --base overrides format.useAutoBase' '
1609 test_when_finished "git config --unset format.useAutoBase" &&
1610 git config format.useAutoBase true &&
1611 git format-patch --stdout --base=HEAD~1 -1 >patch &&
1612 grep "^base-commit:" patch >actual &&
1613 echo "base-commit: $(git rev-parse HEAD~1)" >expected &&
1614 test_cmp expected actual
1617 test_expect_success 'format-patch --pretty=mboxrd' '
1618 sp=" " &&
1619 cat >msg <<-INPUT_END &&
1620 mboxrd should escape the body
1622 From could trip up a loose mbox parser
1623 >From extra escape for reversibility
1624 >>From extra escape for reversibility 2
1625 from lower case not escaped
1626 Fromm bad speling not escaped
1627 From with leading space not escaped
1630 From
1631 From$sp
1632 From $sp
1633 From $sp
1634 INPUT_END
1636 cat >expect <<-INPUT_END &&
1637 >From could trip up a loose mbox parser
1638 >>From extra escape for reversibility
1639 >>>From extra escape for reversibility 2
1640 from lower case not escaped
1641 Fromm bad speling not escaped
1642 From with leading space not escaped
1645 From
1646 From
1647 From
1648 From
1649 INPUT_END
1651 C=$(git commit-tree HEAD^^{tree} -p HEAD <msg) &&
1652 git format-patch --pretty=mboxrd --stdout -1 $C~1..$C >patch &&
1653 git grep -h --no-index -A11 \
1654 "^>From could trip up a loose mbox parser" patch >actual &&
1655 test_cmp expect actual
1658 test_done