Merge branch 'km/t3000-retitle'
[git/raj.git] / t / t4014-format-patch.sh
blobb6e2fdbc4410f1b8b04586f12bb8806e85a10e8d
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 before=$(git hash-object file) &&
582 before=$(git rev-parse --short $before) &&
583 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
584 after=$(git hash-object file) &&
585 after=$(git rev-parse --short $after) &&
586 git update-index file &&
587 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." &&
588 git format-patch -o patches/ master..side &&
589 ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
592 test_expect_success 'failure to write cover-letter aborts gracefully' '
593 test_when_finished "rmdir 0000-cover-letter.patch" &&
594 mkdir 0000-cover-letter.patch &&
595 test_must_fail git format-patch --no-renames --cover-letter -1
598 test_expect_success 'cover-letter inherits diff options' '
599 git mv file foo &&
600 git commit -m foo &&
601 git format-patch --no-renames --cover-letter -1 &&
602 check_patch 0000-cover-letter.patch &&
603 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
604 git format-patch --cover-letter -1 -M &&
605 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
609 cat > expect << EOF
610 This is an excessively long subject line for a message due to the
611 habit some projects have of not having a short, one-line subject at
612 the start of the commit message, but rather sticking a whole
613 paragraph right at the start as the only thing in the commit
614 message. It had better not become the filename for the patch.
619 test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
621 git format-patch --cover-letter -2 &&
622 sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
623 test_cmp expect output
627 cat > expect << EOF
628 index $before..$after 100644
629 --- a/file
630 +++ b/file
631 @@ -13,4 +13,20 @@ C
639 test_expect_success 'format-patch respects -U' '
641 git format-patch -U4 -2 &&
642 sed -e "1,/^diff/d" -e "/^+5/q" \
643 <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
644 >output &&
645 test_cmp expect output
649 cat > expect << EOF
651 diff --git a/file b/file
652 index $before..$after 100644
653 --- a/file
654 +++ b/file
655 @@ -14,3 +14,19 @@ C
662 test_expect_success 'format-patch -p suppresses stat' '
664 git format-patch -p -2 &&
665 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
666 test_cmp expect output
670 test_expect_success 'format-patch from a subdirectory (1)' '
671 filename=$(
672 rm -rf sub &&
673 mkdir -p sub/dir &&
674 cd sub/dir &&
675 git format-patch -1
676 ) &&
677 case "$filename" in
679 ;; # ok
681 echo "Oops? $filename"
682 false
684 esac &&
685 test -f "$filename"
688 test_expect_success 'format-patch from a subdirectory (2)' '
689 filename=$(
690 rm -rf sub &&
691 mkdir -p sub/dir &&
692 cd sub/dir &&
693 git format-patch -1 -o ..
694 ) &&
695 case "$filename" in
696 ../0*)
697 ;; # ok
699 echo "Oops? $filename"
700 false
702 esac &&
703 basename=$(expr "$filename" : ".*/\(.*\)") &&
704 test -f "sub/$basename"
707 test_expect_success 'format-patch from a subdirectory (3)' '
708 rm -f 0* &&
709 filename=$(
710 rm -rf sub &&
711 mkdir -p sub/dir &&
712 cd sub/dir &&
713 git format-patch -1 -o "$TRASH_DIRECTORY"
714 ) &&
715 basename=$(expr "$filename" : ".*/\(.*\)") &&
716 test -f "$basename"
719 test_expect_success 'format-patch --in-reply-to' '
720 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
721 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
722 grep "^References: <baz@foo.bar>" patch8
725 test_expect_success 'format-patch --signoff' '
726 git format-patch -1 --signoff --stdout >out &&
727 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
730 test_expect_success 'format-patch --notes --signoff' '
731 git notes --ref test add -m "test message" HEAD &&
732 git format-patch -1 --signoff --stdout --notes=test >out &&
733 # Three dashes must come after S-o-b
734 ! sed "/^Signed-off-by: /q" out | grep "test message" &&
735 sed "1,/^Signed-off-by: /d" out | grep "test message" &&
736 # Notes message must come after three dashes
737 ! sed "/^---$/q" out | grep "test message" &&
738 sed "1,/^---$/d" out | grep "test message"
741 echo "fatal: --name-only does not make sense" > expect.name-only
742 echo "fatal: --name-status does not make sense" > expect.name-status
743 echo "fatal: --check does not make sense" > expect.check
745 test_expect_success 'options no longer allowed for format-patch' '
746 test_must_fail git format-patch --name-only 2> output &&
747 test_i18ncmp expect.name-only output &&
748 test_must_fail git format-patch --name-status 2> output &&
749 test_i18ncmp expect.name-status output &&
750 test_must_fail git format-patch --check 2> output &&
751 test_i18ncmp expect.check output'
753 test_expect_success 'format-patch --numstat should produce a patch' '
754 git format-patch --numstat --stdout master..side > output &&
755 test 5 = $(grep "^diff --git a/" output | wc -l)'
757 test_expect_success 'format-patch -- <path>' '
758 git format-patch master..side -- file 2>error &&
759 ! grep "Use .--" error
762 test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
763 git format-patch --ignore-if-in-upstream HEAD
766 git_version="$(git --version | sed "s/.* //")"
768 signature() {
769 printf "%s\n%s\n\n" "-- " "${1:-$git_version}"
772 test_expect_success 'format-patch default signature' '
773 git format-patch --stdout -1 | tail -n 3 >output &&
774 signature >expect &&
775 test_cmp expect output
778 test_expect_success 'format-patch --signature' '
779 git format-patch --stdout --signature="my sig" -1 | tail -n 3 >output &&
780 signature "my sig" >expect &&
781 test_cmp expect output
784 test_expect_success 'format-patch with format.signature config' '
785 git config format.signature "config sig" &&
786 git format-patch --stdout -1 >output &&
787 grep "config sig" output
790 test_expect_success 'format-patch --signature overrides format.signature' '
791 git config format.signature "config sig" &&
792 git format-patch --stdout --signature="overrides" -1 >output &&
793 ! grep "config sig" output &&
794 grep "overrides" output
797 test_expect_success 'format-patch --no-signature ignores format.signature' '
798 git config format.signature "config sig" &&
799 git format-patch --stdout --signature="my sig" --no-signature \
800 -1 >output &&
801 check_patch output &&
802 ! grep "config sig" output &&
803 ! grep "my sig" output &&
804 ! grep "^-- \$" output
807 test_expect_success 'format-patch --signature --cover-letter' '
808 git config --unset-all format.signature &&
809 git format-patch --stdout --signature="my sig" --cover-letter \
810 -1 >output &&
811 grep "my sig" output &&
812 test 2 = $(grep "my sig" output | wc -l)
815 test_expect_success 'format.signature="" suppresses signatures' '
816 git config format.signature "" &&
817 git format-patch --stdout -1 >output &&
818 check_patch output &&
819 ! grep "^-- \$" output
822 test_expect_success 'format-patch --no-signature suppresses signatures' '
823 git config --unset-all format.signature &&
824 git format-patch --stdout --no-signature -1 >output &&
825 check_patch output &&
826 ! grep "^-- \$" output
829 test_expect_success 'format-patch --signature="" suppresses signatures' '
830 git format-patch --stdout --signature="" -1 >output &&
831 check_patch output &&
832 ! grep "^-- \$" output
835 test_expect_success 'prepare mail-signature input' '
836 cat >mail-signature <<-\EOF
838 Test User <test.email@kernel.org>
839 http://git.kernel.org/cgit/git/git.git
841 git.kernel.org/?p=git/git.git;a=summary
846 test_expect_success '--signature-file=file works' '
847 git format-patch --stdout --signature-file=mail-signature -1 >output &&
848 check_patch output &&
849 sed -e "1,/^-- \$/d" <output >actual &&
851 cat mail-signature && echo
852 } >expect &&
853 test_cmp expect actual
856 test_expect_success 'format.signaturefile works' '
857 test_config format.signaturefile mail-signature &&
858 git format-patch --stdout -1 >output &&
859 check_patch output &&
860 sed -e "1,/^-- \$/d" <output >actual &&
862 cat mail-signature && echo
863 } >expect &&
864 test_cmp expect actual
867 test_expect_success '--no-signature suppresses format.signaturefile ' '
868 test_config format.signaturefile mail-signature &&
869 git format-patch --stdout --no-signature -1 >output &&
870 check_patch output &&
871 ! grep "^-- \$" output
874 test_expect_success '--signature-file overrides format.signaturefile' '
875 cat >other-mail-signature <<-\EOF &&
876 Use this other signature instead of mail-signature.
878 test_config format.signaturefile mail-signature &&
879 git format-patch --stdout \
880 --signature-file=other-mail-signature -1 >output &&
881 check_patch output &&
882 sed -e "1,/^-- \$/d" <output >actual &&
884 cat other-mail-signature && echo
885 } >expect &&
886 test_cmp expect actual
889 test_expect_success '--signature overrides format.signaturefile' '
890 test_config format.signaturefile mail-signature &&
891 git format-patch --stdout --signature="my sig" -1 >output &&
892 check_patch output &&
893 grep "my sig" output
896 test_expect_success TTY 'format-patch --stdout paginates' '
897 rm -f pager_used &&
898 test_terminal env GIT_PAGER="wc >pager_used" git format-patch --stdout --all &&
899 test_path_is_file pager_used
902 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
903 rm -f pager_used &&
904 test_terminal env GIT_PAGER="wc >pager_used" git --no-pager format-patch --stdout --all &&
905 test_terminal env GIT_PAGER="wc >pager_used" git -c "pager.format-patch=false" format-patch --stdout --all &&
906 test_path_is_missing pager_used &&
907 test_path_is_missing .git/pager_used
910 test_expect_success 'format-patch handles multi-line subjects' '
911 rm -rf patches/ &&
912 echo content >>file &&
913 for i in one two three; do echo $i; done >msg &&
914 git add file &&
915 git commit -F msg &&
916 git format-patch -o patches -1 &&
917 grep ^Subject: patches/0001-one.patch >actual &&
918 echo "Subject: [PATCH] one two three" >expect &&
919 test_cmp expect actual
922 test_expect_success 'format-patch handles multi-line encoded subjects' '
923 rm -rf patches/ &&
924 echo content >>file &&
925 for i in en två tre; do echo $i; done >msg &&
926 git add file &&
927 git commit -F msg &&
928 git format-patch -o patches -1 &&
929 grep ^Subject: patches/0001-en.patch >actual &&
930 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
931 test_cmp expect actual
934 M8="foo bar "
935 M64=$M8$M8$M8$M8$M8$M8$M8$M8
936 M512=$M64$M64$M64$M64$M64$M64$M64$M64
937 cat >expect <<'EOF'
938 Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
939 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
940 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
941 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
942 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
943 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
944 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
946 test_expect_success 'format-patch wraps extremely long subject (ascii)' '
947 echo content >>file &&
948 git add file &&
949 git commit -m "$M512" &&
950 git format-patch --stdout -1 >patch &&
951 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
952 test_cmp expect subject
955 M8="föö bar "
956 M64=$M8$M8$M8$M8$M8$M8$M8$M8
957 M512=$M64$M64$M64$M64$M64$M64$M64$M64
958 cat >expect <<'EOF'
959 Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
960 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
961 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
962 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
963 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
964 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
965 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
966 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
967 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
968 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
969 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
970 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
971 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
972 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
973 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
974 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
975 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
976 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
977 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
978 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
979 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
980 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
981 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
982 =?UTF-8?q?bar?=
984 test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
985 rm -rf patches/ &&
986 echo content >>file &&
987 git add file &&
988 git commit -m "$M512" &&
989 git format-patch --stdout -1 >patch &&
990 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
991 test_cmp expect subject
994 check_author() {
995 echo content >>file &&
996 git add file &&
997 GIT_AUTHOR_NAME=$1 git commit -m author-check &&
998 git format-patch --stdout -1 >patch &&
999 sed -n "/^From: /p; /^ /p; /^$/q" <patch >actual &&
1000 test_cmp expect actual
1003 cat >expect <<'EOF'
1004 From: "Foo B. Bar" <author@example.com>
1006 test_expect_success 'format-patch quotes dot in from-headers' '
1007 check_author "Foo B. Bar"
1010 cat >expect <<'EOF'
1011 From: "Foo \"The Baz\" Bar" <author@example.com>
1013 test_expect_success 'format-patch quotes double-quote in from-headers' '
1014 check_author "Foo \"The Baz\" Bar"
1017 cat >expect <<'EOF'
1018 From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
1020 test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
1021 check_author "Föo Bar"
1024 cat >expect <<'EOF'
1025 From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
1027 test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
1028 check_author "Föo B. Bar"
1031 cat >expect <<EOF
1032 From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
1033 <author@example.com>
1035 test_expect_success 'format-patch wraps moderately long from-header (ascii)' '
1036 check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
1039 cat >expect <<'EOF'
1040 From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1041 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1042 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
1044 test_expect_success 'format-patch wraps extremely long from-header (ascii)' '
1045 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"
1048 cat >expect <<'EOF'
1049 From: "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1050 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1051 Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
1053 test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
1054 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"
1057 cat >expect <<'EOF'
1058 From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
1059 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
1060 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
1061 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
1062 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
1064 test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
1065 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"
1068 cat >expect <<'EOF'
1069 Subject: header with . in it
1071 test_expect_success 'subject lines do not have 822 atom-quoting' '
1072 echo content >>file &&
1073 git add file &&
1074 git commit -m "header with . in it" &&
1075 git format-patch -k -1 --stdout >patch &&
1076 grep ^Subject: patch >actual &&
1077 test_cmp expect actual
1080 cat >expect <<'EOF'
1081 Subject: [PREFIX 1/1] header with . in it
1083 test_expect_success 'subject prefixes have space prepended' '
1084 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
1085 grep ^Subject: patch >actual &&
1086 test_cmp expect actual
1089 cat >expect <<'EOF'
1090 Subject: [1/1] header with . in it
1092 test_expect_success 'empty subject prefix does not have extra space' '
1093 git format-patch -n -1 --stdout --subject-prefix= >patch &&
1094 grep ^Subject: patch >actual &&
1095 test_cmp expect actual
1098 test_expect_success '--rfc' '
1099 cat >expect <<-\EOF &&
1100 Subject: [RFC PATCH 1/1] header with . in it
1102 git format-patch -n -1 --stdout --rfc >patch &&
1103 grep ^Subject: patch >actual &&
1104 test_cmp expect actual
1107 test_expect_success '--from=ident notices bogus ident' '
1108 test_must_fail git format-patch -1 --stdout --from=foo >patch
1111 test_expect_success '--from=ident replaces author' '
1112 git format-patch -1 --stdout --from="Me <me@example.com>" >patch &&
1113 cat >expect <<-\EOF &&
1114 From: Me <me@example.com>
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 '--from uses committer ident' '
1124 git format-patch -1 --stdout --from >patch &&
1125 cat >expect <<-\EOF &&
1126 From: C O Mitter <committer@example.com>
1128 From: A U Thor <author@example.com>
1131 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1132 test_cmp expect patch.head
1135 test_expect_success '--from omits redundant in-body header' '
1136 git format-patch -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1137 cat >expect <<-\EOF &&
1138 From: A U Thor <author@example.com>
1141 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1142 test_cmp expect patch.head
1145 test_expect_success 'in-body headers trigger content encoding' '
1146 test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
1147 test_when_finished "git reset --hard HEAD^" &&
1148 git format-patch -1 --stdout --from >patch &&
1149 cat >expect <<-\EOF &&
1150 From: C O Mitter <committer@example.com>
1151 Content-Type: text/plain; charset=UTF-8
1153 From: éxötìc <author@example.com>
1156 sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" <patch >patch.head &&
1157 test_cmp expect patch.head
1160 append_signoff()
1162 C=$(git commit-tree HEAD^^{tree} -p HEAD) &&
1163 git format-patch --stdout --signoff $C^..$C >append_signoff.patch &&
1164 sed -n -e "1,/^---$/p" append_signoff.patch |
1165 egrep -n "^Subject|Sign|^$"
1168 test_expect_success 'signoff: commit with no body' '
1169 append_signoff </dev/null >actual &&
1170 cat <<\EOF | sed "s/EOL$//" >expected &&
1171 4:Subject: [PATCH] EOL
1173 9:Signed-off-by: C O Mitter <committer@example.com>
1175 test_cmp expected actual
1178 test_expect_success 'signoff: commit with only subject' '
1179 echo subject | append_signoff >actual &&
1180 cat >expected <<\EOF &&
1181 4:Subject: [PATCH] subject
1183 9:Signed-off-by: C O Mitter <committer@example.com>
1185 test_cmp expected actual
1188 test_expect_success 'signoff: commit with only subject that does not end with NL' '
1189 printf subject | append_signoff >actual &&
1190 cat >expected <<\EOF &&
1191 4:Subject: [PATCH] subject
1193 9:Signed-off-by: C O Mitter <committer@example.com>
1195 test_cmp expected actual
1198 test_expect_success 'signoff: no existing signoffs' '
1199 append_signoff <<\EOF >actual &&
1200 subject
1202 body
1204 cat >expected <<\EOF &&
1205 4:Subject: [PATCH] subject
1208 11:Signed-off-by: C O Mitter <committer@example.com>
1210 test_cmp expected actual
1213 test_expect_success 'signoff: no existing signoffs and no trailing NL' '
1214 printf "subject\n\nbody" | append_signoff >actual &&
1215 cat >expected <<\EOF &&
1216 4:Subject: [PATCH] subject
1219 11:Signed-off-by: C O Mitter <committer@example.com>
1221 test_cmp expected actual
1224 test_expect_success 'signoff: some random signoff' '
1225 append_signoff <<\EOF >actual &&
1226 subject
1228 body
1230 Signed-off-by: my@house
1232 cat >expected <<\EOF &&
1233 4:Subject: [PATCH] subject
1236 11:Signed-off-by: my@house
1237 12:Signed-off-by: C O Mitter <committer@example.com>
1239 test_cmp expected actual
1242 test_expect_success 'signoff: misc conforming footer elements' '
1243 append_signoff <<\EOF >actual &&
1244 subject
1246 body
1248 Signed-off-by: my@house
1249 (cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1250 Tested-by: Some One <someone@example.com>
1251 Bug: 1234
1253 cat >expected <<\EOF &&
1254 4:Subject: [PATCH] subject
1257 11:Signed-off-by: my@house
1258 15:Signed-off-by: C O Mitter <committer@example.com>
1260 test_cmp expected actual
1263 test_expect_success 'signoff: some random signoff-alike' '
1264 append_signoff <<\EOF >actual &&
1265 subject
1267 body
1268 Fooled-by-me: my@house
1270 cat >expected <<\EOF &&
1271 4:Subject: [PATCH] subject
1274 12:Signed-off-by: C O Mitter <committer@example.com>
1276 test_cmp expected actual
1279 test_expect_success 'signoff: not really a signoff' '
1280 append_signoff <<\EOF >actual &&
1281 subject
1283 I want to mention about Signed-off-by: here.
1285 cat >expected <<\EOF &&
1286 4:Subject: [PATCH] subject
1288 9:I want to mention about Signed-off-by: here.
1290 11:Signed-off-by: C O Mitter <committer@example.com>
1292 test_cmp expected actual
1295 test_expect_success 'signoff: not really a signoff (2)' '
1296 append_signoff <<\EOF >actual &&
1297 subject
1299 My unfortunate
1300 Signed-off-by: example happens to be wrapped here.
1302 cat >expected <<\EOF &&
1303 4:Subject: [PATCH] subject
1305 10:Signed-off-by: example happens to be wrapped here.
1306 11:Signed-off-by: C O Mitter <committer@example.com>
1308 test_cmp expected actual
1311 test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
1312 append_signoff <<\EOF >actual &&
1313 subject
1315 Signed-off-by: my@house
1316 Signed-off-by: your@house
1318 A lot of houses.
1320 cat >expected <<\EOF &&
1321 4:Subject: [PATCH] subject
1323 9:Signed-off-by: my@house
1324 10:Signed-off-by: your@house
1327 14:Signed-off-by: C O Mitter <committer@example.com>
1329 test_cmp expected actual
1332 test_expect_success 'signoff: the same signoff at the end' '
1333 append_signoff <<\EOF >actual &&
1334 subject
1336 body
1338 Signed-off-by: C O Mitter <committer@example.com>
1340 cat >expected <<\EOF &&
1341 4:Subject: [PATCH] subject
1344 11:Signed-off-by: C O Mitter <committer@example.com>
1346 test_cmp expected actual
1349 test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
1350 printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
1351 append_signoff >actual &&
1352 cat >expected <<\EOF &&
1353 4:Subject: [PATCH] subject
1355 9:Signed-off-by: C O Mitter <committer@example.com>
1357 test_cmp expected actual
1360 test_expect_success 'signoff: the same signoff NOT at the end' '
1361 append_signoff <<\EOF >actual &&
1362 subject
1364 body
1366 Signed-off-by: C O Mitter <committer@example.com>
1367 Signed-off-by: my@house
1369 cat >expected <<\EOF &&
1370 4:Subject: [PATCH] subject
1373 11:Signed-off-by: C O Mitter <committer@example.com>
1374 12:Signed-off-by: my@house
1376 test_cmp expected actual
1379 test_expect_success 'signoff: tolerate garbage in conforming footer' '
1380 append_signoff <<\EOF >actual &&
1381 subject
1383 body
1385 Tested-by: my@house
1386 Some Trash
1387 Signed-off-by: C O Mitter <committer@example.com>
1389 cat >expected <<\EOF &&
1390 4:Subject: [PATCH] subject
1393 13:Signed-off-by: C O Mitter <committer@example.com>
1395 test_cmp expected actual
1398 test_expect_success 'signoff: respect trailer config' '
1399 append_signoff <<\EOF >actual &&
1400 subject
1402 Myfooter: x
1403 Some Trash
1405 cat >expected <<\EOF &&
1406 4:Subject: [PATCH] subject
1409 12:Signed-off-by: C O Mitter <committer@example.com>
1411 test_cmp expected actual &&
1413 test_config trailer.Myfooter.ifexists add &&
1414 append_signoff <<\EOF >actual &&
1415 subject
1417 Myfooter: x
1418 Some Trash
1420 cat >expected <<\EOF &&
1421 4:Subject: [PATCH] subject
1423 11:Signed-off-by: C O Mitter <committer@example.com>
1425 test_cmp expected actual
1428 test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
1429 append_signoff <<\EOF >actual &&
1430 subject
1432 body
1434 Reviewed-id: Noone
1435 Tested-by: my@house
1436 Change-id: Ideadbeef
1437 Signed-off-by: C O Mitter <committer@example.com>
1438 Bug: 1234
1440 cat >expected <<\EOF &&
1441 4:Subject: [PATCH] subject
1444 14:Signed-off-by: C O Mitter <committer@example.com>
1446 test_cmp expected actual
1449 test_expect_success 'format patch ignores color.ui' '
1450 test_unconfig color.ui &&
1451 git format-patch --stdout -1 >expect &&
1452 test_config color.ui always &&
1453 git format-patch --stdout -1 >actual &&
1454 test_cmp expect actual
1457 test_expect_success 'cover letter using branch description (1)' '
1458 git checkout rebuild-1 &&
1459 test_config branch.rebuild-1.description hello &&
1460 git format-patch --stdout --cover-letter master >actual &&
1461 grep hello actual >/dev/null
1464 test_expect_success 'cover letter using branch description (2)' '
1465 git checkout rebuild-1 &&
1466 test_config branch.rebuild-1.description hello &&
1467 git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
1468 grep hello actual >/dev/null
1471 test_expect_success 'cover letter using branch description (3)' '
1472 git checkout rebuild-1 &&
1473 test_config branch.rebuild-1.description hello &&
1474 git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
1475 grep hello actual >/dev/null
1478 test_expect_success 'cover letter using branch description (4)' '
1479 git checkout rebuild-1 &&
1480 test_config branch.rebuild-1.description hello &&
1481 git format-patch --stdout --cover-letter master.. >actual &&
1482 grep hello actual >/dev/null
1485 test_expect_success 'cover letter using branch description (5)' '
1486 git checkout rebuild-1 &&
1487 test_config branch.rebuild-1.description hello &&
1488 git format-patch --stdout --cover-letter -2 HEAD >actual &&
1489 grep hello actual >/dev/null
1492 test_expect_success 'cover letter using branch description (6)' '
1493 git checkout rebuild-1 &&
1494 test_config branch.rebuild-1.description hello &&
1495 git format-patch --stdout --cover-letter -2 >actual &&
1496 grep hello actual >/dev/null
1499 test_expect_success 'cover letter with nothing' '
1500 git format-patch --stdout --cover-letter >actual &&
1501 test_line_count = 0 actual
1504 test_expect_success 'cover letter auto' '
1505 mkdir -p tmp &&
1506 test_when_finished "rm -rf tmp;
1507 git config --unset format.coverletter" &&
1509 git config format.coverletter auto &&
1510 git format-patch -o tmp -1 >list &&
1511 test_line_count = 1 list &&
1512 git format-patch -o tmp -2 >list &&
1513 test_line_count = 3 list
1516 test_expect_success 'cover letter auto user override' '
1517 mkdir -p tmp &&
1518 test_when_finished "rm -rf tmp;
1519 git config --unset format.coverletter" &&
1521 git config format.coverletter auto &&
1522 git format-patch -o tmp --cover-letter -1 >list &&
1523 test_line_count = 2 list &&
1524 git format-patch -o tmp --cover-letter -2 >list &&
1525 test_line_count = 3 list &&
1526 git format-patch -o tmp --no-cover-letter -1 >list &&
1527 test_line_count = 1 list &&
1528 git format-patch -o tmp --no-cover-letter -2 >list &&
1529 test_line_count = 2 list
1532 test_expect_success 'format-patch --zero-commit' '
1533 git format-patch --zero-commit --stdout v2..v1 >patch2 &&
1534 grep "^From " patch2 | sort | uniq >actual &&
1535 echo "From $ZERO_OID Mon Sep 17 00:00:00 2001" >expect &&
1536 test_cmp expect actual
1539 test_expect_success 'From line has expected format' '
1540 git format-patch --stdout v2..v1 >patch2 &&
1541 grep "^From " patch2 >from &&
1542 grep "^From $OID_REGEX Mon Sep 17 00:00:00 2001$" patch2 >filtered &&
1543 test_cmp from filtered
1546 test_expect_success 'format-patch format.outputDirectory option' '
1547 test_config format.outputDirectory patches &&
1548 rm -fr patches &&
1549 git format-patch master..side &&
1550 test $(git rev-list master..side | wc -l) -eq $(ls patches | wc -l)
1553 test_expect_success 'format-patch -o overrides format.outputDirectory' '
1554 test_config format.outputDirectory patches &&
1555 rm -fr patches patchset &&
1556 git format-patch master..side -o patchset &&
1557 test_path_is_missing patches &&
1558 test_path_is_dir patchset
1561 test_expect_success 'format-patch --base' '
1562 git checkout side &&
1563 git format-patch --stdout --base=HEAD~3 -1 | tail -n 7 >actual1 &&
1564 git format-patch --stdout --base=HEAD~3 HEAD~.. | tail -n 7 >actual2 &&
1565 echo >expected &&
1566 echo "base-commit: $(git rev-parse HEAD~3)" >>expected &&
1567 echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1568 echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1569 signature >> expected &&
1570 test_cmp expected actual1 &&
1571 test_cmp expected actual2
1574 test_expect_success 'format-patch --base errors out when base commit is in revision list' '
1575 test_must_fail git format-patch --base=HEAD -2 &&
1576 test_must_fail git format-patch --base=HEAD~1 -2 &&
1577 git format-patch --stdout --base=HEAD~2 -2 >patch &&
1578 grep "^base-commit:" patch >actual &&
1579 echo "base-commit: $(git rev-parse HEAD~2)" >expected &&
1580 test_cmp expected actual
1583 test_expect_success 'format-patch --base errors out when base commit is not ancestor of revision list' '
1584 # For history as below:
1586 # ---Q---P---Z---Y---*---X
1587 # \ /
1588 # ------------W
1590 # If "format-patch Z..X" is given, P and Z can not be specified as the base commit
1591 git checkout -b topic1 master &&
1592 git rev-parse HEAD >commit-id-base &&
1593 test_commit P &&
1594 git rev-parse HEAD >commit-id-P &&
1595 test_commit Z &&
1596 git rev-parse HEAD >commit-id-Z &&
1597 test_commit Y &&
1598 git checkout -b topic2 master &&
1599 test_commit W &&
1600 git merge topic1 &&
1601 test_commit X &&
1602 test_must_fail git format-patch --base=$(cat commit-id-P) -3 &&
1603 test_must_fail git format-patch --base=$(cat commit-id-Z) -3 &&
1604 git format-patch --stdout --base=$(cat commit-id-base) -3 >patch &&
1605 grep "^base-commit:" patch >actual &&
1606 echo "base-commit: $(cat commit-id-base)" >expected &&
1607 test_cmp expected actual
1610 test_expect_success 'format-patch --base=auto' '
1611 git checkout -b upstream master &&
1612 git checkout -b local upstream &&
1613 git branch --set-upstream-to=upstream &&
1614 test_commit N1 &&
1615 test_commit N2 &&
1616 git format-patch --stdout --base=auto -2 >patch &&
1617 grep "^base-commit:" patch >actual &&
1618 echo "base-commit: $(git rev-parse upstream)" >expected &&
1619 test_cmp expected actual
1622 test_expect_success 'format-patch errors out when history involves criss-cross' '
1623 # setup criss-cross history
1625 # B---M1---D
1626 # / \ /
1627 # A X
1628 # \ / \
1629 # C---M2---E
1631 git checkout master &&
1632 test_commit A &&
1633 git checkout -b xb master &&
1634 test_commit B &&
1635 git checkout -b xc master &&
1636 test_commit C &&
1637 git checkout -b xbc xb -- &&
1638 git merge xc &&
1639 git checkout -b xcb xc -- &&
1640 git branch --set-upstream-to=xbc &&
1641 git merge xb &&
1642 git checkout xbc &&
1643 test_commit D &&
1644 git checkout xcb &&
1645 test_commit E &&
1646 test_must_fail git format-patch --base=auto -1
1649 test_expect_success 'format-patch format.useAutoBaseoption' '
1650 test_when_finished "git config --unset format.useAutoBase" &&
1651 git checkout local &&
1652 git config format.useAutoBase true &&
1653 git format-patch --stdout -1 >patch &&
1654 grep "^base-commit:" patch >actual &&
1655 echo "base-commit: $(git rev-parse upstream)" >expected &&
1656 test_cmp expected actual
1659 test_expect_success 'format-patch --base overrides format.useAutoBase' '
1660 test_when_finished "git config --unset format.useAutoBase" &&
1661 git config format.useAutoBase true &&
1662 git format-patch --stdout --base=HEAD~1 -1 >patch &&
1663 grep "^base-commit:" patch >actual &&
1664 echo "base-commit: $(git rev-parse HEAD~1)" >expected &&
1665 test_cmp expected actual
1668 test_expect_success 'format-patch --base with --attach' '
1669 git format-patch --attach=mimemime --stdout --base=HEAD~ -1 >patch &&
1670 sed -n -e "/^base-commit:/s/.*/1/p" -e "/^---*mimemime--$/s/.*/2/p" \
1671 patch >actual &&
1672 test_write_lines 1 2 >expect &&
1673 test_cmp expect actual
1675 test_expect_success 'format-patch --attach cover-letter only is non-multipart' '
1676 test_when_finished "rm -fr patches" &&
1677 git format-patch -o patches --cover-letter --attach=mimemime --base=HEAD~ -1 &&
1678 ! egrep "^--+mimemime" patches/0000*.patch &&
1679 egrep "^--+mimemime$" patches/0001*.patch >output &&
1680 test_line_count = 2 output &&
1681 egrep "^--+mimemime--$" patches/0001*.patch >output &&
1682 test_line_count = 1 output
1685 test_expect_success 'format-patch --pretty=mboxrd' '
1686 sp=" " &&
1687 cat >msg <<-INPUT_END &&
1688 mboxrd should escape the body
1690 From could trip up a loose mbox parser
1691 >From extra escape for reversibility
1692 >>From extra escape for reversibility 2
1693 from lower case not escaped
1694 Fromm bad speling not escaped
1695 From with leading space not escaped
1698 From
1699 From$sp
1700 From $sp
1701 From $sp
1702 INPUT_END
1704 cat >expect <<-INPUT_END &&
1705 >From could trip up a loose mbox parser
1706 >>From extra escape for reversibility
1707 >>>From extra escape for reversibility 2
1708 from lower case not escaped
1709 Fromm bad speling not escaped
1710 From with leading space not escaped
1713 From
1714 From
1715 From
1716 From
1717 INPUT_END
1719 C=$(git commit-tree HEAD^^{tree} -p HEAD <msg) &&
1720 git format-patch --pretty=mboxrd --stdout -1 $C~1..$C >patch &&
1721 git grep -h --no-index -A11 \
1722 "^>From could trip up a loose mbox parser" patch >actual &&
1723 test_cmp expect actual
1726 test_expect_success 'interdiff: setup' '
1727 git checkout -b boop master &&
1728 test_commit fnorp blorp &&
1729 test_commit fleep blorp
1732 test_expect_success 'interdiff: cover-letter' '
1733 sed "y/q/ /" >expect <<-\EOF &&
1734 +fleep
1737 git format-patch --cover-letter --interdiff=boop~2 -1 boop &&
1738 test_i18ngrep "^Interdiff:$" 0000-cover-letter.patch &&
1739 test_i18ngrep ! "^Interdiff:$" 0001-fleep.patch &&
1740 sed "1,/^@@ /d; /^-- $/q" <0000-cover-letter.patch >actual &&
1741 test_cmp expect actual
1744 test_expect_success 'interdiff: reroll-count' '
1745 git format-patch --cover-letter --interdiff=boop~2 -v2 -1 boop &&
1746 test_i18ngrep "^Interdiff ..* v1:$" v2-0000-cover-letter.patch
1749 test_expect_success 'interdiff: solo-patch' '
1750 cat >expect <<-\EOF &&
1751 +fleep
1754 git format-patch --interdiff=boop~2 -1 boop &&
1755 test_i18ngrep "^Interdiff:$" 0001-fleep.patch &&
1756 sed "1,/^ @@ /d; /^$/q" <0001-fleep.patch >actual &&
1757 test_cmp expect actual
1760 test_done