Merge branch 'rs/hex2chr'
[git.git] / t / t4014-format-patch.sh
blobb0579dd45242f64d129d3c10e8ae1c3de6cc5458
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 '--from=ident notices bogus ident' '
1077 test_must_fail git format-patch -1 --stdout --from=foo >patch
1080 test_expect_success '--from=ident replaces author' '
1081 git format-patch -1 --stdout --from="Me <me@example.com>" >patch &&
1082 cat >expect <<-\EOF &&
1083 From: Me <me@example.com>
1085 From: A U Thor <author@example.com>
1088 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1089 test_cmp expect patch.head
1092 test_expect_success '--from uses committer ident' '
1093 git format-patch -1 --stdout --from >patch &&
1094 cat >expect <<-\EOF &&
1095 From: C O Mitter <committer@example.com>
1097 From: A U Thor <author@example.com>
1100 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1101 test_cmp expect patch.head
1104 test_expect_success '--from omits redundant in-body header' '
1105 git format-patch -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1106 cat >expect <<-\EOF &&
1107 From: A U Thor <author@example.com>
1110 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1111 test_cmp expect patch.head
1114 test_expect_success 'in-body headers trigger content encoding' '
1115 test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
1116 test_when_finished "git reset --hard HEAD^" &&
1117 git format-patch -1 --stdout --from >patch &&
1118 cat >expect <<-\EOF &&
1119 From: C O Mitter <committer@example.com>
1120 Content-Type: text/plain; charset=UTF-8
1122 From: éxötìc <author@example.com>
1125 sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" <patch >patch.head &&
1126 test_cmp expect patch.head
1129 append_signoff()
1131 C=$(git commit-tree HEAD^^{tree} -p HEAD) &&
1132 git format-patch --stdout --signoff $C^..$C >append_signoff.patch &&
1133 sed -n -e "1,/^---$/p" append_signoff.patch |
1134 egrep -n "^Subject|Sign|^$"
1137 test_expect_success 'signoff: commit with no body' '
1138 append_signoff </dev/null >actual &&
1139 cat <<\EOF | sed "s/EOL$//" >expected &&
1140 4:Subject: [PATCH] EOL
1142 9:Signed-off-by: C O Mitter <committer@example.com>
1144 test_cmp expected actual
1147 test_expect_success 'signoff: commit with only subject' '
1148 echo subject | append_signoff >actual &&
1149 cat >expected <<\EOF &&
1150 4:Subject: [PATCH] subject
1152 9:Signed-off-by: C O Mitter <committer@example.com>
1154 test_cmp expected actual
1157 test_expect_success 'signoff: commit with only subject that does not end with NL' '
1158 printf subject | append_signoff >actual &&
1159 cat >expected <<\EOF &&
1160 4:Subject: [PATCH] subject
1162 9:Signed-off-by: C O Mitter <committer@example.com>
1164 test_cmp expected actual
1167 test_expect_success 'signoff: no existing signoffs' '
1168 append_signoff <<\EOF >actual &&
1169 subject
1171 body
1173 cat >expected <<\EOF &&
1174 4:Subject: [PATCH] subject
1177 11:Signed-off-by: C O Mitter <committer@example.com>
1179 test_cmp expected actual
1182 test_expect_success 'signoff: no existing signoffs and no trailing NL' '
1183 printf "subject\n\nbody" | append_signoff >actual &&
1184 cat >expected <<\EOF &&
1185 4:Subject: [PATCH] subject
1188 11:Signed-off-by: C O Mitter <committer@example.com>
1190 test_cmp expected actual
1193 test_expect_success 'signoff: some random signoff' '
1194 append_signoff <<\EOF >actual &&
1195 subject
1197 body
1199 Signed-off-by: my@house
1201 cat >expected <<\EOF &&
1202 4:Subject: [PATCH] subject
1205 11:Signed-off-by: my@house
1206 12:Signed-off-by: C O Mitter <committer@example.com>
1208 test_cmp expected actual
1211 test_expect_success 'signoff: misc conforming footer elements' '
1212 append_signoff <<\EOF >actual &&
1213 subject
1215 body
1217 Signed-off-by: my@house
1218 (cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1219 Tested-by: Some One <someone@example.com>
1220 Bug: 1234
1222 cat >expected <<\EOF &&
1223 4:Subject: [PATCH] subject
1226 11:Signed-off-by: my@house
1227 15:Signed-off-by: C O Mitter <committer@example.com>
1229 test_cmp expected actual
1232 test_expect_success 'signoff: some random signoff-alike' '
1233 append_signoff <<\EOF >actual &&
1234 subject
1236 body
1237 Fooled-by-me: my@house
1239 cat >expected <<\EOF &&
1240 4:Subject: [PATCH] subject
1243 12:Signed-off-by: C O Mitter <committer@example.com>
1245 test_cmp expected actual
1248 test_expect_success 'signoff: not really a signoff' '
1249 append_signoff <<\EOF >actual &&
1250 subject
1252 I want to mention about Signed-off-by: here.
1254 cat >expected <<\EOF &&
1255 4:Subject: [PATCH] subject
1257 9:I want to mention about Signed-off-by: here.
1259 11:Signed-off-by: C O Mitter <committer@example.com>
1261 test_cmp expected actual
1264 test_expect_success 'signoff: not really a signoff (2)' '
1265 append_signoff <<\EOF >actual &&
1266 subject
1268 My unfortunate
1269 Signed-off-by: example happens to be wrapped here.
1271 cat >expected <<\EOF &&
1272 4:Subject: [PATCH] subject
1274 10:Signed-off-by: example happens to be wrapped here.
1276 12:Signed-off-by: C O Mitter <committer@example.com>
1278 test_cmp expected actual
1281 test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
1282 append_signoff <<\EOF >actual &&
1283 subject
1285 Signed-off-by: my@house
1286 Signed-off-by: your@house
1288 A lot of houses.
1290 cat >expected <<\EOF &&
1291 4:Subject: [PATCH] subject
1293 9:Signed-off-by: my@house
1294 10:Signed-off-by: your@house
1297 14:Signed-off-by: C O Mitter <committer@example.com>
1299 test_cmp expected actual
1302 test_expect_success 'signoff: the same signoff at the end' '
1303 append_signoff <<\EOF >actual &&
1304 subject
1306 body
1308 Signed-off-by: C O Mitter <committer@example.com>
1310 cat >expected <<\EOF &&
1311 4:Subject: [PATCH] subject
1314 11:Signed-off-by: C O Mitter <committer@example.com>
1316 test_cmp expected actual
1319 test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
1320 printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
1321 append_signoff >actual &&
1322 cat >expected <<\EOF &&
1323 4:Subject: [PATCH] subject
1325 9:Signed-off-by: C O Mitter <committer@example.com>
1327 test_cmp expected actual
1330 test_expect_success 'signoff: the same signoff NOT at the end' '
1331 append_signoff <<\EOF >actual &&
1332 subject
1334 body
1336 Signed-off-by: C O Mitter <committer@example.com>
1337 Signed-off-by: my@house
1339 cat >expected <<\EOF &&
1340 4:Subject: [PATCH] subject
1343 11:Signed-off-by: C O Mitter <committer@example.com>
1344 12:Signed-off-by: my@house
1346 test_cmp expected actual
1349 test_expect_success 'signoff: detect garbage in non-conforming footer' '
1350 append_signoff <<\EOF >actual &&
1351 subject
1353 body
1355 Tested-by: my@house
1356 Some Trash
1357 Signed-off-by: C O Mitter <committer@example.com>
1359 cat >expected <<\EOF &&
1360 4:Subject: [PATCH] subject
1363 13:Signed-off-by: C O Mitter <committer@example.com>
1365 15:Signed-off-by: C O Mitter <committer@example.com>
1367 test_cmp expected actual
1370 test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
1371 append_signoff <<\EOF >actual &&
1372 subject
1374 body
1376 Reviewed-id: Noone
1377 Tested-by: my@house
1378 Change-id: Ideadbeef
1379 Signed-off-by: C O Mitter <committer@example.com>
1380 Bug: 1234
1382 cat >expected <<\EOF &&
1383 4:Subject: [PATCH] subject
1386 14:Signed-off-by: C O Mitter <committer@example.com>
1388 test_cmp expected actual
1391 test_expect_success 'format patch ignores color.ui' '
1392 test_unconfig color.ui &&
1393 git format-patch --stdout -1 >expect &&
1394 test_config color.ui always &&
1395 git format-patch --stdout -1 >actual &&
1396 test_cmp expect actual
1399 test_expect_success 'cover letter using branch description (1)' '
1400 git checkout rebuild-1 &&
1401 test_config branch.rebuild-1.description hello &&
1402 git format-patch --stdout --cover-letter master >actual &&
1403 grep hello actual >/dev/null
1406 test_expect_success 'cover letter using branch description (2)' '
1407 git checkout rebuild-1 &&
1408 test_config branch.rebuild-1.description hello &&
1409 git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
1410 grep hello actual >/dev/null
1413 test_expect_success 'cover letter using branch description (3)' '
1414 git checkout rebuild-1 &&
1415 test_config branch.rebuild-1.description hello &&
1416 git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
1417 grep hello actual >/dev/null
1420 test_expect_success 'cover letter using branch description (4)' '
1421 git checkout rebuild-1 &&
1422 test_config branch.rebuild-1.description hello &&
1423 git format-patch --stdout --cover-letter master.. >actual &&
1424 grep hello actual >/dev/null
1427 test_expect_success 'cover letter using branch description (5)' '
1428 git checkout rebuild-1 &&
1429 test_config branch.rebuild-1.description hello &&
1430 git format-patch --stdout --cover-letter -2 HEAD >actual &&
1431 grep hello actual >/dev/null
1434 test_expect_success 'cover letter using branch description (6)' '
1435 git checkout rebuild-1 &&
1436 test_config branch.rebuild-1.description hello &&
1437 git format-patch --stdout --cover-letter -2 >actual &&
1438 grep hello actual >/dev/null
1441 test_expect_success 'cover letter with nothing' '
1442 git format-patch --stdout --cover-letter >actual &&
1443 test_line_count = 0 actual
1446 test_expect_success 'cover letter auto' '
1447 mkdir -p tmp &&
1448 test_when_finished "rm -rf tmp;
1449 git config --unset format.coverletter" &&
1451 git config format.coverletter auto &&
1452 git format-patch -o tmp -1 >list &&
1453 test_line_count = 1 list &&
1454 git format-patch -o tmp -2 >list &&
1455 test_line_count = 3 list
1458 test_expect_success 'cover letter auto user override' '
1459 mkdir -p tmp &&
1460 test_when_finished "rm -rf tmp;
1461 git config --unset format.coverletter" &&
1463 git config format.coverletter auto &&
1464 git format-patch -o tmp --cover-letter -1 >list &&
1465 test_line_count = 2 list &&
1466 git format-patch -o tmp --cover-letter -2 >list &&
1467 test_line_count = 3 list &&
1468 git format-patch -o tmp --no-cover-letter -1 >list &&
1469 test_line_count = 1 list &&
1470 git format-patch -o tmp --no-cover-letter -2 >list &&
1471 test_line_count = 2 list
1474 test_expect_success 'format-patch --zero-commit' '
1475 git format-patch --zero-commit --stdout v2..v1 >patch2 &&
1476 grep "^From " patch2 | sort | uniq >actual &&
1477 echo "From $_z40 Mon Sep 17 00:00:00 2001" >expect &&
1478 test_cmp expect actual
1481 test_expect_success 'From line has expected format' '
1482 git format-patch --stdout v2..v1 >patch2 &&
1483 grep "^From " patch2 >from &&
1484 grep "^From $_x40 Mon Sep 17 00:00:00 2001$" patch2 >filtered &&
1485 test_cmp from filtered
1488 test_expect_success 'format-patch format.outputDirectory option' '
1489 test_config format.outputDirectory patches &&
1490 rm -fr patches &&
1491 git format-patch master..side &&
1492 test $(git rev-list master..side | wc -l) -eq $(ls patches | wc -l)
1495 test_expect_success 'format-patch -o overrides format.outputDirectory' '
1496 test_config format.outputDirectory patches &&
1497 rm -fr patches patchset &&
1498 git format-patch master..side -o patchset &&
1499 test_path_is_missing patches &&
1500 test_path_is_dir patchset
1503 test_expect_success 'format-patch --base' '
1504 git checkout side &&
1505 git format-patch --stdout --base=HEAD~3 -1 >patch &&
1506 grep "^base-commit:" patch >actual &&
1507 grep "^prerequisite-patch-id:" patch >>actual &&
1508 echo "base-commit: $(git rev-parse HEAD~3)" >expected &&
1509 echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1510 echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1511 test_cmp expected actual
1514 test_expect_success 'format-patch --base errors out when base commit is in revision list' '
1515 test_must_fail git format-patch --base=HEAD -2 &&
1516 test_must_fail git format-patch --base=HEAD~1 -2 &&
1517 git format-patch --stdout --base=HEAD~2 -2 >patch &&
1518 grep "^base-commit:" patch >actual &&
1519 echo "base-commit: $(git rev-parse HEAD~2)" >expected &&
1520 test_cmp expected actual
1523 test_expect_success 'format-patch --base errors out when base commit is not ancestor of revision list' '
1524 # For history as below:
1526 # ---Q---P---Z---Y---*---X
1527 # \ /
1528 # ------------W
1530 # If "format-patch Z..X" is given, P and Z can not be specified as the base commit
1531 git checkout -b topic1 master &&
1532 git rev-parse HEAD >commit-id-base &&
1533 test_commit P &&
1534 git rev-parse HEAD >commit-id-P &&
1535 test_commit Z &&
1536 git rev-parse HEAD >commit-id-Z &&
1537 test_commit Y &&
1538 git checkout -b topic2 master &&
1539 test_commit W &&
1540 git merge topic1 &&
1541 test_commit X &&
1542 test_must_fail git format-patch --base=$(cat commit-id-P) -3 &&
1543 test_must_fail git format-patch --base=$(cat commit-id-Z) -3 &&
1544 git format-patch --stdout --base=$(cat commit-id-base) -3 >patch &&
1545 grep "^base-commit:" patch >actual &&
1546 echo "base-commit: $(cat commit-id-base)" >expected &&
1547 test_cmp expected actual
1550 test_expect_success 'format-patch --base=auto' '
1551 git checkout -b upstream master &&
1552 git checkout -b local upstream &&
1553 git branch --set-upstream-to=upstream &&
1554 test_commit N1 &&
1555 test_commit N2 &&
1556 git format-patch --stdout --base=auto -2 >patch &&
1557 grep "^base-commit:" patch >actual &&
1558 echo "base-commit: $(git rev-parse upstream)" >expected &&
1559 test_cmp expected actual
1562 test_expect_success 'format-patch errors out when history involves criss-cross' '
1563 # setup criss-cross history
1565 # B---M1---D
1566 # / \ /
1567 # A X
1568 # \ / \
1569 # C---M2---E
1571 git checkout master &&
1572 test_commit A &&
1573 git checkout -b xb master &&
1574 test_commit B &&
1575 git checkout -b xc master &&
1576 test_commit C &&
1577 git checkout -b xbc xb -- &&
1578 git merge xc &&
1579 git checkout -b xcb xc -- &&
1580 git branch --set-upstream-to=xbc &&
1581 git merge xb &&
1582 git checkout xbc &&
1583 test_commit D &&
1584 git checkout xcb &&
1585 test_commit E &&
1586 test_must_fail git format-patch --base=auto -1
1589 test_expect_success 'format-patch format.useAutoBaseoption' '
1590 test_when_finished "git config --unset format.useAutoBase" &&
1591 git checkout local &&
1592 git config format.useAutoBase true &&
1593 git format-patch --stdout -1 >patch &&
1594 grep "^base-commit:" patch >actual &&
1595 echo "base-commit: $(git rev-parse upstream)" >expected &&
1596 test_cmp expected actual
1599 test_expect_success 'format-patch --base overrides format.useAutoBase' '
1600 test_when_finished "git config --unset format.useAutoBase" &&
1601 git config format.useAutoBase true &&
1602 git format-patch --stdout --base=HEAD~1 -1 >patch &&
1603 grep "^base-commit:" patch >actual &&
1604 echo "base-commit: $(git rev-parse HEAD~1)" >expected &&
1605 test_cmp expected actual
1608 test_expect_success 'format-patch --pretty=mboxrd' '
1609 sp=" " &&
1610 cat >msg <<-INPUT_END &&
1611 mboxrd should escape the body
1613 From could trip up a loose mbox parser
1614 >From extra escape for reversibility
1615 >>From extra escape for reversibility 2
1616 from lower case not escaped
1617 Fromm bad speling not escaped
1618 From with leading space not escaped
1621 From
1622 From$sp
1623 From $sp
1624 From $sp
1625 INPUT_END
1627 cat >expect <<-INPUT_END &&
1628 >From could trip up a loose mbox parser
1629 >>From extra escape for reversibility
1630 >>>From extra escape for reversibility 2
1631 from lower case not escaped
1632 Fromm bad speling not escaped
1633 From with leading space not escaped
1636 From
1637 From
1638 From
1639 From
1640 INPUT_END
1642 C=$(git commit-tree HEAD^^{tree} -p HEAD <msg) &&
1643 git format-patch --pretty=mboxrd --stdout -1 $C~1..$C >patch &&
1644 git grep -h --no-index -A11 \
1645 "^>From could trip up a loose mbox parser" patch >actual &&
1646 test_cmp expect actual
1649 test_done