Code

use persistent memory for rejected paths
[git.git] / t / t4014-format-patch.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2006 Junio C Hamano
4 #
6 test_description='various format-patch tests'
8 . ./test-lib.sh
10 test_expect_success setup '
12         for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i"; done >file &&
13         cat file >elif &&
14         git add file elif &&
15         git commit -m Initial &&
16         git checkout -b side &&
18         for i in 1 2 5 6 A B C 7 8 9 10; do echo "$i"; done >file &&
19         test_chmod +x elif &&
20         git commit -m "Side changes #1" &&
22         for i in D E F; do echo "$i"; done >>file &&
23         git update-index file &&
24         git commit -m "Side changes #2" &&
25         git tag C2 &&
27         for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file &&
28         git update-index file &&
29         git commit -m "Side changes #3 with \\n backslash-n in it." &&
31         git checkout master &&
32         git diff-tree -p C2 | git apply --index &&
33         git commit -m "Master accepts moral equivalent of #2"
35 '
37 test_expect_success "format-patch --ignore-if-in-upstream" '
39         git format-patch --stdout master..side >patch0 &&
40         cnt=`grep "^From " patch0 | wc -l` &&
41         test $cnt = 3
43 '
45 test_expect_success "format-patch --ignore-if-in-upstream" '
47         git format-patch --stdout \
48                 --ignore-if-in-upstream master..side >patch1 &&
49         cnt=`grep "^From " patch1 | wc -l` &&
50         test $cnt = 2
52 '
54 test_expect_success "format-patch result applies" '
56         git checkout -b rebuild-0 master &&
57         git am -3 patch0 &&
58         cnt=`git rev-list master.. | wc -l` &&
59         test $cnt = 2
60 '
62 test_expect_success "format-patch --ignore-if-in-upstream result applies" '
64         git checkout -b rebuild-1 master &&
65         git am -3 patch1 &&
66         cnt=`git rev-list master.. | wc -l` &&
67         test $cnt = 2
68 '
70 test_expect_success 'commit did not screw up the log message' '
72         git cat-file commit side | grep "^Side .* with .* backslash-n"
74 '
76 test_expect_success 'format-patch did not screw up the log message' '
78         grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
79         grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
81 '
83 test_expect_success 'replay did not screw up the log message' '
85         git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
87 '
89 test_expect_success 'extra headers' '
91         git config format.headers "To: R. E. Cipient <rcipient@example.com>
92 " &&
93         git config --add format.headers "Cc: S. E. Cipient <scipient@example.com>
94 " &&
95         git format-patch --stdout master..side > patch2 &&
96         sed -e "/^\$/q" patch2 > hdrs2 &&
97         grep "^To: R. E. Cipient <rcipient@example.com>\$" hdrs2 &&
98         grep "^Cc: S. E. Cipient <scipient@example.com>\$" hdrs2
102 test_expect_success 'extra headers without newlines' '
104         git config --replace-all format.headers "To: R. E. Cipient <rcipient@example.com>" &&
105         git config --add format.headers "Cc: S. E. Cipient <scipient@example.com>" &&
106         git format-patch --stdout master..side >patch3 &&
107         sed -e "/^\$/q" patch3 > hdrs3 &&
108         grep "^To: R. E. Cipient <rcipient@example.com>\$" hdrs3 &&
109         grep "^Cc: S. E. Cipient <scipient@example.com>\$" hdrs3
113 test_expect_success 'extra headers with multiple To:s' '
115         git config --replace-all format.headers "To: R. E. Cipient <rcipient@example.com>" &&
116         git config --add format.headers "To: S. E. Cipient <scipient@example.com>" &&
117         git format-patch --stdout master..side > patch4 &&
118         sed -e "/^\$/q" patch4 > hdrs4 &&
119         grep "^To: R. E. Cipient <rcipient@example.com>,\$" hdrs4 &&
120         grep "^ *S. E. Cipient <scipient@example.com>\$" hdrs4
123 test_expect_success 'additional command line cc' '
125         git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" &&
126         git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
127         grep "^Cc: R. E. Cipient <rcipient@example.com>,\$" patch5 &&
128         grep "^ *S. E. Cipient <scipient@example.com>\$" patch5
131 test_expect_success 'command line headers' '
133         git config --unset-all format.headers &&
134         git format-patch --add-header="Cc: R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 &&
135         grep "^Cc: R. E. Cipient <rcipient@example.com>\$" patch6
138 test_expect_success 'configuration headers and command line headers' '
140         git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" &&
141         git format-patch --add-header="Cc: S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 &&
142         grep "^Cc: R. E. Cipient <rcipient@example.com>,\$" patch7 &&
143         grep "^ *S. E. Cipient <scipient@example.com>\$" patch7
146 test_expect_success 'command line To: header' '
148         git config --unset-all format.headers &&
149         git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
150         grep "^To: R. E. Cipient <rcipient@example.com>\$" patch8
153 test_expect_success 'configuration To: header' '
155         git config format.to "R. E. Cipient <rcipient@example.com>" &&
156         git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
157         grep "^To: R. E. Cipient <rcipient@example.com>\$" patch9
160 test_expect_success '--no-to overrides config.to' '
162         git config --replace-all format.to \
163                 "R. E. Cipient <rcipient@example.com>" &&
164         git format-patch --no-to --stdout master..side |
165         sed -e "/^\$/q" >patch10 &&
166         ! grep "^To: R. E. Cipient <rcipient@example.com>\$" patch10
169 test_expect_success '--no-to and --to replaces config.to' '
171         git config --replace-all format.to \
172                 "Someone <someone@out.there>" &&
173         git format-patch --no-to --to="Someone Else <else@out.there>" \
174                 --stdout master..side |
175         sed -e "/^\$/q" >patch11 &&
176         ! grep "^To: Someone <someone@out.there>\$" patch11 &&
177         grep "^To: Someone Else <else@out.there>\$" patch11
180 test_expect_success '--no-cc overrides config.cc' '
182         git config --replace-all format.cc \
183                 "C. E. Cipient <rcipient@example.com>" &&
184         git format-patch --no-cc --stdout master..side |
185         sed -e "/^\$/q" >patch12 &&
186         ! grep "^Cc: C. E. Cipient <rcipient@example.com>\$" patch12
189 test_expect_success '--no-add-headers overrides config.headers' '
191         git config --replace-all format.headers \
192                 "Header1: B. E. Cipient <rcipient@example.com>" &&
193         git format-patch --no-add-headers --stdout master..side |
194         sed -e "/^\$/q" >patch13 &&
195         ! grep "^Header1: B. E. Cipient <rcipient@example.com>\$" patch13
198 test_expect_success 'multiple files' '
200         rm -rf patches/ &&
201         git checkout side &&
202         git format-patch -o patches/ master &&
203         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
206 check_threading () {
207         expect="$1" &&
208         shift &&
209         (git format-patch --stdout "$@"; echo $? > status.out) |
210         # Prints everything between the Message-ID and In-Reply-To,
211         # and replaces all Message-ID-lookalikes by a sequence number
212         perl -ne '
213                 if (/^(message-id|references|in-reply-to)/i) {
214                         $printing = 1;
215                 } elsif (/^\S/) {
216                         $printing = 0;
217                 }
218                 if ($printing) {
219                         $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
220                         for $k (keys %h) {s/$k/$h{$k}/};
221                         print;
222                 }
223                 print "---\n" if /^From /i;
224         ' > actual &&
225         test 0 = "$(cat status.out)" &&
226         test_cmp "$expect" actual
229 cat >> expect.no-threading <<EOF
230 ---
231 ---
232 ---
233 EOF
235 test_expect_success 'no threading' '
236         git checkout side &&
237         check_threading expect.no-threading master
240 cat > expect.thread <<EOF
241 ---
242 Message-Id: <0>
243 ---
244 Message-Id: <1>
245 In-Reply-To: <0>
246 References: <0>
247 ---
248 Message-Id: <2>
249 In-Reply-To: <0>
250 References: <0>
251 EOF
253 test_expect_success 'thread' '
254         check_threading expect.thread --thread master
257 cat > expect.in-reply-to <<EOF
258 ---
259 Message-Id: <0>
260 In-Reply-To: <1>
261 References: <1>
262 ---
263 Message-Id: <2>
264 In-Reply-To: <1>
265 References: <1>
266 ---
267 Message-Id: <3>
268 In-Reply-To: <1>
269 References: <1>
270 EOF
272 test_expect_success 'thread in-reply-to' '
273         check_threading expect.in-reply-to --in-reply-to="<test.message>" \
274                 --thread master
277 cat > expect.cover-letter <<EOF
278 ---
279 Message-Id: <0>
280 ---
281 Message-Id: <1>
282 In-Reply-To: <0>
283 References: <0>
284 ---
285 Message-Id: <2>
286 In-Reply-To: <0>
287 References: <0>
288 ---
289 Message-Id: <3>
290 In-Reply-To: <0>
291 References: <0>
292 EOF
294 test_expect_success 'thread cover-letter' '
295         check_threading expect.cover-letter --cover-letter --thread master
298 cat > expect.cl-irt <<EOF
299 ---
300 Message-Id: <0>
301 In-Reply-To: <1>
302 References: <1>
303 ---
304 Message-Id: <2>
305 In-Reply-To: <0>
306 References: <1>
307         <0>
308 ---
309 Message-Id: <3>
310 In-Reply-To: <0>
311 References: <1>
312         <0>
313 ---
314 Message-Id: <4>
315 In-Reply-To: <0>
316 References: <1>
317         <0>
318 EOF
320 test_expect_success 'thread cover-letter in-reply-to' '
321         check_threading expect.cl-irt --cover-letter \
322                 --in-reply-to="<test.message>" --thread master
325 test_expect_success 'thread explicit shallow' '
326         check_threading expect.cl-irt --cover-letter \
327                 --in-reply-to="<test.message>" --thread=shallow master
330 cat > expect.deep <<EOF
331 ---
332 Message-Id: <0>
333 ---
334 Message-Id: <1>
335 In-Reply-To: <0>
336 References: <0>
337 ---
338 Message-Id: <2>
339 In-Reply-To: <1>
340 References: <0>
341         <1>
342 EOF
344 test_expect_success 'thread deep' '
345         check_threading expect.deep --thread=deep master
348 cat > expect.deep-irt <<EOF
349 ---
350 Message-Id: <0>
351 In-Reply-To: <1>
352 References: <1>
353 ---
354 Message-Id: <2>
355 In-Reply-To: <0>
356 References: <1>
357         <0>
358 ---
359 Message-Id: <3>
360 In-Reply-To: <2>
361 References: <1>
362         <0>
363         <2>
364 EOF
366 test_expect_success 'thread deep in-reply-to' '
367         check_threading expect.deep-irt  --thread=deep \
368                 --in-reply-to="<test.message>" master
371 cat > expect.deep-cl <<EOF
372 ---
373 Message-Id: <0>
374 ---
375 Message-Id: <1>
376 In-Reply-To: <0>
377 References: <0>
378 ---
379 Message-Id: <2>
380 In-Reply-To: <1>
381 References: <0>
382         <1>
383 ---
384 Message-Id: <3>
385 In-Reply-To: <2>
386 References: <0>
387         <1>
388         <2>
389 EOF
391 test_expect_success 'thread deep cover-letter' '
392         check_threading expect.deep-cl --cover-letter --thread=deep master
395 cat > expect.deep-cl-irt <<EOF
396 ---
397 Message-Id: <0>
398 In-Reply-To: <1>
399 References: <1>
400 ---
401 Message-Id: <2>
402 In-Reply-To: <0>
403 References: <1>
404         <0>
405 ---
406 Message-Id: <3>
407 In-Reply-To: <2>
408 References: <1>
409         <0>
410         <2>
411 ---
412 Message-Id: <4>
413 In-Reply-To: <3>
414 References: <1>
415         <0>
416         <2>
417         <3>
418 EOF
420 test_expect_success 'thread deep cover-letter in-reply-to' '
421         check_threading expect.deep-cl-irt --cover-letter \
422                 --in-reply-to="<test.message>" --thread=deep master
425 test_expect_success 'thread via config' '
426         git config format.thread true &&
427         check_threading expect.thread master
430 test_expect_success 'thread deep via config' '
431         git config format.thread deep &&
432         check_threading expect.deep master
435 test_expect_success 'thread config + override' '
436         git config format.thread deep &&
437         check_threading expect.thread --thread master
440 test_expect_success 'thread config + --no-thread' '
441         git config format.thread deep &&
442         check_threading expect.no-threading --no-thread master
445 test_expect_success 'excessive subject' '
447         rm -rf patches/ &&
448         git checkout side &&
449         for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
450         git update-index file &&
451         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." &&
452         git format-patch -o patches/ master..side &&
453         ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
456 test_expect_success 'cover-letter inherits diff options' '
458         git mv file foo &&
459         git commit -m foo &&
460         git format-patch --cover-letter -1 &&
461         ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
462         git format-patch --cover-letter -1 -M &&
463         grep "file => foo .* 0 *\$" 0000-cover-letter.patch
467 cat > expect << EOF
468   This is an excessively long subject line for a message due to the
469     habit some projects have of not having a short, one-line subject at
470     the start of the commit message, but rather sticking a whole
471     paragraph right at the start as the only thing in the commit
472     message. It had better not become the filename for the patch.
473   foo
475 EOF
477 test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
479         git format-patch --cover-letter -2 &&
480         sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
481         test_cmp expect output
485 cat > expect << EOF
486 ---
487  file |   16 ++++++++++++++++
488  1 files changed, 16 insertions(+), 0 deletions(-)
490 diff --git a/file b/file
491 index 40f36c6..2dc5c23 100644
492 --- a/file
493 +++ b/file
494 @@ -13,4 +13,20 @@ C
495  10
496  D
497  E
498  F
499 +5
500 EOF
502 test_expect_success 'format-patch respects -U' '
504         git format-patch -U4 -2 &&
505         sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
506         test_cmp expect output
510 cat > expect << EOF
512 diff --git a/file b/file
513 index 40f36c6..2dc5c23 100644
514 --- a/file
515 +++ b/file
516 @@ -14,3 +14,19 @@ C
517  D
518  E
519  F
520 +5
521 EOF
523 test_expect_success 'format-patch -p suppresses stat' '
525         git format-patch -p -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
531 test_expect_success 'format-patch from a subdirectory (1)' '
532         filename=$(
533                 rm -rf sub &&
534                 mkdir -p sub/dir &&
535                 cd sub/dir &&
536                 git format-patch -1
537         ) &&
538         case "$filename" in
539         0*)
540                 ;; # ok
541         *)
542                 echo "Oops? $filename"
543                 false
544                 ;;
545         esac &&
546         test -f "$filename"
549 test_expect_success 'format-patch from a subdirectory (2)' '
550         filename=$(
551                 rm -rf sub &&
552                 mkdir -p sub/dir &&
553                 cd sub/dir &&
554                 git format-patch -1 -o ..
555         ) &&
556         case "$filename" in
557         ../0*)
558                 ;; # ok
559         *)
560                 echo "Oops? $filename"
561                 false
562                 ;;
563         esac &&
564         basename=$(expr "$filename" : ".*/\(.*\)") &&
565         test -f "sub/$basename"
568 test_expect_success 'format-patch from a subdirectory (3)' '
569         rm -f 0* &&
570         filename=$(
571                 rm -rf sub &&
572                 mkdir -p sub/dir &&
573                 cd sub/dir &&
574                 git format-patch -1 -o "$TRASH_DIRECTORY"
575         ) &&
576         basename=$(expr "$filename" : ".*/\(.*\)") &&
577         test -f "$basename"
580 test_expect_success 'format-patch --in-reply-to' '
581         git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
582         grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
583         grep "^References: <baz@foo.bar>" patch8
586 test_expect_success 'format-patch --signoff' '
587         git format-patch -1 --signoff --stdout |
588         grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
591 echo "fatal: --name-only does not make sense" > expect.name-only
592 echo "fatal: --name-status does not make sense" > expect.name-status
593 echo "fatal: --check does not make sense" > expect.check
595 test_expect_success 'options no longer allowed for format-patch' '
596         test_must_fail git format-patch --name-only 2> output &&
597         test_cmp expect.name-only output &&
598         test_must_fail git format-patch --name-status 2> output &&
599         test_cmp expect.name-status output &&
600         test_must_fail git format-patch --check 2> output &&
601         test_cmp expect.check output'
603 test_expect_success 'format-patch --numstat should produce a patch' '
604         git format-patch --numstat --stdout master..side > output &&
605         test 6 = $(grep "^diff --git a/" output | wc -l)'
607 test_expect_success 'format-patch -- <path>' '
608         git format-patch master..side -- file 2>error &&
609         ! grep "Use .--" error
612 test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
613         git format-patch --ignore-if-in-upstream HEAD
616 test_expect_success 'format-patch --signature' '
617         git format-patch --stdout --signature="my sig" -1 >output &&
618         grep "my sig" output
621 test_expect_success 'format-patch with format.signature config' '
622         git config format.signature "config sig" &&
623         git format-patch --stdout -1 >output &&
624         grep "config sig" output
627 test_expect_success 'format-patch --signature overrides format.signature' '
628         git config format.signature "config sig" &&
629         git format-patch --stdout --signature="overrides" -1 >output &&
630         ! grep "config sig" output &&
631         grep "overrides" output
634 test_expect_success 'format-patch --no-signature ignores format.signature' '
635         git config format.signature "config sig" &&
636         git format-patch --stdout --signature="my sig" --no-signature \
637                 -1 >output &&
638         ! grep "config sig" output &&
639         ! grep "my sig" output &&
640         ! grep "^-- \$" output
643 test_expect_success 'format-patch --signature --cover-letter' '
644         git config --unset-all format.signature &&
645         git format-patch --stdout --signature="my sig" --cover-letter \
646                 -1 >output &&
647         grep "my sig" output &&
648         test 2 = $(grep "my sig" output | wc -l)
651 test_expect_success 'format.signature="" supresses signatures' '
652         git config format.signature "" &&
653         git format-patch --stdout -1 >output &&
654         ! grep "^-- \$" output
657 test_expect_success 'format-patch --no-signature supresses signatures' '
658         git config --unset-all format.signature &&
659         git format-patch --stdout --no-signature -1 >output &&
660         ! grep "^-- \$" output
663 test_expect_success 'format-patch --signature="" supresses signatures' '
664         git format-patch --signature="" -1 >output &&
665         ! grep "^-- \$" output
668 test_done