3 # Copyright (c) 2006 Junio C Hamano
6 test_description='various format-patch tests'
10 test_expect_success setup '
12 for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i"; done >file &&
16 git commit -m Initial &&
17 git checkout -b side &&
19 for i in 1 2 5 6 A B C 7 8 9 10; do echo "$i"; done >file &&
22 git commit -m "Side changes #1" &&
24 for i in D E F; do echo "$i"; done >>file &&
25 git update-index file &&
27 git commit -m "Side changes #2" &&
30 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file &&
31 git update-index file &&
33 git commit -m "Side changes #3 with \\n backslash-n in it." &&
35 git checkout master &&
36 git diff-tree -p C2 | git apply --index &&
38 git commit -m "Master accepts moral equivalent of #2"
42 test_expect_success "format-patch --ignore-if-in-upstream" '
44 git format-patch --stdout master..side >patch0 &&
45 cnt=`grep "^From " patch0 | wc -l` &&
50 test_expect_success "format-patch --ignore-if-in-upstream" '
52 git format-patch --stdout \
53 --ignore-if-in-upstream master..side >patch1 &&
54 cnt=`grep "^From " patch1 | wc -l` &&
59 test_expect_success "format-patch doesn't consider merge commits" '
61 git checkout -b slave master &&
62 echo "Another line" >>file &&
64 git commit -am "Slave change #1" &&
65 echo "Yet another line" >>file &&
67 git commit -am "Slave change #2" &&
68 git checkout -b merger master &&
70 git merge --no-ff slave &&
71 cnt=`git format-patch -3 --stdout | grep "^From " | wc -l` &&
75 test_expect_success "format-patch result applies" '
77 git checkout -b rebuild-0 master &&
79 cnt=`git rev-list master.. | wc -l` &&
83 test_expect_success "format-patch --ignore-if-in-upstream result applies" '
85 git checkout -b rebuild-1 master &&
87 cnt=`git rev-list master.. | wc -l` &&
91 test_expect_success 'commit did not screw up the log message' '
93 git cat-file commit side | grep "^Side .* with .* backslash-n"
97 test_expect_success 'format-patch did not screw up the log message' '
99 grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
100 grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
104 test_expect_success 'replay did not screw up the log message' '
106 git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
110 test_expect_success 'extra headers' '
112 git config format.headers "To: R. E. Cipient <rcipient@example.com>
114 git config --add format.headers "Cc: S. E. Cipient <scipient@example.com>
116 git format-patch --stdout master..side > patch2 &&
117 sed -e "/^\$/q" patch2 > hdrs2 &&
118 grep "^To: R. E. Cipient <rcipient@example.com>\$" hdrs2 &&
119 grep "^Cc: S. E. Cipient <scipient@example.com>\$" hdrs2
123 test_expect_success 'extra headers without newlines' '
125 git config --replace-all format.headers "To: R. E. Cipient <rcipient@example.com>" &&
126 git config --add format.headers "Cc: S. E. Cipient <scipient@example.com>" &&
127 git format-patch --stdout master..side >patch3 &&
128 sed -e "/^\$/q" patch3 > hdrs3 &&
129 grep "^To: R. E. Cipient <rcipient@example.com>\$" hdrs3 &&
130 grep "^Cc: S. E. Cipient <scipient@example.com>\$" hdrs3
134 test_expect_success 'extra headers with multiple To:s' '
136 git config --replace-all format.headers "To: R. E. Cipient <rcipient@example.com>" &&
137 git config --add format.headers "To: S. E. Cipient <scipient@example.com>" &&
138 git format-patch --stdout master..side > patch4 &&
139 sed -e "/^\$/q" patch4 > hdrs4 &&
140 grep "^To: R. E. Cipient <rcipient@example.com>,\$" hdrs4 &&
141 grep "^ *S. E. Cipient <scipient@example.com>\$" hdrs4
144 test_expect_success 'additional command line cc' '
146 git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" &&
147 git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
148 grep "^Cc: R. E. Cipient <rcipient@example.com>,\$" patch5 &&
149 grep "^ *S. E. Cipient <scipient@example.com>\$" patch5
152 test_expect_success 'command line headers' '
154 git config --unset-all format.headers &&
155 git format-patch --add-header="Cc: R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 &&
156 grep "^Cc: R. E. Cipient <rcipient@example.com>\$" patch6
159 test_expect_success 'configuration headers and command line headers' '
161 git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" &&
162 git format-patch --add-header="Cc: S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 &&
163 grep "^Cc: R. E. Cipient <rcipient@example.com>,\$" patch7 &&
164 grep "^ *S. E. Cipient <scipient@example.com>\$" patch7
167 test_expect_success 'command line To: header' '
169 git config --unset-all format.headers &&
170 git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
171 grep "^To: R. E. Cipient <rcipient@example.com>\$" patch8
174 test_expect_success 'configuration To: header' '
176 git config format.to "R. E. Cipient <rcipient@example.com>" &&
177 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
178 grep "^To: R. E. Cipient <rcipient@example.com>\$" patch9
181 test_expect_success '--no-to overrides config.to' '
183 git config --replace-all format.to \
184 "R. E. Cipient <rcipient@example.com>" &&
185 git format-patch --no-to --stdout master..side |
186 sed -e "/^\$/q" >patch10 &&
187 ! grep "^To: R. E. Cipient <rcipient@example.com>\$" patch10
190 test_expect_success '--no-to and --to replaces config.to' '
192 git config --replace-all format.to \
193 "Someone <someone@out.there>" &&
194 git format-patch --no-to --to="Someone Else <else@out.there>" \
195 --stdout master..side |
196 sed -e "/^\$/q" >patch11 &&
197 ! grep "^To: Someone <someone@out.there>\$" patch11 &&
198 grep "^To: Someone Else <else@out.there>\$" patch11
201 test_expect_success '--no-cc overrides config.cc' '
203 git config --replace-all format.cc \
204 "C. E. Cipient <rcipient@example.com>" &&
205 git format-patch --no-cc --stdout master..side |
206 sed -e "/^\$/q" >patch12 &&
207 ! grep "^Cc: C. E. Cipient <rcipient@example.com>\$" patch12
210 test_expect_success '--no-add-headers overrides config.headers' '
212 git config --replace-all format.headers \
213 "Header1: B. E. Cipient <rcipient@example.com>" &&
214 git format-patch --no-add-headers --stdout master..side |
215 sed -e "/^\$/q" >patch13 &&
216 ! grep "^Header1: B. E. Cipient <rcipient@example.com>\$" patch13
219 test_expect_success 'multiple files' '
223 git format-patch -o patches/ master &&
224 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
230 (git format-patch --stdout "$@"; echo $? > status.out) |
231 # Prints everything between the Message-ID and In-Reply-To,
232 # and replaces all Message-ID-lookalikes by a sequence number
234 if (/^(message-id|references|in-reply-to)/i) {
240 $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
241 for $k (keys %h) {s/$k/$h{$k}/};
244 print "---\n" if /^From /i;
246 test 0 = "$(cat status.out)" &&
247 test_cmp "$expect" actual
250 cat >> expect.no-threading <<EOF
256 test_expect_success 'no threading' '
258 check_threading expect.no-threading master
261 cat > expect.thread <<EOF
274 test_expect_success 'thread' '
275 check_threading expect.thread --thread master
278 cat > expect.in-reply-to <<EOF
293 test_expect_success 'thread in-reply-to' '
294 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
298 cat > expect.cover-letter <<EOF
315 test_expect_success 'thread cover-letter' '
316 check_threading expect.cover-letter --cover-letter --thread master
319 cat > expect.cl-irt <<EOF
341 test_expect_success 'thread cover-letter in-reply-to' '
342 check_threading expect.cl-irt --cover-letter \
343 --in-reply-to="<test.message>" --thread master
346 test_expect_success 'thread explicit shallow' '
347 check_threading expect.cl-irt --cover-letter \
348 --in-reply-to="<test.message>" --thread=shallow master
351 cat > expect.deep <<EOF
365 test_expect_success 'thread deep' '
366 check_threading expect.deep --thread=deep master
369 cat > expect.deep-irt <<EOF
387 test_expect_success 'thread deep in-reply-to' '
388 check_threading expect.deep-irt --thread=deep \
389 --in-reply-to="<test.message>" master
392 cat > expect.deep-cl <<EOF
412 test_expect_success 'thread deep cover-letter' '
413 check_threading expect.deep-cl --cover-letter --thread=deep master
416 cat > expect.deep-cl-irt <<EOF
441 test_expect_success 'thread deep cover-letter in-reply-to' '
442 check_threading expect.deep-cl-irt --cover-letter \
443 --in-reply-to="<test.message>" --thread=deep master
446 test_expect_success 'thread via config' '
447 git config format.thread true &&
448 check_threading expect.thread master
451 test_expect_success 'thread deep via config' '
452 git config format.thread deep &&
453 check_threading expect.deep master
456 test_expect_success 'thread config + override' '
457 git config format.thread deep &&
458 check_threading expect.thread --thread master
461 test_expect_success 'thread config + --no-thread' '
462 git config format.thread deep &&
463 check_threading expect.no-threading --no-thread master
466 test_expect_success 'excessive subject' '
470 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
471 git update-index file &&
472 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." &&
473 git format-patch -o patches/ master..side &&
474 ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
477 test_expect_success 'cover-letter inherits diff options' '
481 git format-patch --cover-letter -1 &&
482 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
483 git format-patch --cover-letter -1 -M &&
484 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
489 This is an excessively long subject line for a message due to the
490 habit some projects have of not having a short, one-line subject at
491 the start of the commit message, but rather sticking a whole
492 paragraph right at the start as the only thing in the commit
493 message. It had better not become the filename for the patch.
498 test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
500 git format-patch --cover-letter -2 &&
501 sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
502 test_cmp expect output
508 file | 16 ++++++++++++++++
509 1 files changed, 16 insertions(+), 0 deletions(-)
511 diff --git a/file b/file
512 index 40f36c6..2dc5c23 100644
523 test_expect_success 'format-patch respects -U' '
525 git format-patch -U4 -2 &&
526 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
527 test_cmp expect output
533 diff --git a/file b/file
534 index 40f36c6..2dc5c23 100644
544 test_expect_success 'format-patch -p suppresses stat' '
546 git format-patch -p -2 &&
547 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
548 test_cmp expect output
552 test_expect_success 'format-patch from a subdirectory (1)' '
563 echo "Oops? $filename"
570 test_expect_success 'format-patch from a subdirectory (2)' '
575 git format-patch -1 -o ..
581 echo "Oops? $filename"
585 basename=$(expr "$filename" : ".*/\(.*\)") &&
586 test -f "sub/$basename"
589 test_expect_success 'format-patch from a subdirectory (3)' '
595 git format-patch -1 -o "$TRASH_DIRECTORY"
597 basename=$(expr "$filename" : ".*/\(.*\)") &&
601 test_expect_success 'format-patch --in-reply-to' '
602 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
603 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
604 grep "^References: <baz@foo.bar>" patch8
607 test_expect_success 'format-patch --signoff' '
608 git format-patch -1 --signoff --stdout |
609 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
612 echo "fatal: --name-only does not make sense" > expect.name-only
613 echo "fatal: --name-status does not make sense" > expect.name-status
614 echo "fatal: --check does not make sense" > expect.check
616 test_expect_success 'options no longer allowed for format-patch' '
617 test_must_fail git format-patch --name-only 2> output &&
618 test_cmp expect.name-only output &&
619 test_must_fail git format-patch --name-status 2> output &&
620 test_cmp expect.name-status output &&
621 test_must_fail git format-patch --check 2> output &&
622 test_cmp expect.check output'
624 test_expect_success 'format-patch --numstat should produce a patch' '
625 git format-patch --numstat --stdout master..side > output &&
626 test 6 = $(grep "^diff --git a/" output | wc -l)'
628 test_expect_success 'format-patch -- <path>' '
629 git format-patch master..side -- file 2>error &&
630 ! grep "Use .--" error
633 test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
634 git format-patch --ignore-if-in-upstream HEAD
637 test_expect_success 'format-patch --signature' '
638 git format-patch --stdout --signature="my sig" -1 >output &&
642 test_expect_success 'format-patch with format.signature config' '
643 git config format.signature "config sig" &&
644 git format-patch --stdout -1 >output &&
645 grep "config sig" output
648 test_expect_success 'format-patch --signature overrides format.signature' '
649 git config format.signature "config sig" &&
650 git format-patch --stdout --signature="overrides" -1 >output &&
651 ! grep "config sig" output &&
652 grep "overrides" output
655 test_expect_success 'format-patch --no-signature ignores format.signature' '
656 git config format.signature "config sig" &&
657 git format-patch --stdout --signature="my sig" --no-signature \
659 ! grep "config sig" output &&
660 ! grep "my sig" output &&
661 ! grep "^-- \$" output
664 test_expect_success 'format-patch --signature --cover-letter' '
665 git config --unset-all format.signature &&
666 git format-patch --stdout --signature="my sig" --cover-letter \
668 grep "my sig" output &&
669 test 2 = $(grep "my sig" output | wc -l)
672 test_expect_success 'format.signature="" supresses signatures' '
673 git config format.signature "" &&
674 git format-patch --stdout -1 >output &&
675 ! grep "^-- \$" output
678 test_expect_success 'format-patch --no-signature supresses signatures' '
679 git config --unset-all format.signature &&
680 git format-patch --stdout --no-signature -1 >output &&
681 ! grep "^-- \$" output
684 test_expect_success 'format-patch --signature="" supresses signatures' '
685 git format-patch --signature="" -1 >output &&
686 ! grep "^-- \$" output