Merge branch 'js/commit-graph-chunk-table-fix'
[git.git] / t / t4014-format-patch.sh
blob909c743c134c5e18e0a80db3eae2dfb6e8210e6a
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 'cover-letter inherits diff options' '
593 git mv file foo &&
594 git commit -m foo &&
595 git format-patch --no-renames --cover-letter -1 &&
596 check_patch 0000-cover-letter.patch &&
597 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
598 git format-patch --cover-letter -1 -M &&
599 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
603 cat > expect << EOF
604 This is an excessively long subject line for a message due to the
605 habit some projects have of not having a short, one-line subject at
606 the start of the commit message, but rather sticking a whole
607 paragraph right at the start as the only thing in the commit
608 message. It had better not become the filename for the patch.
613 test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
615 git format-patch --cover-letter -2 &&
616 sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
617 test_cmp expect output
621 cat > expect << EOF
622 index $before..$after 100644
623 --- a/file
624 +++ b/file
625 @@ -13,4 +13,20 @@ C
633 test_expect_success 'format-patch respects -U' '
635 git format-patch -U4 -2 &&
636 sed -e "1,/^diff/d" -e "/^+5/q" \
637 <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
638 >output &&
639 test_cmp expect output
643 cat > expect << EOF
645 diff --git a/file b/file
646 index $before..$after 100644
647 --- a/file
648 +++ b/file
649 @@ -14,3 +14,19 @@ C
656 test_expect_success 'format-patch -p suppresses stat' '
658 git format-patch -p -2 &&
659 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
660 test_cmp expect output
664 test_expect_success 'format-patch from a subdirectory (1)' '
665 filename=$(
666 rm -rf sub &&
667 mkdir -p sub/dir &&
668 cd sub/dir &&
669 git format-patch -1
670 ) &&
671 case "$filename" in
673 ;; # ok
675 echo "Oops? $filename"
676 false
678 esac &&
679 test -f "$filename"
682 test_expect_success 'format-patch from a subdirectory (2)' '
683 filename=$(
684 rm -rf sub &&
685 mkdir -p sub/dir &&
686 cd sub/dir &&
687 git format-patch -1 -o ..
688 ) &&
689 case "$filename" in
690 ../0*)
691 ;; # ok
693 echo "Oops? $filename"
694 false
696 esac &&
697 basename=$(expr "$filename" : ".*/\(.*\)") &&
698 test -f "sub/$basename"
701 test_expect_success 'format-patch from a subdirectory (3)' '
702 rm -f 0* &&
703 filename=$(
704 rm -rf sub &&
705 mkdir -p sub/dir &&
706 cd sub/dir &&
707 git format-patch -1 -o "$TRASH_DIRECTORY"
708 ) &&
709 basename=$(expr "$filename" : ".*/\(.*\)") &&
710 test -f "$basename"
713 test_expect_success 'format-patch --in-reply-to' '
714 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
715 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
716 grep "^References: <baz@foo.bar>" patch8
719 test_expect_success 'format-patch --signoff' '
720 git format-patch -1 --signoff --stdout >out &&
721 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
724 test_expect_success 'format-patch --notes --signoff' '
725 git notes --ref test add -m "test message" HEAD &&
726 git format-patch -1 --signoff --stdout --notes=test >out &&
727 # Three dashes must come after S-o-b
728 ! sed "/^Signed-off-by: /q" out | grep "test message" &&
729 sed "1,/^Signed-off-by: /d" out | grep "test message" &&
730 # Notes message must come after three dashes
731 ! sed "/^---$/q" out | grep "test message" &&
732 sed "1,/^---$/d" out | grep "test message"
735 echo "fatal: --name-only does not make sense" > expect.name-only
736 echo "fatal: --name-status does not make sense" > expect.name-status
737 echo "fatal: --check does not make sense" > expect.check
739 test_expect_success 'options no longer allowed for format-patch' '
740 test_must_fail git format-patch --name-only 2> output &&
741 test_i18ncmp expect.name-only output &&
742 test_must_fail git format-patch --name-status 2> output &&
743 test_i18ncmp expect.name-status output &&
744 test_must_fail git format-patch --check 2> output &&
745 test_i18ncmp expect.check output'
747 test_expect_success 'format-patch --numstat should produce a patch' '
748 git format-patch --numstat --stdout master..side > output &&
749 test 5 = $(grep "^diff --git a/" output | wc -l)'
751 test_expect_success 'format-patch -- <path>' '
752 git format-patch master..side -- file 2>error &&
753 ! grep "Use .--" error
756 test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
757 git format-patch --ignore-if-in-upstream HEAD
760 git_version="$(git --version | sed "s/.* //")"
762 signature() {
763 printf "%s\n%s\n\n" "-- " "${1:-$git_version}"
766 test_expect_success 'format-patch default signature' '
767 git format-patch --stdout -1 | tail -n 3 >output &&
768 signature >expect &&
769 test_cmp expect output
772 test_expect_success 'format-patch --signature' '
773 git format-patch --stdout --signature="my sig" -1 | tail -n 3 >output &&
774 signature "my sig" >expect &&
775 test_cmp expect output
778 test_expect_success 'format-patch with format.signature config' '
779 git config format.signature "config sig" &&
780 git format-patch --stdout -1 >output &&
781 grep "config sig" output
784 test_expect_success 'format-patch --signature overrides format.signature' '
785 git config format.signature "config sig" &&
786 git format-patch --stdout --signature="overrides" -1 >output &&
787 ! grep "config sig" output &&
788 grep "overrides" output
791 test_expect_success 'format-patch --no-signature ignores format.signature' '
792 git config format.signature "config sig" &&
793 git format-patch --stdout --signature="my sig" --no-signature \
794 -1 >output &&
795 check_patch output &&
796 ! grep "config sig" output &&
797 ! grep "my sig" output &&
798 ! grep "^-- \$" output
801 test_expect_success 'format-patch --signature --cover-letter' '
802 git config --unset-all format.signature &&
803 git format-patch --stdout --signature="my sig" --cover-letter \
804 -1 >output &&
805 grep "my sig" output &&
806 test 2 = $(grep "my sig" output | wc -l)
809 test_expect_success 'format.signature="" suppresses signatures' '
810 git config format.signature "" &&
811 git format-patch --stdout -1 >output &&
812 check_patch output &&
813 ! grep "^-- \$" output
816 test_expect_success 'format-patch --no-signature suppresses signatures' '
817 git config --unset-all format.signature &&
818 git format-patch --stdout --no-signature -1 >output &&
819 check_patch output &&
820 ! grep "^-- \$" output
823 test_expect_success 'format-patch --signature="" suppresses signatures' '
824 git format-patch --stdout --signature="" -1 >output &&
825 check_patch output &&
826 ! grep "^-- \$" output
829 test_expect_success 'prepare mail-signature input' '
830 cat >mail-signature <<-\EOF
832 Test User <test.email@kernel.org>
833 http://git.kernel.org/cgit/git/git.git
835 git.kernel.org/?p=git/git.git;a=summary
840 test_expect_success '--signature-file=file works' '
841 git format-patch --stdout --signature-file=mail-signature -1 >output &&
842 check_patch output &&
843 sed -e "1,/^-- \$/d" <output >actual &&
845 cat mail-signature && echo
846 } >expect &&
847 test_cmp expect actual
850 test_expect_success 'format.signaturefile works' '
851 test_config format.signaturefile mail-signature &&
852 git format-patch --stdout -1 >output &&
853 check_patch output &&
854 sed -e "1,/^-- \$/d" <output >actual &&
856 cat mail-signature && echo
857 } >expect &&
858 test_cmp expect actual
861 test_expect_success '--no-signature suppresses format.signaturefile ' '
862 test_config format.signaturefile mail-signature &&
863 git format-patch --stdout --no-signature -1 >output &&
864 check_patch output &&
865 ! grep "^-- \$" output
868 test_expect_success '--signature-file overrides format.signaturefile' '
869 cat >other-mail-signature <<-\EOF &&
870 Use this other signature instead of mail-signature.
872 test_config format.signaturefile mail-signature &&
873 git format-patch --stdout \
874 --signature-file=other-mail-signature -1 >output &&
875 check_patch output &&
876 sed -e "1,/^-- \$/d" <output >actual &&
878 cat other-mail-signature && echo
879 } >expect &&
880 test_cmp expect actual
883 test_expect_success '--signature overrides format.signaturefile' '
884 test_config format.signaturefile mail-signature &&
885 git format-patch --stdout --signature="my sig" -1 >output &&
886 check_patch output &&
887 grep "my sig" output
890 test_expect_success TTY 'format-patch --stdout paginates' '
891 rm -f pager_used &&
892 test_terminal env GIT_PAGER="wc >pager_used" git format-patch --stdout --all &&
893 test_path_is_file pager_used
896 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
897 rm -f pager_used &&
898 test_terminal env GIT_PAGER="wc >pager_used" git --no-pager format-patch --stdout --all &&
899 test_terminal env GIT_PAGER="wc >pager_used" git -c "pager.format-patch=false" format-patch --stdout --all &&
900 test_path_is_missing pager_used &&
901 test_path_is_missing .git/pager_used
904 test_expect_success 'format-patch handles multi-line subjects' '
905 rm -rf patches/ &&
906 echo content >>file &&
907 for i in one two three; do echo $i; done >msg &&
908 git add file &&
909 git commit -F msg &&
910 git format-patch -o patches -1 &&
911 grep ^Subject: patches/0001-one.patch >actual &&
912 echo "Subject: [PATCH] one two three" >expect &&
913 test_cmp expect actual
916 test_expect_success 'format-patch handles multi-line encoded subjects' '
917 rm -rf patches/ &&
918 echo content >>file &&
919 for i in en två tre; do echo $i; done >msg &&
920 git add file &&
921 git commit -F msg &&
922 git format-patch -o patches -1 &&
923 grep ^Subject: patches/0001-en.patch >actual &&
924 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
925 test_cmp expect actual
928 M8="foo bar "
929 M64=$M8$M8$M8$M8$M8$M8$M8$M8
930 M512=$M64$M64$M64$M64$M64$M64$M64$M64
931 cat >expect <<'EOF'
932 Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
933 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
934 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
935 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
936 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
937 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
938 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
940 test_expect_success 'format-patch wraps extremely long subject (ascii)' '
941 echo content >>file &&
942 git add file &&
943 git commit -m "$M512" &&
944 git format-patch --stdout -1 >patch &&
945 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
946 test_cmp expect subject
949 M8="föö bar "
950 M64=$M8$M8$M8$M8$M8$M8$M8$M8
951 M512=$M64$M64$M64$M64$M64$M64$M64$M64
952 cat >expect <<'EOF'
953 Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
954 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
955 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
956 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
957 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
958 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
959 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
960 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
961 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
962 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
963 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
964 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
965 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
966 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
967 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
968 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
969 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
970 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
971 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
972 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
973 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
974 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
975 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
976 =?UTF-8?q?bar?=
978 test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
979 rm -rf patches/ &&
980 echo content >>file &&
981 git add file &&
982 git commit -m "$M512" &&
983 git format-patch --stdout -1 >patch &&
984 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
985 test_cmp expect subject
988 check_author() {
989 echo content >>file &&
990 git add file &&
991 GIT_AUTHOR_NAME=$1 git commit -m author-check &&
992 git format-patch --stdout -1 >patch &&
993 sed -n "/^From: /p; /^ /p; /^$/q" <patch >actual &&
994 test_cmp expect actual
997 cat >expect <<'EOF'
998 From: "Foo B. Bar" <author@example.com>
1000 test_expect_success 'format-patch quotes dot in from-headers' '
1001 check_author "Foo B. Bar"
1004 cat >expect <<'EOF'
1005 From: "Foo \"The Baz\" Bar" <author@example.com>
1007 test_expect_success 'format-patch quotes double-quote in from-headers' '
1008 check_author "Foo \"The Baz\" Bar"
1011 cat >expect <<'EOF'
1012 From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
1014 test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
1015 check_author "Föo Bar"
1018 cat >expect <<'EOF'
1019 From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
1021 test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
1022 check_author "Föo B. Bar"
1025 cat >expect <<EOF
1026 From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
1027 <author@example.com>
1029 test_expect_success 'format-patch wraps moderately long from-header (ascii)' '
1030 check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
1033 cat >expect <<'EOF'
1034 From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1035 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1036 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
1038 test_expect_success 'format-patch wraps extremely long from-header (ascii)' '
1039 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"
1042 cat >expect <<'EOF'
1043 From: "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1044 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1045 Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
1047 test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
1048 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"
1051 cat >expect <<'EOF'
1052 From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
1053 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
1054 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
1055 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
1056 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
1058 test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
1059 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"
1062 cat >expect <<'EOF'
1063 Subject: header with . in it
1065 test_expect_success 'subject lines do not have 822 atom-quoting' '
1066 echo content >>file &&
1067 git add file &&
1068 git commit -m "header with . in it" &&
1069 git format-patch -k -1 --stdout >patch &&
1070 grep ^Subject: patch >actual &&
1071 test_cmp expect actual
1074 cat >expect <<'EOF'
1075 Subject: [PREFIX 1/1] header with . in it
1077 test_expect_success 'subject prefixes have space prepended' '
1078 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
1079 grep ^Subject: patch >actual &&
1080 test_cmp expect actual
1083 cat >expect <<'EOF'
1084 Subject: [1/1] header with . in it
1086 test_expect_success 'empty subject prefix does not have extra space' '
1087 git format-patch -n -1 --stdout --subject-prefix= >patch &&
1088 grep ^Subject: patch >actual &&
1089 test_cmp expect actual
1092 test_expect_success '--rfc' '
1093 cat >expect <<-\EOF &&
1094 Subject: [RFC PATCH 1/1] header with . in it
1096 git format-patch -n -1 --stdout --rfc >patch &&
1097 grep ^Subject: patch >actual &&
1098 test_cmp expect actual
1101 test_expect_success '--from=ident notices bogus ident' '
1102 test_must_fail git format-patch -1 --stdout --from=foo >patch
1105 test_expect_success '--from=ident replaces author' '
1106 git format-patch -1 --stdout --from="Me <me@example.com>" >patch &&
1107 cat >expect <<-\EOF &&
1108 From: Me <me@example.com>
1110 From: A U Thor <author@example.com>
1113 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1114 test_cmp expect patch.head
1117 test_expect_success '--from uses committer ident' '
1118 git format-patch -1 --stdout --from >patch &&
1119 cat >expect <<-\EOF &&
1120 From: C O Mitter <committer@example.com>
1122 From: A U Thor <author@example.com>
1125 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1126 test_cmp expect patch.head
1129 test_expect_success '--from omits redundant in-body header' '
1130 git format-patch -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1131 cat >expect <<-\EOF &&
1132 From: A U Thor <author@example.com>
1135 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1136 test_cmp expect patch.head
1139 test_expect_success 'in-body headers trigger content encoding' '
1140 test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
1141 test_when_finished "git reset --hard HEAD^" &&
1142 git format-patch -1 --stdout --from >patch &&
1143 cat >expect <<-\EOF &&
1144 From: C O Mitter <committer@example.com>
1145 Content-Type: text/plain; charset=UTF-8
1147 From: éxötìc <author@example.com>
1150 sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" <patch >patch.head &&
1151 test_cmp expect patch.head
1154 append_signoff()
1156 C=$(git commit-tree HEAD^^{tree} -p HEAD) &&
1157 git format-patch --stdout --signoff $C^..$C >append_signoff.patch &&
1158 sed -n -e "1,/^---$/p" append_signoff.patch |
1159 egrep -n "^Subject|Sign|^$"
1162 test_expect_success 'signoff: commit with no body' '
1163 append_signoff </dev/null >actual &&
1164 cat <<\EOF | sed "s/EOL$//" >expected &&
1165 4:Subject: [PATCH] EOL
1167 9:Signed-off-by: C O Mitter <committer@example.com>
1169 test_cmp expected actual
1172 test_expect_success 'signoff: commit with only subject' '
1173 echo subject | append_signoff >actual &&
1174 cat >expected <<\EOF &&
1175 4:Subject: [PATCH] subject
1177 9:Signed-off-by: C O Mitter <committer@example.com>
1179 test_cmp expected actual
1182 test_expect_success 'signoff: commit with only subject that does not end with NL' '
1183 printf subject | append_signoff >actual &&
1184 cat >expected <<\EOF &&
1185 4:Subject: [PATCH] subject
1187 9:Signed-off-by: C O Mitter <committer@example.com>
1189 test_cmp expected actual
1192 test_expect_success 'signoff: no existing signoffs' '
1193 append_signoff <<\EOF >actual &&
1194 subject
1196 body
1198 cat >expected <<\EOF &&
1199 4:Subject: [PATCH] subject
1202 11:Signed-off-by: C O Mitter <committer@example.com>
1204 test_cmp expected actual
1207 test_expect_success 'signoff: no existing signoffs and no trailing NL' '
1208 printf "subject\n\nbody" | append_signoff >actual &&
1209 cat >expected <<\EOF &&
1210 4:Subject: [PATCH] subject
1213 11:Signed-off-by: C O Mitter <committer@example.com>
1215 test_cmp expected actual
1218 test_expect_success 'signoff: some random signoff' '
1219 append_signoff <<\EOF >actual &&
1220 subject
1222 body
1224 Signed-off-by: my@house
1226 cat >expected <<\EOF &&
1227 4:Subject: [PATCH] subject
1230 11:Signed-off-by: my@house
1231 12:Signed-off-by: C O Mitter <committer@example.com>
1233 test_cmp expected actual
1236 test_expect_success 'signoff: misc conforming footer elements' '
1237 append_signoff <<\EOF >actual &&
1238 subject
1240 body
1242 Signed-off-by: my@house
1243 (cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1244 Tested-by: Some One <someone@example.com>
1245 Bug: 1234
1247 cat >expected <<\EOF &&
1248 4:Subject: [PATCH] subject
1251 11:Signed-off-by: my@house
1252 15:Signed-off-by: C O Mitter <committer@example.com>
1254 test_cmp expected actual
1257 test_expect_success 'signoff: some random signoff-alike' '
1258 append_signoff <<\EOF >actual &&
1259 subject
1261 body
1262 Fooled-by-me: my@house
1264 cat >expected <<\EOF &&
1265 4:Subject: [PATCH] subject
1268 12:Signed-off-by: C O Mitter <committer@example.com>
1270 test_cmp expected actual
1273 test_expect_success 'signoff: not really a signoff' '
1274 append_signoff <<\EOF >actual &&
1275 subject
1277 I want to mention about Signed-off-by: here.
1279 cat >expected <<\EOF &&
1280 4:Subject: [PATCH] subject
1282 9:I want to mention about Signed-off-by: here.
1284 11:Signed-off-by: C O Mitter <committer@example.com>
1286 test_cmp expected actual
1289 test_expect_success 'signoff: not really a signoff (2)' '
1290 append_signoff <<\EOF >actual &&
1291 subject
1293 My unfortunate
1294 Signed-off-by: example happens to be wrapped here.
1296 cat >expected <<\EOF &&
1297 4:Subject: [PATCH] subject
1299 10:Signed-off-by: example happens to be wrapped here.
1300 11:Signed-off-by: C O Mitter <committer@example.com>
1302 test_cmp expected actual
1305 test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
1306 append_signoff <<\EOF >actual &&
1307 subject
1309 Signed-off-by: my@house
1310 Signed-off-by: your@house
1312 A lot of houses.
1314 cat >expected <<\EOF &&
1315 4:Subject: [PATCH] subject
1317 9:Signed-off-by: my@house
1318 10:Signed-off-by: your@house
1321 14:Signed-off-by: C O Mitter <committer@example.com>
1323 test_cmp expected actual
1326 test_expect_success 'signoff: the same signoff at the end' '
1327 append_signoff <<\EOF >actual &&
1328 subject
1330 body
1332 Signed-off-by: C O Mitter <committer@example.com>
1334 cat >expected <<\EOF &&
1335 4:Subject: [PATCH] subject
1338 11:Signed-off-by: C O Mitter <committer@example.com>
1340 test_cmp expected actual
1343 test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
1344 printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
1345 append_signoff >actual &&
1346 cat >expected <<\EOF &&
1347 4:Subject: [PATCH] subject
1349 9:Signed-off-by: C O Mitter <committer@example.com>
1351 test_cmp expected actual
1354 test_expect_success 'signoff: the same signoff NOT at the end' '
1355 append_signoff <<\EOF >actual &&
1356 subject
1358 body
1360 Signed-off-by: C O Mitter <committer@example.com>
1361 Signed-off-by: my@house
1363 cat >expected <<\EOF &&
1364 4:Subject: [PATCH] subject
1367 11:Signed-off-by: C O Mitter <committer@example.com>
1368 12:Signed-off-by: my@house
1370 test_cmp expected actual
1373 test_expect_success 'signoff: tolerate garbage in conforming footer' '
1374 append_signoff <<\EOF >actual &&
1375 subject
1377 body
1379 Tested-by: my@house
1380 Some Trash
1381 Signed-off-by: C O Mitter <committer@example.com>
1383 cat >expected <<\EOF &&
1384 4:Subject: [PATCH] subject
1387 13:Signed-off-by: C O Mitter <committer@example.com>
1389 test_cmp expected actual
1392 test_expect_success 'signoff: respect trailer config' '
1393 append_signoff <<\EOF >actual &&
1394 subject
1396 Myfooter: x
1397 Some Trash
1399 cat >expected <<\EOF &&
1400 4:Subject: [PATCH] subject
1403 12:Signed-off-by: C O Mitter <committer@example.com>
1405 test_cmp expected actual &&
1407 test_config trailer.Myfooter.ifexists add &&
1408 append_signoff <<\EOF >actual &&
1409 subject
1411 Myfooter: x
1412 Some Trash
1414 cat >expected <<\EOF &&
1415 4:Subject: [PATCH] subject
1417 11:Signed-off-by: C O Mitter <committer@example.com>
1419 test_cmp expected actual
1422 test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
1423 append_signoff <<\EOF >actual &&
1424 subject
1426 body
1428 Reviewed-id: Noone
1429 Tested-by: my@house
1430 Change-id: Ideadbeef
1431 Signed-off-by: C O Mitter <committer@example.com>
1432 Bug: 1234
1434 cat >expected <<\EOF &&
1435 4:Subject: [PATCH] subject
1438 14:Signed-off-by: C O Mitter <committer@example.com>
1440 test_cmp expected actual
1443 test_expect_success 'format patch ignores color.ui' '
1444 test_unconfig color.ui &&
1445 git format-patch --stdout -1 >expect &&
1446 test_config color.ui always &&
1447 git format-patch --stdout -1 >actual &&
1448 test_cmp expect actual
1451 test_expect_success 'cover letter using branch description (1)' '
1452 git checkout rebuild-1 &&
1453 test_config branch.rebuild-1.description hello &&
1454 git format-patch --stdout --cover-letter master >actual &&
1455 grep hello actual >/dev/null
1458 test_expect_success 'cover letter using branch description (2)' '
1459 git checkout rebuild-1 &&
1460 test_config branch.rebuild-1.description hello &&
1461 git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
1462 grep hello actual >/dev/null
1465 test_expect_success 'cover letter using branch description (3)' '
1466 git checkout rebuild-1 &&
1467 test_config branch.rebuild-1.description hello &&
1468 git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
1469 grep hello actual >/dev/null
1472 test_expect_success 'cover letter using branch description (4)' '
1473 git checkout rebuild-1 &&
1474 test_config branch.rebuild-1.description hello &&
1475 git format-patch --stdout --cover-letter master.. >actual &&
1476 grep hello actual >/dev/null
1479 test_expect_success 'cover letter using branch description (5)' '
1480 git checkout rebuild-1 &&
1481 test_config branch.rebuild-1.description hello &&
1482 git format-patch --stdout --cover-letter -2 HEAD >actual &&
1483 grep hello actual >/dev/null
1486 test_expect_success 'cover letter using branch description (6)' '
1487 git checkout rebuild-1 &&
1488 test_config branch.rebuild-1.description hello &&
1489 git format-patch --stdout --cover-letter -2 >actual &&
1490 grep hello actual >/dev/null
1493 test_expect_success 'cover letter with nothing' '
1494 git format-patch --stdout --cover-letter >actual &&
1495 test_line_count = 0 actual
1498 test_expect_success 'cover letter auto' '
1499 mkdir -p tmp &&
1500 test_when_finished "rm -rf tmp;
1501 git config --unset format.coverletter" &&
1503 git config format.coverletter auto &&
1504 git format-patch -o tmp -1 >list &&
1505 test_line_count = 1 list &&
1506 git format-patch -o tmp -2 >list &&
1507 test_line_count = 3 list
1510 test_expect_success 'cover letter auto user override' '
1511 mkdir -p tmp &&
1512 test_when_finished "rm -rf tmp;
1513 git config --unset format.coverletter" &&
1515 git config format.coverletter auto &&
1516 git format-patch -o tmp --cover-letter -1 >list &&
1517 test_line_count = 2 list &&
1518 git format-patch -o tmp --cover-letter -2 >list &&
1519 test_line_count = 3 list &&
1520 git format-patch -o tmp --no-cover-letter -1 >list &&
1521 test_line_count = 1 list &&
1522 git format-patch -o tmp --no-cover-letter -2 >list &&
1523 test_line_count = 2 list
1526 test_expect_success 'format-patch --zero-commit' '
1527 git format-patch --zero-commit --stdout v2..v1 >patch2 &&
1528 grep "^From " patch2 | sort | uniq >actual &&
1529 echo "From $ZERO_OID Mon Sep 17 00:00:00 2001" >expect &&
1530 test_cmp expect actual
1533 test_expect_success 'From line has expected format' '
1534 git format-patch --stdout v2..v1 >patch2 &&
1535 grep "^From " patch2 >from &&
1536 grep "^From $OID_REGEX Mon Sep 17 00:00:00 2001$" patch2 >filtered &&
1537 test_cmp from filtered
1540 test_expect_success 'format-patch format.outputDirectory option' '
1541 test_config format.outputDirectory patches &&
1542 rm -fr patches &&
1543 git format-patch master..side &&
1544 test $(git rev-list master..side | wc -l) -eq $(ls patches | wc -l)
1547 test_expect_success 'format-patch -o overrides format.outputDirectory' '
1548 test_config format.outputDirectory patches &&
1549 rm -fr patches patchset &&
1550 git format-patch master..side -o patchset &&
1551 test_path_is_missing patches &&
1552 test_path_is_dir patchset
1555 test_expect_success 'format-patch --base' '
1556 git checkout side &&
1557 git format-patch --stdout --base=HEAD~3 -1 | tail -n 7 >actual1 &&
1558 git format-patch --stdout --base=HEAD~3 HEAD~.. | tail -n 7 >actual2 &&
1559 echo >expected &&
1560 echo "base-commit: $(git rev-parse HEAD~3)" >>expected &&
1561 echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1562 echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1563 signature >> expected &&
1564 test_cmp expected actual1 &&
1565 test_cmp expected actual2
1568 test_expect_success 'format-patch --base errors out when base commit is in revision list' '
1569 test_must_fail git format-patch --base=HEAD -2 &&
1570 test_must_fail git format-patch --base=HEAD~1 -2 &&
1571 git format-patch --stdout --base=HEAD~2 -2 >patch &&
1572 grep "^base-commit:" patch >actual &&
1573 echo "base-commit: $(git rev-parse HEAD~2)" >expected &&
1574 test_cmp expected actual
1577 test_expect_success 'format-patch --base errors out when base commit is not ancestor of revision list' '
1578 # For history as below:
1580 # ---Q---P---Z---Y---*---X
1581 # \ /
1582 # ------------W
1584 # If "format-patch Z..X" is given, P and Z can not be specified as the base commit
1585 git checkout -b topic1 master &&
1586 git rev-parse HEAD >commit-id-base &&
1587 test_commit P &&
1588 git rev-parse HEAD >commit-id-P &&
1589 test_commit Z &&
1590 git rev-parse HEAD >commit-id-Z &&
1591 test_commit Y &&
1592 git checkout -b topic2 master &&
1593 test_commit W &&
1594 git merge topic1 &&
1595 test_commit X &&
1596 test_must_fail git format-patch --base=$(cat commit-id-P) -3 &&
1597 test_must_fail git format-patch --base=$(cat commit-id-Z) -3 &&
1598 git format-patch --stdout --base=$(cat commit-id-base) -3 >patch &&
1599 grep "^base-commit:" patch >actual &&
1600 echo "base-commit: $(cat commit-id-base)" >expected &&
1601 test_cmp expected actual
1604 test_expect_success 'format-patch --base=auto' '
1605 git checkout -b upstream master &&
1606 git checkout -b local upstream &&
1607 git branch --set-upstream-to=upstream &&
1608 test_commit N1 &&
1609 test_commit N2 &&
1610 git format-patch --stdout --base=auto -2 >patch &&
1611 grep "^base-commit:" patch >actual &&
1612 echo "base-commit: $(git rev-parse upstream)" >expected &&
1613 test_cmp expected actual
1616 test_expect_success 'format-patch errors out when history involves criss-cross' '
1617 # setup criss-cross history
1619 # B---M1---D
1620 # / \ /
1621 # A X
1622 # \ / \
1623 # C---M2---E
1625 git checkout master &&
1626 test_commit A &&
1627 git checkout -b xb master &&
1628 test_commit B &&
1629 git checkout -b xc master &&
1630 test_commit C &&
1631 git checkout -b xbc xb -- &&
1632 git merge xc &&
1633 git checkout -b xcb xc -- &&
1634 git branch --set-upstream-to=xbc &&
1635 git merge xb &&
1636 git checkout xbc &&
1637 test_commit D &&
1638 git checkout xcb &&
1639 test_commit E &&
1640 test_must_fail git format-patch --base=auto -1
1643 test_expect_success 'format-patch format.useAutoBaseoption' '
1644 test_when_finished "git config --unset format.useAutoBase" &&
1645 git checkout local &&
1646 git config format.useAutoBase true &&
1647 git format-patch --stdout -1 >patch &&
1648 grep "^base-commit:" patch >actual &&
1649 echo "base-commit: $(git rev-parse upstream)" >expected &&
1650 test_cmp expected actual
1653 test_expect_success 'format-patch --base overrides format.useAutoBase' '
1654 test_when_finished "git config --unset format.useAutoBase" &&
1655 git config format.useAutoBase true &&
1656 git format-patch --stdout --base=HEAD~1 -1 >patch &&
1657 grep "^base-commit:" patch >actual &&
1658 echo "base-commit: $(git rev-parse HEAD~1)" >expected &&
1659 test_cmp expected actual
1662 test_expect_success 'format-patch --base with --attach' '
1663 git format-patch --attach=mimemime --stdout --base=HEAD~ -1 >patch &&
1664 sed -n -e "/^base-commit:/s/.*/1/p" -e "/^---*mimemime--$/s/.*/2/p" \
1665 patch >actual &&
1666 test_write_lines 1 2 >expect &&
1667 test_cmp expect actual
1669 test_expect_success 'format-patch --attach cover-letter only is non-multipart' '
1670 test_when_finished "rm -fr patches" &&
1671 git format-patch -o patches --cover-letter --attach=mimemime --base=HEAD~ -1 &&
1672 ! egrep "^--+mimemime" patches/0000*.patch &&
1673 egrep "^--+mimemime$" patches/0001*.patch >output &&
1674 test_line_count = 2 output &&
1675 egrep "^--+mimemime--$" patches/0001*.patch >output &&
1676 test_line_count = 1 output
1679 test_expect_success 'format-patch --pretty=mboxrd' '
1680 sp=" " &&
1681 cat >msg <<-INPUT_END &&
1682 mboxrd should escape the body
1684 From could trip up a loose mbox parser
1685 >From extra escape for reversibility
1686 >>From extra escape for reversibility 2
1687 from lower case not escaped
1688 Fromm bad speling not escaped
1689 From with leading space not escaped
1692 From
1693 From$sp
1694 From $sp
1695 From $sp
1696 INPUT_END
1698 cat >expect <<-INPUT_END &&
1699 >From could trip up a loose mbox parser
1700 >>From extra escape for reversibility
1701 >>>From extra escape for reversibility 2
1702 from lower case not escaped
1703 Fromm bad speling not escaped
1704 From with leading space not escaped
1707 From
1708 From
1709 From
1710 From
1711 INPUT_END
1713 C=$(git commit-tree HEAD^^{tree} -p HEAD <msg) &&
1714 git format-patch --pretty=mboxrd --stdout -1 $C~1..$C >patch &&
1715 git grep -h --no-index -A11 \
1716 "^>From could trip up a loose mbox parser" patch >actual &&
1717 test_cmp expect actual
1720 test_expect_success 'interdiff: setup' '
1721 git checkout -b boop master &&
1722 test_commit fnorp blorp &&
1723 test_commit fleep blorp
1726 test_expect_success 'interdiff: cover-letter' '
1727 sed "y/q/ /" >expect <<-\EOF &&
1728 +fleep
1731 git format-patch --cover-letter --interdiff=boop~2 -1 boop &&
1732 test_i18ngrep "^Interdiff:$" 0000-cover-letter.patch &&
1733 test_i18ngrep ! "^Interdiff:$" 0001-fleep.patch &&
1734 sed "1,/^@@ /d; /^-- $/q" <0000-cover-letter.patch >actual &&
1735 test_cmp expect actual
1738 test_expect_success 'interdiff: reroll-count' '
1739 git format-patch --cover-letter --interdiff=boop~2 -v2 -1 boop &&
1740 test_i18ngrep "^Interdiff ..* v1:$" v2-0000-cover-letter.patch
1743 test_expect_success 'interdiff: solo-patch' '
1744 cat >expect <<-\EOF &&
1745 +fleep
1748 git format-patch --interdiff=boop~2 -1 boop &&
1749 test_i18ngrep "^Interdiff:$" 0001-fleep.patch &&
1750 sed "1,/^ @@ /d; /^$/q" <0001-fleep.patch >actual &&
1751 test_cmp expect actual
1754 test_done