grep: avoid leak of chartables in PCRE2
[git.git] / t / t4014-format-patch.sh
blobca7debf1d4c0b5f73301b2f8a35490b77c167a61
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" &&
41 git checkout side &&
42 git checkout -b patchid &&
43 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file2 &&
44 for i in 1 2 3 A 4 B C 7 8 9 10 D E F 5 6; do echo "$i"; done >file3 &&
45 for i in 8 9 10; do echo "$i"; done >file &&
46 git add file file2 file3 &&
47 test_tick &&
48 git commit -m "patchid 1" &&
49 for i in 4 A B 7 8 9 10; do echo "$i"; done >file2 &&
50 for i in 8 9 10 5 6; do echo "$i"; done >file3 &&
51 git add file2 file3 &&
52 test_tick &&
53 git commit -m "patchid 2" &&
54 for i in 10 5 6; do echo "$i"; done >file &&
55 git add file &&
56 test_tick &&
57 git commit -m "patchid 3" &&
59 git checkout master
62 test_expect_success "format-patch --ignore-if-in-upstream" '
64 git format-patch --stdout master..side >patch0 &&
65 cnt=$(grep "^From " patch0 | wc -l) &&
66 test $cnt = 3
70 test_expect_success "format-patch --ignore-if-in-upstream" '
72 git format-patch --stdout \
73 --ignore-if-in-upstream master..side >patch1 &&
74 cnt=$(grep "^From " patch1 | wc -l) &&
75 test $cnt = 2
79 test_expect_success "format-patch --ignore-if-in-upstream handles tags" '
80 git tag -a v1 -m tag side &&
81 git tag -a v2 -m tag master &&
82 git format-patch --stdout --ignore-if-in-upstream v2..v1 >patch1 &&
83 cnt=$(grep "^From " patch1 | wc -l) &&
84 test $cnt = 2
87 test_expect_success "format-patch doesn't consider merge commits" '
89 git checkout -b slave master &&
90 echo "Another line" >>file &&
91 test_tick &&
92 git commit -am "Slave change #1" &&
93 echo "Yet another line" >>file &&
94 test_tick &&
95 git commit -am "Slave change #2" &&
96 git checkout -b merger master &&
97 test_tick &&
98 git merge --no-ff slave &&
99 cnt=$(git format-patch -3 --stdout | grep "^From " | wc -l) &&
100 test $cnt = 3
103 test_expect_success "format-patch result applies" '
105 git checkout -b rebuild-0 master &&
106 git am -3 patch0 &&
107 cnt=$(git rev-list master.. | wc -l) &&
108 test $cnt = 2
111 test_expect_success "format-patch --ignore-if-in-upstream result applies" '
113 git checkout -b rebuild-1 master &&
114 git am -3 patch1 &&
115 cnt=$(git rev-list master.. | wc -l) &&
116 test $cnt = 2
119 test_expect_success 'commit did not screw up the log message' '
121 git cat-file commit side | grep "^Side .* with .* backslash-n"
125 test_expect_success 'format-patch did not screw up the log message' '
127 grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
128 grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
132 test_expect_success 'replay did not screw up the log message' '
134 git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
138 test_expect_success 'extra headers' '
140 git config format.headers "To: R E Cipient <rcipient@example.com>
141 " &&
142 git config --add format.headers "Cc: S E Cipient <scipient@example.com>
143 " &&
144 git format-patch --stdout master..side > patch2 &&
145 sed -e "/^\$/q" patch2 > hdrs2 &&
146 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs2 &&
147 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs2
151 test_expect_success 'extra headers without newlines' '
153 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
154 git config --add format.headers "Cc: S E Cipient <scipient@example.com>" &&
155 git format-patch --stdout master..side >patch3 &&
156 sed -e "/^\$/q" patch3 > hdrs3 &&
157 grep "^To: R E Cipient <rcipient@example.com>\$" hdrs3 &&
158 grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs3
162 test_expect_success 'extra headers with multiple To:s' '
164 git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
165 git config --add format.headers "To: S E Cipient <scipient@example.com>" &&
166 git format-patch --stdout master..side > patch4 &&
167 sed -e "/^\$/q" patch4 > hdrs4 &&
168 grep "^To: R E Cipient <rcipient@example.com>,\$" hdrs4 &&
169 grep "^ *S E Cipient <scipient@example.com>\$" hdrs4
172 test_expect_success 'additional command line cc (ascii)' '
174 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
175 git format-patch --cc="S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
176 grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
177 grep "^ *S E Cipient <scipient@example.com>\$" patch5
180 test_expect_failure 'additional command line cc (rfc822)' '
182 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
183 git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
184 grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
185 grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" patch5
188 test_expect_success 'command line headers' '
190 git config --unset-all format.headers &&
191 git format-patch --add-header="Cc: R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 &&
192 grep "^Cc: R E Cipient <rcipient@example.com>\$" patch6
195 test_expect_success 'configuration headers and command line headers' '
197 git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
198 git format-patch --add-header="Cc: S E Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 &&
199 grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch7 &&
200 grep "^ *S E Cipient <scipient@example.com>\$" patch7
203 test_expect_success 'command line To: header (ascii)' '
205 git config --unset-all format.headers &&
206 git format-patch --to="R E Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
207 grep "^To: R E Cipient <rcipient@example.com>\$" patch8
210 test_expect_failure 'command line To: header (rfc822)' '
212 git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
213 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch8
216 test_expect_failure 'command line To: header (rfc2047)' '
218 git format-patch --to="R Ä Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
219 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch8
222 test_expect_success 'configuration To: header (ascii)' '
224 git config format.to "R E Cipient <rcipient@example.com>" &&
225 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
226 grep "^To: R E Cipient <rcipient@example.com>\$" patch9
229 test_expect_failure 'configuration To: header (rfc822)' '
231 git config format.to "R. E. Cipient <rcipient@example.com>" &&
232 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
233 grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch9
236 test_expect_failure 'configuration To: header (rfc2047)' '
238 git config format.to "R Ä Cipient <rcipient@example.com>" &&
239 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
240 grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" patch9
243 # check_patch <patch>: Verify that <patch> looks like a half-sane
244 # patch email to avoid a false positive with !grep
245 check_patch () {
246 grep -e "^From:" "$1" &&
247 grep -e "^Date:" "$1" &&
248 grep -e "^Subject:" "$1"
251 test_expect_success 'format.from=false' '
253 git -c format.from=false format-patch --stdout master..side |
254 sed -e "/^\$/q" >patch &&
255 check_patch patch &&
256 ! grep "^From: C O Mitter <committer@example.com>\$" patch
259 test_expect_success 'format.from=true' '
261 git -c format.from=true format-patch --stdout master..side |
262 sed -e "/^\$/q" >patch &&
263 check_patch patch &&
264 grep "^From: C O Mitter <committer@example.com>\$" patch
267 test_expect_success 'format.from with address' '
269 git -c format.from="F R Om <from@example.com>" format-patch --stdout master..side |
270 sed -e "/^\$/q" >patch &&
271 check_patch patch &&
272 grep "^From: F R Om <from@example.com>\$" patch
275 test_expect_success '--no-from overrides format.from' '
277 git -c format.from="F R Om <from@example.com>" format-patch --no-from --stdout master..side |
278 sed -e "/^\$/q" >patch &&
279 check_patch patch &&
280 ! grep "^From: F R Om <from@example.com>\$" patch
283 test_expect_success '--from overrides format.from' '
285 git -c format.from="F R Om <from@example.com>" format-patch --from --stdout master..side |
286 sed -e "/^\$/q" >patch &&
287 check_patch patch &&
288 ! grep "^From: F R Om <from@example.com>\$" patch
291 test_expect_success '--no-to overrides config.to' '
293 git config --replace-all format.to \
294 "R E Cipient <rcipient@example.com>" &&
295 git format-patch --no-to --stdout master..side |
296 sed -e "/^\$/q" >patch10 &&
297 check_patch patch10 &&
298 ! grep "^To: R E Cipient <rcipient@example.com>\$" patch10
301 test_expect_success '--no-to and --to replaces config.to' '
303 git config --replace-all format.to \
304 "Someone <someone@out.there>" &&
305 git format-patch --no-to --to="Someone Else <else@out.there>" \
306 --stdout master..side |
307 sed -e "/^\$/q" >patch11 &&
308 check_patch patch11 &&
309 ! grep "^To: Someone <someone@out.there>\$" patch11 &&
310 grep "^To: Someone Else <else@out.there>\$" patch11
313 test_expect_success '--no-cc overrides config.cc' '
315 git config --replace-all format.cc \
316 "C E Cipient <rcipient@example.com>" &&
317 git format-patch --no-cc --stdout master..side |
318 sed -e "/^\$/q" >patch12 &&
319 check_patch patch12 &&
320 ! grep "^Cc: C E Cipient <rcipient@example.com>\$" patch12
323 test_expect_success '--no-add-header overrides config.headers' '
325 git config --replace-all format.headers \
326 "Header1: B E Cipient <rcipient@example.com>" &&
327 git format-patch --no-add-header --stdout master..side |
328 sed -e "/^\$/q" >patch13 &&
329 check_patch patch13 &&
330 ! grep "^Header1: B E Cipient <rcipient@example.com>\$" patch13
333 test_expect_success 'multiple files' '
335 rm -rf patches/ &&
336 git checkout side &&
337 git format-patch -o patches/ master &&
338 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
341 test_expect_success 'reroll count' '
342 rm -fr patches &&
343 git format-patch -o patches --cover-letter --reroll-count 4 master..side >list &&
344 ! grep -v "^patches/v4-000[0-3]-" list &&
345 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
346 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
349 test_expect_success 'reroll count (-v)' '
350 rm -fr patches &&
351 git format-patch -o patches --cover-letter -v4 master..side >list &&
352 ! grep -v "^patches/v4-000[0-3]-" list &&
353 sed -n -e "/^Subject: /p" $(cat list) >subjects &&
354 ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
357 check_threading () {
358 expect="$1" &&
359 shift &&
360 (git format-patch --stdout "$@"; echo $? > status.out) |
361 # Prints everything between the Message-ID and In-Reply-To,
362 # and replaces all Message-ID-lookalikes by a sequence number
363 perl -ne '
364 if (/^(message-id|references|in-reply-to)/i) {
365 $printing = 1;
366 } elsif (/^\S/) {
367 $printing = 0;
369 if ($printing) {
370 $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
371 for $k (keys %h) {s/$k/$h{$k}/};
372 print;
374 print "---\n" if /^From /i;
375 ' > actual &&
376 test 0 = "$(cat status.out)" &&
377 test_cmp "$expect" actual
380 cat >> expect.no-threading <<EOF
386 test_expect_success 'no threading' '
387 git checkout side &&
388 check_threading expect.no-threading master
391 cat > expect.thread <<EOF
393 Message-Id: <0>
395 Message-Id: <1>
396 In-Reply-To: <0>
397 References: <0>
399 Message-Id: <2>
400 In-Reply-To: <0>
401 References: <0>
404 test_expect_success 'thread' '
405 check_threading expect.thread --thread master
408 cat > expect.in-reply-to <<EOF
410 Message-Id: <0>
411 In-Reply-To: <1>
412 References: <1>
414 Message-Id: <2>
415 In-Reply-To: <1>
416 References: <1>
418 Message-Id: <3>
419 In-Reply-To: <1>
420 References: <1>
423 test_expect_success 'thread in-reply-to' '
424 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
425 --thread master
428 cat > expect.cover-letter <<EOF
430 Message-Id: <0>
432 Message-Id: <1>
433 In-Reply-To: <0>
434 References: <0>
436 Message-Id: <2>
437 In-Reply-To: <0>
438 References: <0>
440 Message-Id: <3>
441 In-Reply-To: <0>
442 References: <0>
445 test_expect_success 'thread cover-letter' '
446 check_threading expect.cover-letter --cover-letter --thread master
449 cat > expect.cl-irt <<EOF
451 Message-Id: <0>
452 In-Reply-To: <1>
453 References: <1>
455 Message-Id: <2>
456 In-Reply-To: <0>
457 References: <1>
460 Message-Id: <3>
461 In-Reply-To: <0>
462 References: <1>
465 Message-Id: <4>
466 In-Reply-To: <0>
467 References: <1>
471 test_expect_success 'thread cover-letter in-reply-to' '
472 check_threading expect.cl-irt --cover-letter \
473 --in-reply-to="<test.message>" --thread master
476 test_expect_success 'thread explicit shallow' '
477 check_threading expect.cl-irt --cover-letter \
478 --in-reply-to="<test.message>" --thread=shallow master
481 cat > expect.deep <<EOF
483 Message-Id: <0>
485 Message-Id: <1>
486 In-Reply-To: <0>
487 References: <0>
489 Message-Id: <2>
490 In-Reply-To: <1>
491 References: <0>
495 test_expect_success 'thread deep' '
496 check_threading expect.deep --thread=deep master
499 cat > expect.deep-irt <<EOF
501 Message-Id: <0>
502 In-Reply-To: <1>
503 References: <1>
505 Message-Id: <2>
506 In-Reply-To: <0>
507 References: <1>
510 Message-Id: <3>
511 In-Reply-To: <2>
512 References: <1>
517 test_expect_success 'thread deep in-reply-to' '
518 check_threading expect.deep-irt --thread=deep \
519 --in-reply-to="<test.message>" master
522 cat > expect.deep-cl <<EOF
524 Message-Id: <0>
526 Message-Id: <1>
527 In-Reply-To: <0>
528 References: <0>
530 Message-Id: <2>
531 In-Reply-To: <1>
532 References: <0>
535 Message-Id: <3>
536 In-Reply-To: <2>
537 References: <0>
542 test_expect_success 'thread deep cover-letter' '
543 check_threading expect.deep-cl --cover-letter --thread=deep master
546 cat > expect.deep-cl-irt <<EOF
548 Message-Id: <0>
549 In-Reply-To: <1>
550 References: <1>
552 Message-Id: <2>
553 In-Reply-To: <0>
554 References: <1>
557 Message-Id: <3>
558 In-Reply-To: <2>
559 References: <1>
563 Message-Id: <4>
564 In-Reply-To: <3>
565 References: <1>
571 test_expect_success 'thread deep cover-letter in-reply-to' '
572 check_threading expect.deep-cl-irt --cover-letter \
573 --in-reply-to="<test.message>" --thread=deep master
576 test_expect_success 'thread via config' '
577 test_config format.thread true &&
578 check_threading expect.thread master
581 test_expect_success 'thread deep via config' '
582 test_config format.thread deep &&
583 check_threading expect.deep master
586 test_expect_success 'thread config + override' '
587 test_config format.thread deep &&
588 check_threading expect.thread --thread master
591 test_expect_success 'thread config + --no-thread' '
592 test_config format.thread deep &&
593 check_threading expect.no-threading --no-thread master
596 test_expect_success 'excessive subject' '
598 rm -rf patches/ &&
599 git checkout side &&
600 before=$(git hash-object file) &&
601 before=$(git rev-parse --short $before) &&
602 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
603 after=$(git hash-object file) &&
604 after=$(git rev-parse --short $after) &&
605 git update-index file &&
606 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." &&
607 git format-patch -o patches/ master..side &&
608 ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
611 test_expect_success 'failure to write cover-letter aborts gracefully' '
612 test_when_finished "rmdir 0000-cover-letter.patch" &&
613 mkdir 0000-cover-letter.patch &&
614 test_must_fail git format-patch --no-renames --cover-letter -1
617 test_expect_success 'cover-letter inherits diff options' '
618 git mv file foo &&
619 git commit -m foo &&
620 git format-patch --no-renames --cover-letter -1 &&
621 check_patch 0000-cover-letter.patch &&
622 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
623 git format-patch --cover-letter -1 -M &&
624 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
628 cat > expect << EOF
629 This is an excessively long subject line for a message due to the
630 habit some projects have of not having a short, one-line subject at
631 the start of the commit message, but rather sticking a whole
632 paragraph right at the start as the only thing in the commit
633 message. It had better not become the filename for the patch.
638 test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
640 git format-patch --cover-letter -2 &&
641 sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
642 test_cmp expect output
646 cat > expect << EOF
647 index $before..$after 100644
648 --- a/file
649 +++ b/file
650 @@ -13,4 +13,20 @@ C
658 test_expect_success 'format-patch respects -U' '
660 git format-patch -U4 -2 &&
661 sed -e "1,/^diff/d" -e "/^+5/q" \
662 <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
663 >output &&
664 test_cmp expect output
668 cat > expect << EOF
670 diff --git a/file b/file
671 index $before..$after 100644
672 --- a/file
673 +++ b/file
674 @@ -14,3 +14,19 @@ C
681 test_expect_success 'format-patch -p suppresses stat' '
683 git format-patch -p -2 &&
684 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
685 test_cmp expect output
689 test_expect_success 'format-patch from a subdirectory (1)' '
690 filename=$(
691 rm -rf sub &&
692 mkdir -p sub/dir &&
693 cd sub/dir &&
694 git format-patch -1
695 ) &&
696 case "$filename" in
698 ;; # ok
700 echo "Oops? $filename"
701 false
703 esac &&
704 test -f "$filename"
707 test_expect_success 'format-patch from a subdirectory (2)' '
708 filename=$(
709 rm -rf sub &&
710 mkdir -p sub/dir &&
711 cd sub/dir &&
712 git format-patch -1 -o ..
713 ) &&
714 case "$filename" in
715 ../0*)
716 ;; # ok
718 echo "Oops? $filename"
719 false
721 esac &&
722 basename=$(expr "$filename" : ".*/\(.*\)") &&
723 test -f "sub/$basename"
726 test_expect_success 'format-patch from a subdirectory (3)' '
727 rm -f 0* &&
728 filename=$(
729 rm -rf sub &&
730 mkdir -p sub/dir &&
731 cd sub/dir &&
732 git format-patch -1 -o "$TRASH_DIRECTORY"
733 ) &&
734 basename=$(expr "$filename" : ".*/\(.*\)") &&
735 test -f "$basename"
738 test_expect_success 'format-patch --in-reply-to' '
739 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
740 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
741 grep "^References: <baz@foo.bar>" patch8
744 test_expect_success 'format-patch --signoff' '
745 git format-patch -1 --signoff --stdout >out &&
746 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
749 test_expect_success 'format-patch --notes --signoff' '
750 git notes --ref test add -m "test message" HEAD &&
751 git format-patch -1 --signoff --stdout --notes=test >out &&
752 # Three dashes must come after S-o-b
753 ! sed "/^Signed-off-by: /q" out | grep "test message" &&
754 sed "1,/^Signed-off-by: /d" out | grep "test message" &&
755 # Notes message must come after three dashes
756 ! sed "/^---$/q" out | grep "test message" &&
757 sed "1,/^---$/d" out | grep "test message"
760 test_expect_success 'format-patch notes output control' '
761 git notes add -m "notes config message" HEAD &&
762 test_when_finished git notes remove HEAD &&
764 git format-patch -1 --stdout >out &&
765 ! grep "notes config message" out &&
766 git format-patch -1 --stdout --notes >out &&
767 grep "notes config message" out &&
768 git format-patch -1 --stdout --no-notes >out &&
769 ! grep "notes config message" out &&
770 git format-patch -1 --stdout --notes --no-notes >out &&
771 ! grep "notes config message" out &&
772 git format-patch -1 --stdout --no-notes --notes >out &&
773 grep "notes config message" out &&
775 test_config format.notes true &&
776 git format-patch -1 --stdout >out &&
777 grep "notes config message" out &&
778 git format-patch -1 --stdout --notes >out &&
779 grep "notes config message" out &&
780 git format-patch -1 --stdout --no-notes >out &&
781 ! grep "notes config message" out &&
782 git format-patch -1 --stdout --notes --no-notes >out &&
783 ! grep "notes config message" out &&
784 git format-patch -1 --stdout --no-notes --notes >out &&
785 grep "notes config message" out
788 test_expect_success 'format-patch with multiple notes refs' '
789 git notes --ref note1 add -m "this is note 1" HEAD &&
790 test_when_finished git notes --ref note1 remove HEAD &&
791 git notes --ref note2 add -m "this is note 2" HEAD &&
792 test_when_finished git notes --ref note2 remove HEAD &&
794 git format-patch -1 --stdout >out &&
795 ! grep "this is note 1" out &&
796 ! grep "this is note 2" out &&
797 git format-patch -1 --stdout --notes=note1 >out &&
798 grep "this is note 1" out &&
799 ! grep "this is note 2" out &&
800 git format-patch -1 --stdout --notes=note2 >out &&
801 ! grep "this is note 1" out &&
802 grep "this is note 2" out &&
803 git format-patch -1 --stdout --notes=note1 --notes=note2 >out &&
804 grep "this is note 1" out &&
805 grep "this is note 2" out &&
807 test_config format.notes note1 &&
808 git format-patch -1 --stdout >out &&
809 grep "this is note 1" out &&
810 ! grep "this is note 2" out &&
811 git format-patch -1 --stdout --no-notes >out &&
812 ! grep "this is note 1" out &&
813 ! grep "this is note 2" out &&
814 git format-patch -1 --stdout --notes=note2 >out &&
815 grep "this is note 1" out &&
816 grep "this is note 2" out &&
817 git format-patch -1 --stdout --no-notes --notes=note2 >out &&
818 ! grep "this is note 1" out &&
819 grep "this is note 2" out &&
821 git config --add format.notes note2 &&
822 git format-patch -1 --stdout >out &&
823 grep "this is note 1" out &&
824 grep "this is note 2" out &&
825 git format-patch -1 --stdout --no-notes >out &&
826 ! grep "this is note 1" out &&
827 ! grep "this is note 2" out
830 echo "fatal: --name-only does not make sense" > expect.name-only
831 echo "fatal: --name-status does not make sense" > expect.name-status
832 echo "fatal: --check does not make sense" > expect.check
834 test_expect_success 'options no longer allowed for format-patch' '
835 test_must_fail git format-patch --name-only 2> output &&
836 test_i18ncmp expect.name-only output &&
837 test_must_fail git format-patch --name-status 2> output &&
838 test_i18ncmp expect.name-status output &&
839 test_must_fail git format-patch --check 2> output &&
840 test_i18ncmp expect.check output'
842 test_expect_success 'format-patch --numstat should produce a patch' '
843 git format-patch --numstat --stdout master..side > output &&
844 test 5 = $(grep "^diff --git a/" output | wc -l)'
846 test_expect_success 'format-patch -- <path>' '
847 git format-patch master..side -- file 2>error &&
848 ! grep "Use .--" error
851 test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
852 git format-patch --ignore-if-in-upstream HEAD
855 git_version="$(git --version | sed "s/.* //")"
857 signature() {
858 printf "%s\n%s\n\n" "-- " "${1:-$git_version}"
861 test_expect_success 'format-patch default signature' '
862 git format-patch --stdout -1 | tail -n 3 >output &&
863 signature >expect &&
864 test_cmp expect output
867 test_expect_success 'format-patch --signature' '
868 git format-patch --stdout --signature="my sig" -1 | tail -n 3 >output &&
869 signature "my sig" >expect &&
870 test_cmp expect output
873 test_expect_success 'format-patch with format.signature config' '
874 git config format.signature "config sig" &&
875 git format-patch --stdout -1 >output &&
876 grep "config sig" output
879 test_expect_success 'format-patch --signature overrides format.signature' '
880 git config format.signature "config sig" &&
881 git format-patch --stdout --signature="overrides" -1 >output &&
882 ! grep "config sig" output &&
883 grep "overrides" output
886 test_expect_success 'format-patch --no-signature ignores format.signature' '
887 git config format.signature "config sig" &&
888 git format-patch --stdout --signature="my sig" --no-signature \
889 -1 >output &&
890 check_patch output &&
891 ! grep "config sig" output &&
892 ! grep "my sig" output &&
893 ! grep "^-- \$" output
896 test_expect_success 'format-patch --signature --cover-letter' '
897 git config --unset-all format.signature &&
898 git format-patch --stdout --signature="my sig" --cover-letter \
899 -1 >output &&
900 grep "my sig" output &&
901 test 2 = $(grep "my sig" output | wc -l)
904 test_expect_success 'format.signature="" suppresses signatures' '
905 git config format.signature "" &&
906 git format-patch --stdout -1 >output &&
907 check_patch output &&
908 ! grep "^-- \$" output
911 test_expect_success 'format-patch --no-signature suppresses signatures' '
912 git config --unset-all format.signature &&
913 git format-patch --stdout --no-signature -1 >output &&
914 check_patch output &&
915 ! grep "^-- \$" output
918 test_expect_success 'format-patch --signature="" suppresses signatures' '
919 git format-patch --stdout --signature="" -1 >output &&
920 check_patch output &&
921 ! grep "^-- \$" output
924 test_expect_success 'prepare mail-signature input' '
925 cat >mail-signature <<-\EOF
927 Test User <test.email@kernel.org>
928 http://git.kernel.org/cgit/git/git.git
930 git.kernel.org/?p=git/git.git;a=summary
935 test_expect_success '--signature-file=file works' '
936 git format-patch --stdout --signature-file=mail-signature -1 >output &&
937 check_patch output &&
938 sed -e "1,/^-- \$/d" <output >actual &&
940 cat mail-signature && echo
941 } >expect &&
942 test_cmp expect actual
945 test_expect_success 'format.signaturefile works' '
946 test_config format.signaturefile mail-signature &&
947 git format-patch --stdout -1 >output &&
948 check_patch output &&
949 sed -e "1,/^-- \$/d" <output >actual &&
951 cat mail-signature && echo
952 } >expect &&
953 test_cmp expect actual
956 test_expect_success '--no-signature suppresses format.signaturefile ' '
957 test_config format.signaturefile mail-signature &&
958 git format-patch --stdout --no-signature -1 >output &&
959 check_patch output &&
960 ! grep "^-- \$" output
963 test_expect_success '--signature-file overrides format.signaturefile' '
964 cat >other-mail-signature <<-\EOF &&
965 Use this other signature instead of mail-signature.
967 test_config format.signaturefile mail-signature &&
968 git format-patch --stdout \
969 --signature-file=other-mail-signature -1 >output &&
970 check_patch output &&
971 sed -e "1,/^-- \$/d" <output >actual &&
973 cat other-mail-signature && echo
974 } >expect &&
975 test_cmp expect actual
978 test_expect_success '--signature overrides format.signaturefile' '
979 test_config format.signaturefile mail-signature &&
980 git format-patch --stdout --signature="my sig" -1 >output &&
981 check_patch output &&
982 grep "my sig" output
985 test_expect_success TTY 'format-patch --stdout paginates' '
986 rm -f pager_used &&
987 test_terminal env GIT_PAGER="wc >pager_used" git format-patch --stdout --all &&
988 test_path_is_file pager_used
991 test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
992 rm -f pager_used &&
993 test_terminal env GIT_PAGER="wc >pager_used" git --no-pager format-patch --stdout --all &&
994 test_terminal env GIT_PAGER="wc >pager_used" git -c "pager.format-patch=false" format-patch --stdout --all &&
995 test_path_is_missing pager_used &&
996 test_path_is_missing .git/pager_used
999 test_expect_success 'format-patch handles multi-line subjects' '
1000 rm -rf patches/ &&
1001 echo content >>file &&
1002 for i in one two three; do echo $i; done >msg &&
1003 git add file &&
1004 git commit -F msg &&
1005 git format-patch -o patches -1 &&
1006 grep ^Subject: patches/0001-one.patch >actual &&
1007 echo "Subject: [PATCH] one two three" >expect &&
1008 test_cmp expect actual
1011 test_expect_success 'format-patch handles multi-line encoded subjects' '
1012 rm -rf patches/ &&
1013 echo content >>file &&
1014 for i in en två tre; do echo $i; done >msg &&
1015 git add file &&
1016 git commit -F msg &&
1017 git format-patch -o patches -1 &&
1018 grep ^Subject: patches/0001-en.patch >actual &&
1019 echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
1020 test_cmp expect actual
1023 M8="foo bar "
1024 M64=$M8$M8$M8$M8$M8$M8$M8$M8
1025 M512=$M64$M64$M64$M64$M64$M64$M64$M64
1026 cat >expect <<'EOF'
1027 Subject: [PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1028 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1029 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1030 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1031 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
1032 bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1033 foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
1035 test_expect_success 'format-patch wraps extremely long subject (ascii)' '
1036 echo content >>file &&
1037 git add file &&
1038 git commit -m "$M512" &&
1039 git format-patch --stdout -1 >patch &&
1040 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
1041 test_cmp expect subject
1044 M8="föö bar "
1045 M64=$M8$M8$M8$M8$M8$M8$M8$M8
1046 M512=$M64$M64$M64$M64$M64$M64$M64$M64
1047 cat >expect <<'EOF'
1048 Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1049 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1050 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1051 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1052 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1053 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1054 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1055 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1056 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1057 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1058 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1059 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1060 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1061 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1062 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1063 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1064 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1065 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1066 =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
1067 =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
1068 =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
1069 =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
1070 =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
1071 =?UTF-8?q?bar?=
1073 test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
1074 rm -rf patches/ &&
1075 echo content >>file &&
1076 git add file &&
1077 git commit -m "$M512" &&
1078 git format-patch --stdout -1 >patch &&
1079 sed -n "/^Subject/p; /^ /p; /^$/q" <patch >subject &&
1080 test_cmp expect subject
1083 check_author() {
1084 echo content >>file &&
1085 git add file &&
1086 GIT_AUTHOR_NAME=$1 git commit -m author-check &&
1087 git format-patch --stdout -1 >patch &&
1088 sed -n "/^From: /p; /^ /p; /^$/q" <patch >actual &&
1089 test_cmp expect actual
1092 cat >expect <<'EOF'
1093 From: "Foo B. Bar" <author@example.com>
1095 test_expect_success 'format-patch quotes dot in from-headers' '
1096 check_author "Foo B. Bar"
1099 cat >expect <<'EOF'
1100 From: "Foo \"The Baz\" Bar" <author@example.com>
1102 test_expect_success 'format-patch quotes double-quote in from-headers' '
1103 check_author "Foo \"The Baz\" Bar"
1106 cat >expect <<'EOF'
1107 From: =?UTF-8?q?F=C3=B6o=20Bar?= <author@example.com>
1109 test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
1110 check_author "Föo Bar"
1113 cat >expect <<'EOF'
1114 From: =?UTF-8?q?F=C3=B6o=20B=2E=20Bar?= <author@example.com>
1116 test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
1117 check_author "Föo B. Bar"
1120 cat >expect <<EOF
1121 From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
1122 <author@example.com>
1124 test_expect_success 'format-patch wraps moderately long from-header (ascii)' '
1125 check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
1128 cat >expect <<'EOF'
1129 From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1130 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1131 Bar Foo Bar Foo Bar Foo Bar <author@example.com>
1133 test_expect_success 'format-patch wraps extremely long from-header (ascii)' '
1134 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"
1137 cat >expect <<'EOF'
1138 From: "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1139 Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1140 Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
1142 test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
1143 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"
1146 cat >expect <<'EOF'
1147 From: =?UTF-8?q?Fo=C3=B6=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo?=
1148 =?UTF-8?q?=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20?=
1149 =?UTF-8?q?Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar?=
1150 =?UTF-8?q?=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20Foo=20Bar=20?=
1151 =?UTF-8?q?Foo=20Bar=20Foo=20Bar?= <author@example.com>
1153 test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
1154 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"
1157 cat >expect <<'EOF'
1158 Subject: header with . in it
1160 test_expect_success 'subject lines do not have 822 atom-quoting' '
1161 echo content >>file &&
1162 git add file &&
1163 git commit -m "header with . in it" &&
1164 git format-patch -k -1 --stdout >patch &&
1165 grep ^Subject: patch >actual &&
1166 test_cmp expect actual
1169 cat >expect <<'EOF'
1170 Subject: [PREFIX 1/1] header with . in it
1172 test_expect_success 'subject prefixes have space prepended' '
1173 git format-patch -n -1 --stdout --subject-prefix=PREFIX >patch &&
1174 grep ^Subject: patch >actual &&
1175 test_cmp expect actual
1178 cat >expect <<'EOF'
1179 Subject: [1/1] header with . in it
1181 test_expect_success 'empty subject prefix does not have extra space' '
1182 git format-patch -n -1 --stdout --subject-prefix= >patch &&
1183 grep ^Subject: patch >actual &&
1184 test_cmp expect actual
1187 test_expect_success '--rfc' '
1188 cat >expect <<-\EOF &&
1189 Subject: [RFC PATCH 1/1] header with . in it
1191 git format-patch -n -1 --stdout --rfc >patch &&
1192 grep ^Subject: patch >actual &&
1193 test_cmp expect actual
1196 test_expect_success '--from=ident notices bogus ident' '
1197 test_must_fail git format-patch -1 --stdout --from=foo >patch
1200 test_expect_success '--from=ident replaces author' '
1201 git format-patch -1 --stdout --from="Me <me@example.com>" >patch &&
1202 cat >expect <<-\EOF &&
1203 From: Me <me@example.com>
1205 From: A U Thor <author@example.com>
1208 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1209 test_cmp expect patch.head
1212 test_expect_success '--from uses committer ident' '
1213 git format-patch -1 --stdout --from >patch &&
1214 cat >expect <<-\EOF &&
1215 From: C O Mitter <committer@example.com>
1217 From: A U Thor <author@example.com>
1220 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1221 test_cmp expect patch.head
1224 test_expect_success '--from omits redundant in-body header' '
1225 git format-patch -1 --stdout --from="A U Thor <author@example.com>" >patch &&
1226 cat >expect <<-\EOF &&
1227 From: A U Thor <author@example.com>
1230 sed -ne "/^From:/p; /^$/p; /^---$/q" <patch >patch.head &&
1231 test_cmp expect patch.head
1234 test_expect_success 'in-body headers trigger content encoding' '
1235 test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
1236 test_when_finished "git reset --hard HEAD^" &&
1237 git format-patch -1 --stdout --from >patch &&
1238 cat >expect <<-\EOF &&
1239 From: C O Mitter <committer@example.com>
1240 Content-Type: text/plain; charset=UTF-8
1242 From: éxötìc <author@example.com>
1245 sed -ne "/^From:/p; /^$/p; /^Content-Type/p; /^---$/q" <patch >patch.head &&
1246 test_cmp expect patch.head
1249 append_signoff()
1251 C=$(git commit-tree HEAD^^{tree} -p HEAD) &&
1252 git format-patch --stdout --signoff $C^..$C >append_signoff.patch &&
1253 sed -n -e "1,/^---$/p" append_signoff.patch |
1254 egrep -n "^Subject|Sign|^$"
1257 test_expect_success 'signoff: commit with no body' '
1258 append_signoff </dev/null >actual &&
1259 cat <<\EOF | sed "s/EOL$//" >expected &&
1260 4:Subject: [PATCH] EOL
1262 9:Signed-off-by: C O Mitter <committer@example.com>
1264 test_cmp expected actual
1267 test_expect_success 'signoff: commit with only subject' '
1268 echo subject | append_signoff >actual &&
1269 cat >expected <<\EOF &&
1270 4:Subject: [PATCH] subject
1272 9:Signed-off-by: C O Mitter <committer@example.com>
1274 test_cmp expected actual
1277 test_expect_success 'signoff: commit with only subject that does not end with NL' '
1278 printf subject | append_signoff >actual &&
1279 cat >expected <<\EOF &&
1280 4:Subject: [PATCH] subject
1282 9:Signed-off-by: C O Mitter <committer@example.com>
1284 test_cmp expected actual
1287 test_expect_success 'signoff: no existing signoffs' '
1288 append_signoff <<\EOF >actual &&
1289 subject
1291 body
1293 cat >expected <<\EOF &&
1294 4:Subject: [PATCH] subject
1297 11:Signed-off-by: C O Mitter <committer@example.com>
1299 test_cmp expected actual
1302 test_expect_success 'signoff: no existing signoffs and no trailing NL' '
1303 printf "subject\n\nbody" | append_signoff >actual &&
1304 cat >expected <<\EOF &&
1305 4:Subject: [PATCH] subject
1308 11:Signed-off-by: C O Mitter <committer@example.com>
1310 test_cmp expected actual
1313 test_expect_success 'signoff: some random signoff' '
1314 append_signoff <<\EOF >actual &&
1315 subject
1317 body
1319 Signed-off-by: my@house
1321 cat >expected <<\EOF &&
1322 4:Subject: [PATCH] subject
1325 11:Signed-off-by: my@house
1326 12:Signed-off-by: C O Mitter <committer@example.com>
1328 test_cmp expected actual
1331 test_expect_success 'signoff: misc conforming footer elements' '
1332 append_signoff <<\EOF >actual &&
1333 subject
1335 body
1337 Signed-off-by: my@house
1338 (cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
1339 Tested-by: Some One <someone@example.com>
1340 Bug: 1234
1342 cat >expected <<\EOF &&
1343 4:Subject: [PATCH] subject
1346 11:Signed-off-by: my@house
1347 15:Signed-off-by: C O Mitter <committer@example.com>
1349 test_cmp expected actual
1352 test_expect_success 'signoff: some random signoff-alike' '
1353 append_signoff <<\EOF >actual &&
1354 subject
1356 body
1357 Fooled-by-me: my@house
1359 cat >expected <<\EOF &&
1360 4:Subject: [PATCH] subject
1363 12:Signed-off-by: C O Mitter <committer@example.com>
1365 test_cmp expected actual
1368 test_expect_success 'signoff: not really a signoff' '
1369 append_signoff <<\EOF >actual &&
1370 subject
1372 I want to mention about Signed-off-by: here.
1374 cat >expected <<\EOF &&
1375 4:Subject: [PATCH] subject
1377 9:I want to mention about Signed-off-by: here.
1379 11:Signed-off-by: C O Mitter <committer@example.com>
1381 test_cmp expected actual
1384 test_expect_success 'signoff: not really a signoff (2)' '
1385 append_signoff <<\EOF >actual &&
1386 subject
1388 My unfortunate
1389 Signed-off-by: example happens to be wrapped here.
1391 cat >expected <<\EOF &&
1392 4:Subject: [PATCH] subject
1394 10:Signed-off-by: example happens to be wrapped here.
1395 11:Signed-off-by: C O Mitter <committer@example.com>
1397 test_cmp expected actual
1400 test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
1401 append_signoff <<\EOF >actual &&
1402 subject
1404 Signed-off-by: my@house
1405 Signed-off-by: your@house
1407 A lot of houses.
1409 cat >expected <<\EOF &&
1410 4:Subject: [PATCH] subject
1412 9:Signed-off-by: my@house
1413 10:Signed-off-by: your@house
1416 14:Signed-off-by: C O Mitter <committer@example.com>
1418 test_cmp expected actual
1421 test_expect_success 'signoff: the same signoff at the end' '
1422 append_signoff <<\EOF >actual &&
1423 subject
1425 body
1427 Signed-off-by: C O Mitter <committer@example.com>
1429 cat >expected <<\EOF &&
1430 4:Subject: [PATCH] subject
1433 11:Signed-off-by: C O Mitter <committer@example.com>
1435 test_cmp expected actual
1438 test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
1439 printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
1440 append_signoff >actual &&
1441 cat >expected <<\EOF &&
1442 4:Subject: [PATCH] subject
1444 9:Signed-off-by: C O Mitter <committer@example.com>
1446 test_cmp expected actual
1449 test_expect_success 'signoff: the same signoff NOT at the end' '
1450 append_signoff <<\EOF >actual &&
1451 subject
1453 body
1455 Signed-off-by: C O Mitter <committer@example.com>
1456 Signed-off-by: my@house
1458 cat >expected <<\EOF &&
1459 4:Subject: [PATCH] subject
1462 11:Signed-off-by: C O Mitter <committer@example.com>
1463 12:Signed-off-by: my@house
1465 test_cmp expected actual
1468 test_expect_success 'signoff: tolerate garbage in conforming footer' '
1469 append_signoff <<\EOF >actual &&
1470 subject
1472 body
1474 Tested-by: my@house
1475 Some Trash
1476 Signed-off-by: C O Mitter <committer@example.com>
1478 cat >expected <<\EOF &&
1479 4:Subject: [PATCH] subject
1482 13:Signed-off-by: C O Mitter <committer@example.com>
1484 test_cmp expected actual
1487 test_expect_success 'signoff: respect trailer config' '
1488 append_signoff <<\EOF >actual &&
1489 subject
1491 Myfooter: x
1492 Some Trash
1494 cat >expected <<\EOF &&
1495 4:Subject: [PATCH] subject
1498 12:Signed-off-by: C O Mitter <committer@example.com>
1500 test_cmp expected actual &&
1502 test_config trailer.Myfooter.ifexists add &&
1503 append_signoff <<\EOF >actual &&
1504 subject
1506 Myfooter: x
1507 Some Trash
1509 cat >expected <<\EOF &&
1510 4:Subject: [PATCH] subject
1512 11:Signed-off-by: C O Mitter <committer@example.com>
1514 test_cmp expected actual
1517 test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
1518 append_signoff <<\EOF >actual &&
1519 subject
1521 body
1523 Reviewed-id: Noone
1524 Tested-by: my@house
1525 Change-id: Ideadbeef
1526 Signed-off-by: C O Mitter <committer@example.com>
1527 Bug: 1234
1529 cat >expected <<\EOF &&
1530 4:Subject: [PATCH] subject
1533 14:Signed-off-by: C O Mitter <committer@example.com>
1535 test_cmp expected actual
1538 test_expect_success 'format patch ignores color.ui' '
1539 test_unconfig color.ui &&
1540 git format-patch --stdout -1 >expect &&
1541 test_config color.ui always &&
1542 git format-patch --stdout -1 >actual &&
1543 test_cmp expect actual
1546 test_expect_success 'cover letter using branch description (1)' '
1547 git checkout rebuild-1 &&
1548 test_config branch.rebuild-1.description hello &&
1549 git format-patch --stdout --cover-letter master >actual &&
1550 grep hello actual >/dev/null
1553 test_expect_success 'cover letter using branch description (2)' '
1554 git checkout rebuild-1 &&
1555 test_config branch.rebuild-1.description hello &&
1556 git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
1557 grep hello actual >/dev/null
1560 test_expect_success 'cover letter using branch description (3)' '
1561 git checkout rebuild-1 &&
1562 test_config branch.rebuild-1.description hello &&
1563 git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
1564 grep hello actual >/dev/null
1567 test_expect_success 'cover letter using branch description (4)' '
1568 git checkout rebuild-1 &&
1569 test_config branch.rebuild-1.description hello &&
1570 git format-patch --stdout --cover-letter master.. >actual &&
1571 grep hello actual >/dev/null
1574 test_expect_success 'cover letter using branch description (5)' '
1575 git checkout rebuild-1 &&
1576 test_config branch.rebuild-1.description hello &&
1577 git format-patch --stdout --cover-letter -2 HEAD >actual &&
1578 grep hello actual >/dev/null
1581 test_expect_success 'cover letter using branch description (6)' '
1582 git checkout rebuild-1 &&
1583 test_config branch.rebuild-1.description hello &&
1584 git format-patch --stdout --cover-letter -2 >actual &&
1585 grep hello actual >/dev/null
1588 test_expect_success 'cover letter with nothing' '
1589 git format-patch --stdout --cover-letter >actual &&
1590 test_line_count = 0 actual
1593 test_expect_success 'cover letter auto' '
1594 mkdir -p tmp &&
1595 test_when_finished "rm -rf tmp;
1596 git config --unset format.coverletter" &&
1598 git config format.coverletter auto &&
1599 git format-patch -o tmp -1 >list &&
1600 test_line_count = 1 list &&
1601 git format-patch -o tmp -2 >list &&
1602 test_line_count = 3 list
1605 test_expect_success 'cover letter auto user override' '
1606 mkdir -p tmp &&
1607 test_when_finished "rm -rf tmp;
1608 git config --unset format.coverletter" &&
1610 git config format.coverletter auto &&
1611 git format-patch -o tmp --cover-letter -1 >list &&
1612 test_line_count = 2 list &&
1613 git format-patch -o tmp --cover-letter -2 >list &&
1614 test_line_count = 3 list &&
1615 git format-patch -o tmp --no-cover-letter -1 >list &&
1616 test_line_count = 1 list &&
1617 git format-patch -o tmp --no-cover-letter -2 >list &&
1618 test_line_count = 2 list
1621 test_expect_success 'format-patch --zero-commit' '
1622 git format-patch --zero-commit --stdout v2..v1 >patch2 &&
1623 grep "^From " patch2 | sort | uniq >actual &&
1624 echo "From $ZERO_OID Mon Sep 17 00:00:00 2001" >expect &&
1625 test_cmp expect actual
1628 test_expect_success 'From line has expected format' '
1629 git format-patch --stdout v2..v1 >patch2 &&
1630 grep "^From " patch2 >from &&
1631 grep "^From $OID_REGEX Mon Sep 17 00:00:00 2001$" patch2 >filtered &&
1632 test_cmp from filtered
1635 test_expect_success 'format-patch format.outputDirectory option' '
1636 test_config format.outputDirectory patches &&
1637 rm -fr patches &&
1638 git format-patch master..side &&
1639 test $(git rev-list master..side | wc -l) -eq $(ls patches | wc -l)
1642 test_expect_success 'format-patch -o overrides format.outputDirectory' '
1643 test_config format.outputDirectory patches &&
1644 rm -fr patches patchset &&
1645 git format-patch master..side -o patchset &&
1646 test_path_is_missing patches &&
1647 test_path_is_dir patchset
1650 test_expect_success 'format-patch --base' '
1651 git checkout patchid &&
1652 git format-patch --stdout --base=HEAD~3 -1 | tail -n 7 >actual1 &&
1653 git format-patch --stdout --base=HEAD~3 HEAD~.. | tail -n 7 >actual2 &&
1654 echo >expected &&
1655 echo "base-commit: $(git rev-parse HEAD~3)" >>expected &&
1656 echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1657 echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected &&
1658 signature >> expected &&
1659 test_cmp expected actual1 &&
1660 test_cmp expected actual2 &&
1661 echo >fail &&
1662 echo "base-commit: $(git rev-parse HEAD~3)" >>fail &&
1663 echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --unstable | awk "{print \$1}")" >>fail &&
1664 echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --unstable | awk "{print \$1}")" >>fail &&
1665 signature >> fail &&
1666 ! test_cmp fail actual1 &&
1667 ! test_cmp fail actual2
1670 test_expect_success 'format-patch --base errors out when base commit is in revision list' '
1671 test_must_fail git format-patch --base=HEAD -2 &&
1672 test_must_fail git format-patch --base=HEAD~1 -2 &&
1673 git format-patch --stdout --base=HEAD~2 -2 >patch &&
1674 grep "^base-commit:" patch >actual &&
1675 echo "base-commit: $(git rev-parse HEAD~2)" >expected &&
1676 test_cmp expected actual
1679 test_expect_success 'format-patch --base errors out when base commit is not ancestor of revision list' '
1680 # For history as below:
1682 # ---Q---P---Z---Y---*---X
1683 # \ /
1684 # ------------W
1686 # If "format-patch Z..X" is given, P and Z can not be specified as the base commit
1687 git checkout -b topic1 master &&
1688 git rev-parse HEAD >commit-id-base &&
1689 test_commit P &&
1690 git rev-parse HEAD >commit-id-P &&
1691 test_commit Z &&
1692 git rev-parse HEAD >commit-id-Z &&
1693 test_commit Y &&
1694 git checkout -b topic2 master &&
1695 test_commit W &&
1696 git merge topic1 &&
1697 test_commit X &&
1698 test_must_fail git format-patch --base=$(cat commit-id-P) -3 &&
1699 test_must_fail git format-patch --base=$(cat commit-id-Z) -3 &&
1700 git format-patch --stdout --base=$(cat commit-id-base) -3 >patch &&
1701 grep "^base-commit:" patch >actual &&
1702 echo "base-commit: $(cat commit-id-base)" >expected &&
1703 test_cmp expected actual
1706 test_expect_success 'format-patch --base=auto' '
1707 git checkout -b upstream master &&
1708 git checkout -b local upstream &&
1709 git branch --set-upstream-to=upstream &&
1710 test_commit N1 &&
1711 test_commit N2 &&
1712 git format-patch --stdout --base=auto -2 >patch &&
1713 grep "^base-commit:" patch >actual &&
1714 echo "base-commit: $(git rev-parse upstream)" >expected &&
1715 test_cmp expected actual
1718 test_expect_success 'format-patch errors out when history involves criss-cross' '
1719 # setup criss-cross history
1721 # B---M1---D
1722 # / \ /
1723 # A X
1724 # \ / \
1725 # C---M2---E
1727 git checkout master &&
1728 test_commit A &&
1729 git checkout -b xb master &&
1730 test_commit B &&
1731 git checkout -b xc master &&
1732 test_commit C &&
1733 git checkout -b xbc xb -- &&
1734 git merge xc &&
1735 git checkout -b xcb xc -- &&
1736 git branch --set-upstream-to=xbc &&
1737 git merge xb &&
1738 git checkout xbc &&
1739 test_commit D &&
1740 git checkout xcb &&
1741 test_commit E &&
1742 test_must_fail git format-patch --base=auto -1
1745 test_expect_success 'format-patch format.useAutoBaseoption' '
1746 test_when_finished "git config --unset format.useAutoBase" &&
1747 git checkout local &&
1748 git config format.useAutoBase true &&
1749 git format-patch --stdout -1 >patch &&
1750 grep "^base-commit:" patch >actual &&
1751 echo "base-commit: $(git rev-parse upstream)" >expected &&
1752 test_cmp expected actual
1755 test_expect_success 'format-patch --base overrides format.useAutoBase' '
1756 test_when_finished "git config --unset format.useAutoBase" &&
1757 git config format.useAutoBase true &&
1758 git format-patch --stdout --base=HEAD~1 -1 >patch &&
1759 grep "^base-commit:" patch >actual &&
1760 echo "base-commit: $(git rev-parse HEAD~1)" >expected &&
1761 test_cmp expected actual
1764 test_expect_success 'format-patch --base with --attach' '
1765 git format-patch --attach=mimemime --stdout --base=HEAD~ -1 >patch &&
1766 sed -n -e "/^base-commit:/s/.*/1/p" -e "/^---*mimemime--$/s/.*/2/p" \
1767 patch >actual &&
1768 test_write_lines 1 2 >expect &&
1769 test_cmp expect actual
1771 test_expect_success 'format-patch --attach cover-letter only is non-multipart' '
1772 test_when_finished "rm -fr patches" &&
1773 git format-patch -o patches --cover-letter --attach=mimemime --base=HEAD~ -1 &&
1774 ! egrep "^--+mimemime" patches/0000*.patch &&
1775 egrep "^--+mimemime$" patches/0001*.patch >output &&
1776 test_line_count = 2 output &&
1777 egrep "^--+mimemime--$" patches/0001*.patch >output &&
1778 test_line_count = 1 output
1781 test_expect_success 'format-patch --pretty=mboxrd' '
1782 sp=" " &&
1783 cat >msg <<-INPUT_END &&
1784 mboxrd should escape the body
1786 From could trip up a loose mbox parser
1787 >From extra escape for reversibility
1788 >>From extra escape for reversibility 2
1789 from lower case not escaped
1790 Fromm bad speling not escaped
1791 From with leading space not escaped
1794 From
1795 From$sp
1796 From $sp
1797 From $sp
1798 INPUT_END
1800 cat >expect <<-INPUT_END &&
1801 >From could trip up a loose mbox parser
1802 >>From extra escape for reversibility
1803 >>>From extra escape for reversibility 2
1804 from lower case not escaped
1805 Fromm bad speling not escaped
1806 From with leading space not escaped
1809 From
1810 From
1811 From
1812 From
1813 INPUT_END
1815 C=$(git commit-tree HEAD^^{tree} -p HEAD <msg) &&
1816 git format-patch --pretty=mboxrd --stdout -1 $C~1..$C >patch &&
1817 git grep -h --no-index -A11 \
1818 "^>From could trip up a loose mbox parser" patch >actual &&
1819 test_cmp expect actual
1822 test_expect_success 'interdiff: setup' '
1823 git checkout -b boop master &&
1824 test_commit fnorp blorp &&
1825 test_commit fleep blorp
1828 test_expect_success 'interdiff: cover-letter' '
1829 sed "y/q/ /" >expect <<-\EOF &&
1830 +fleep
1833 git format-patch --cover-letter --interdiff=boop~2 -1 boop &&
1834 test_i18ngrep "^Interdiff:$" 0000-cover-letter.patch &&
1835 test_i18ngrep ! "^Interdiff:$" 0001-fleep.patch &&
1836 sed "1,/^@@ /d; /^-- $/q" <0000-cover-letter.patch >actual &&
1837 test_cmp expect actual
1840 test_expect_success 'interdiff: reroll-count' '
1841 git format-patch --cover-letter --interdiff=boop~2 -v2 -1 boop &&
1842 test_i18ngrep "^Interdiff ..* v1:$" v2-0000-cover-letter.patch
1845 test_expect_success 'interdiff: solo-patch' '
1846 cat >expect <<-\EOF &&
1847 +fleep
1850 git format-patch --interdiff=boop~2 -1 boop &&
1851 test_i18ngrep "^Interdiff:$" 0001-fleep.patch &&
1852 sed "1,/^ @@ /d; /^$/q" <0001-fleep.patch >actual &&
1853 test_cmp expect actual
1856 test_done