t4014-format-patch: Call test_tick before committing
[git/git.git] / t / t4014-format-patch.sh
CommitLineData
ece3c67f
JH
1#!/bin/sh
2#
3# Copyright (c) 2006 Junio C Hamano
4#
5
9800a754 6test_description='various format-patch tests'
ece3c67f
JH
7
8. ./test-lib.sh
9
10test_expect_success setup '
11
12 for i in 1 2 3 4 5 6 7 8 9 10; do echo "$i"; done >file &&
cd894ee9
JH
13 cat file >elif &&
14 git add file elif &&
6426f2d2 15 test_tick &&
ece3c67f
JH
16 git commit -m Initial &&
17 git checkout -b side &&
18
19 for i in 1 2 5 6 A B C 7 8 9 10; do echo "$i"; done >file &&
1f553918 20 test_chmod +x elif &&
6426f2d2 21 test_tick &&
816366e2 22 git commit -m "Side changes #1" &&
ece3c67f
JH
23
24 for i in D E F; do echo "$i"; done >>file &&
25 git update-index file &&
6426f2d2 26 test_tick &&
816366e2 27 git commit -m "Side changes #2" &&
982b64e4 28 git tag C2 &&
ece3c67f
JH
29
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 &&
6426f2d2 32 test_tick &&
816366e2 33 git commit -m "Side changes #3 with \\n backslash-n in it." &&
ece3c67f
JH
34
35 git checkout master &&
982b64e4 36 git diff-tree -p C2 | git apply --index &&
6426f2d2 37 test_tick &&
982b64e4 38 git commit -m "Master accepts moral equivalent of #2"
ece3c67f
JH
39
40'
41
42test_expect_success "format-patch --ignore-if-in-upstream" '
43
44 git format-patch --stdout master..side >patch0 &&
45 cnt=`grep "^From " patch0 | wc -l` &&
8780bd8f 46 test $cnt = 3
ece3c67f
JH
47
48'
49
50test_expect_success "format-patch --ignore-if-in-upstream" '
51
52 git format-patch --stdout \
53 --ignore-if-in-upstream master..side >patch1 &&
54 cnt=`grep "^From " patch1 | wc -l` &&
8780bd8f 55 test $cnt = 2
ece3c67f
JH
56
57'
58
59test_expect_success "format-patch result applies" '
60
61 git checkout -b rebuild-0 master &&
62 git am -3 patch0 &&
63 cnt=`git rev-list master.. | wc -l` &&
8780bd8f 64 test $cnt = 2
ece3c67f
JH
65'
66
67test_expect_success "format-patch --ignore-if-in-upstream result applies" '
68
69 git checkout -b rebuild-1 master &&
70 git am -3 patch1 &&
71 cnt=`git rev-list master.. | wc -l` &&
8780bd8f 72 test $cnt = 2
ece3c67f
JH
73'
74
816366e2
JH
75test_expect_success 'commit did not screw up the log message' '
76
77 git cat-file commit side | grep "^Side .* with .* backslash-n"
78
79'
80
81test_expect_success 'format-patch did not screw up the log message' '
82
83 grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
84 grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
85
86'
87
88test_expect_success 'replay did not screw up the log message' '
89
90 git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
91
92'
93
a8d8173e
DB
94test_expect_success 'extra headers' '
95
96 git config format.headers "To: R. E. Cipient <rcipient@example.com>
97" &&
98 git config --add format.headers "Cc: S. E. Cipient <scipient@example.com>
99" &&
100 git format-patch --stdout master..side > patch2 &&
9524cf29
SB
101 sed -e "/^\$/q" patch2 > hdrs2 &&
102 grep "^To: R. E. Cipient <rcipient@example.com>\$" hdrs2 &&
103 grep "^Cc: S. E. Cipient <scipient@example.com>\$" hdrs2
3b2eb186 104
a8d8173e
DB
105'
106
7d22708b 107test_expect_success 'extra headers without newlines' '
a8d8173e
DB
108
109 git config --replace-all format.headers "To: R. E. Cipient <rcipient@example.com>" &&
110 git config --add format.headers "Cc: S. E. Cipient <scipient@example.com>" &&
111 git format-patch --stdout master..side >patch3 &&
9524cf29
SB
112 sed -e "/^\$/q" patch3 > hdrs3 &&
113 grep "^To: R. E. Cipient <rcipient@example.com>\$" hdrs3 &&
114 grep "^Cc: S. E. Cipient <scipient@example.com>\$" hdrs3
3b2eb186 115
a8d8173e
DB
116'
117
3ee79d9f 118test_expect_success 'extra headers with multiple To:s' '
a8d8173e
DB
119
120 git config --replace-all format.headers "To: R. E. Cipient <rcipient@example.com>" &&
121 git config --add format.headers "To: S. E. Cipient <scipient@example.com>" &&
122 git format-patch --stdout master..side > patch4 &&
9524cf29
SB
123 sed -e "/^\$/q" patch4 > hdrs4 &&
124 grep "^To: R. E. Cipient <rcipient@example.com>,\$" hdrs4 &&
125 grep "^ *S. E. Cipient <scipient@example.com>\$" hdrs4
a8d8173e
DB
126'
127
736cc67d
DB
128test_expect_success 'additional command line cc' '
129
130 git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" &&
9524cf29
SB
131 git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
132 grep "^Cc: R. E. Cipient <rcipient@example.com>,\$" patch5 &&
133 grep "^ *S. E. Cipient <scipient@example.com>\$" patch5
736cc67d
DB
134'
135
d7d9c2d0
MH
136test_expect_success 'command line headers' '
137
138 git config --unset-all format.headers &&
9524cf29
SB
139 git format-patch --add-header="Cc: R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 &&
140 grep "^Cc: R. E. Cipient <rcipient@example.com>\$" patch6
d7d9c2d0
MH
141'
142
143test_expect_success 'configuration headers and command line headers' '
144
145 git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" &&
9524cf29
SB
146 git format-patch --add-header="Cc: S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 &&
147 grep "^Cc: R. E. Cipient <rcipient@example.com>,\$" patch7 &&
148 grep "^ *S. E. Cipient <scipient@example.com>\$" patch7
d7d9c2d0
MH
149'
150
ae6c098f
SD
151test_expect_success 'command line To: header' '
152
153 git config --unset-all format.headers &&
154 git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
155 grep "^To: R. E. Cipient <rcipient@example.com>\$" patch8
156'
157
158test_expect_success 'configuration To: header' '
159
160 git config format.to "R. E. Cipient <rcipient@example.com>" &&
161 git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
162 grep "^To: R. E. Cipient <rcipient@example.com>\$" patch9
163'
164
c4260034
SB
165test_expect_success '--no-to overrides config.to' '
166
167 git config --replace-all format.to \
168 "R. E. Cipient <rcipient@example.com>" &&
169 git format-patch --no-to --stdout master..side |
170 sed -e "/^\$/q" >patch10 &&
171 ! grep "^To: R. E. Cipient <rcipient@example.com>\$" patch10
172'
173
174test_expect_success '--no-to and --to replaces config.to' '
175
176 git config --replace-all format.to \
177 "Someone <someone@out.there>" &&
178 git format-patch --no-to --to="Someone Else <else@out.there>" \
179 --stdout master..side |
180 sed -e "/^\$/q" >patch11 &&
181 ! grep "^To: Someone <someone@out.there>\$" patch11 &&
182 grep "^To: Someone Else <else@out.there>\$" patch11
183'
184
185test_expect_success '--no-cc overrides config.cc' '
186
187 git config --replace-all format.cc \
188 "C. E. Cipient <rcipient@example.com>" &&
189 git format-patch --no-cc --stdout master..side |
190 sed -e "/^\$/q" >patch12 &&
191 ! grep "^Cc: C. E. Cipient <rcipient@example.com>\$" patch12
192'
193
194test_expect_success '--no-add-headers overrides config.headers' '
195
196 git config --replace-all format.headers \
197 "Header1: B. E. Cipient <rcipient@example.com>" &&
198 git format-patch --no-add-headers --stdout master..side |
199 sed -e "/^\$/q" >patch13 &&
200 ! grep "^Header1: B. E. Cipient <rcipient@example.com>\$" patch13
201'
202
7d812145
DB
203test_expect_success 'multiple files' '
204
205 rm -rf patches/ &&
206 git checkout side &&
207 git format-patch -o patches/ master &&
208 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
209'
210
484cf6c3
TR
211check_threading () {
212 expect="$1" &&
213 shift &&
214 (git format-patch --stdout "$@"; echo $? > status.out) |
215 # Prints everything between the Message-ID and In-Reply-To,
216 # and replaces all Message-ID-lookalikes by a sequence number
217 perl -ne '
218 if (/^(message-id|references|in-reply-to)/i) {
219 $printing = 1;
220 } elsif (/^\S/) {
221 $printing = 0;
222 }
223 if ($printing) {
224 $h{$1}=$i++ if (/<([^>]+)>/ and !exists $h{$1});
225 for $k (keys %h) {s/$k/$h{$k}/};
226 print;
227 }
228 print "---\n" if /^From /i;
229 ' > actual &&
230 test 0 = "$(cat status.out)" &&
231 test_cmp "$expect" actual
232}
233
234cat >> expect.no-threading <<EOF
235---
236---
237---
238EOF
239
240test_expect_success 'no threading' '
7d812145 241 git checkout side &&
484cf6c3 242 check_threading expect.no-threading master
7d812145
DB
243'
244
484cf6c3
TR
245cat > expect.thread <<EOF
246---
247Message-Id: <0>
248---
249Message-Id: <1>
250In-Reply-To: <0>
251References: <0>
252---
253Message-Id: <2>
254In-Reply-To: <0>
255References: <0>
256EOF
7d812145 257
484cf6c3
TR
258test_expect_success 'thread' '
259 check_threading expect.thread --thread master
7d812145
DB
260'
261
484cf6c3
TR
262cat > expect.in-reply-to <<EOF
263---
264Message-Id: <0>
265In-Reply-To: <1>
266References: <1>
267---
268Message-Id: <2>
269In-Reply-To: <1>
270References: <1>
271---
272Message-Id: <3>
273In-Reply-To: <1>
274References: <1>
275EOF
a5a27c79 276
484cf6c3
TR
277test_expect_success 'thread in-reply-to' '
278 check_threading expect.in-reply-to --in-reply-to="<test.message>" \
279 --thread master
a5a27c79
DB
280'
281
484cf6c3
TR
282cat > expect.cover-letter <<EOF
283---
284Message-Id: <0>
285---
286Message-Id: <1>
287In-Reply-To: <0>
288References: <0>
289---
290Message-Id: <2>
291In-Reply-To: <0>
292References: <0>
293---
294Message-Id: <3>
295In-Reply-To: <0>
296References: <0>
297EOF
a5a27c79 298
484cf6c3
TR
299test_expect_success 'thread cover-letter' '
300 check_threading expect.cover-letter --cover-letter --thread master
301'
302
303cat > expect.cl-irt <<EOF
304---
305Message-Id: <0>
306In-Reply-To: <1>
307References: <1>
308---
309Message-Id: <2>
2175c10d 310In-Reply-To: <0>
484cf6c3 311References: <1>
2175c10d 312 <0>
484cf6c3
TR
313---
314Message-Id: <3>
2175c10d 315In-Reply-To: <0>
484cf6c3 316References: <1>
2175c10d 317 <0>
484cf6c3
TR
318---
319Message-Id: <4>
2175c10d 320In-Reply-To: <0>
484cf6c3 321References: <1>
2175c10d 322 <0>
484cf6c3
TR
323EOF
324
325test_expect_success 'thread cover-letter in-reply-to' '
326 check_threading expect.cl-irt --cover-letter \
327 --in-reply-to="<test.message>" --thread master
a5a27c79
DB
328'
329
30984ed2
TR
330test_expect_success 'thread explicit shallow' '
331 check_threading expect.cl-irt --cover-letter \
332 --in-reply-to="<test.message>" --thread=shallow master
333'
334
335cat > expect.deep <<EOF
336---
337Message-Id: <0>
338---
339Message-Id: <1>
340In-Reply-To: <0>
341References: <0>
342---
343Message-Id: <2>
344In-Reply-To: <1>
345References: <0>
346 <1>
347EOF
348
349test_expect_success 'thread deep' '
350 check_threading expect.deep --thread=deep master
351'
352
353cat > expect.deep-irt <<EOF
354---
355Message-Id: <0>
356In-Reply-To: <1>
357References: <1>
358---
359Message-Id: <2>
360In-Reply-To: <0>
361References: <1>
362 <0>
363---
364Message-Id: <3>
365In-Reply-To: <2>
366References: <1>
367 <0>
368 <2>
369EOF
370
371test_expect_success 'thread deep in-reply-to' '
372 check_threading expect.deep-irt --thread=deep \
373 --in-reply-to="<test.message>" master
374'
375
376cat > expect.deep-cl <<EOF
377---
378Message-Id: <0>
379---
380Message-Id: <1>
381In-Reply-To: <0>
382References: <0>
383---
384Message-Id: <2>
385In-Reply-To: <1>
386References: <0>
387 <1>
388---
389Message-Id: <3>
390In-Reply-To: <2>
391References: <0>
392 <1>
393 <2>
394EOF
395
396test_expect_success 'thread deep cover-letter' '
397 check_threading expect.deep-cl --cover-letter --thread=deep master
398'
399
400cat > expect.deep-cl-irt <<EOF
401---
402Message-Id: <0>
403In-Reply-To: <1>
404References: <1>
405---
406Message-Id: <2>
407In-Reply-To: <0>
408References: <1>
409 <0>
410---
411Message-Id: <3>
412In-Reply-To: <2>
413References: <1>
414 <0>
415 <2>
416---
417Message-Id: <4>
418In-Reply-To: <3>
419References: <1>
420 <0>
421 <2>
422 <3>
423EOF
424
425test_expect_success 'thread deep cover-letter in-reply-to' '
426 check_threading expect.deep-cl-irt --cover-letter \
427 --in-reply-to="<test.message>" --thread=deep master
428'
429
430test_expect_success 'thread via config' '
431 git config format.thread true &&
432 check_threading expect.thread master
433'
434
435test_expect_success 'thread deep via config' '
436 git config format.thread deep &&
437 check_threading expect.deep master
438'
439
440test_expect_success 'thread config + override' '
441 git config format.thread deep &&
442 check_threading expect.thread --thread master
443'
444
445test_expect_success 'thread config + --no-thread' '
446 git config format.thread deep &&
447 check_threading expect.no-threading --no-thread master
448'
449
7d812145
DB
450test_expect_success 'excessive subject' '
451
452 rm -rf patches/ &&
453 git checkout side &&
454 for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
455 git update-index file &&
456 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." &&
457 git format-patch -o patches/ master..side &&
458 ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
459'
460
5d02294c
JS
461test_expect_success 'cover-letter inherits diff options' '
462
463 git mv file foo &&
464 git commit -m foo &&
465 git format-patch --cover-letter -1 &&
9524cf29 466 ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
5d02294c 467 git format-patch --cover-letter -1 -M &&
9524cf29 468 grep "file => foo .* 0 *\$" 0000-cover-letter.patch
5d02294c
JS
469
470'
859c4fbe
JS
471
472cat > expect << EOF
473 This is an excessively long subject line for a message due to the
474 habit some projects have of not having a short, one-line subject at
475 the start of the commit message, but rather sticking a whole
476 paragraph right at the start as the only thing in the commit
477 message. It had better not become the filename for the patch.
478 foo
479
480EOF
481
482test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
483
484 git format-patch --cover-letter -2 &&
9524cf29 485 sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
3af82863 486 test_cmp expect output
859c4fbe
JS
487
488'
489
68daa64d
JK
490cat > expect << EOF
491---
492 file | 16 ++++++++++++++++
493 1 files changed, 16 insertions(+), 0 deletions(-)
494
495diff --git a/file b/file
496index 40f36c6..2dc5c23 100644
497--- a/file
498+++ b/file
499@@ -13,4 +13,20 @@ C
500 10
501 D
502 E
503 F
504+5
505EOF
506
507test_expect_success 'format-patch respects -U' '
508
509 git format-patch -U4 -2 &&
9524cf29 510 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
68daa64d
JK
511 test_cmp expect output
512
513'
514
1d46f2ea
JK
515cat > expect << EOF
516
517diff --git a/file b/file
518index 40f36c6..2dc5c23 100644
519--- a/file
520+++ b/file
521@@ -14,3 +14,19 @@ C
522 D
523 E
524 F
525+5
526EOF
527
528test_expect_success 'format-patch -p suppresses stat' '
529
530 git format-patch -p -2 &&
9524cf29 531 sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
1d46f2ea
JK
532 test_cmp expect output
533
534'
535
9800a754
JH
536test_expect_success 'format-patch from a subdirectory (1)' '
537 filename=$(
538 rm -rf sub &&
539 mkdir -p sub/dir &&
540 cd sub/dir &&
541 git format-patch -1
542 ) &&
543 case "$filename" in
544 0*)
545 ;; # ok
546 *)
547 echo "Oops? $filename"
548 false
549 ;;
550 esac &&
551 test -f "$filename"
552'
553
554test_expect_success 'format-patch from a subdirectory (2)' '
555 filename=$(
556 rm -rf sub &&
557 mkdir -p sub/dir &&
558 cd sub/dir &&
559 git format-patch -1 -o ..
560 ) &&
561 case "$filename" in
562 ../0*)
563 ;; # ok
564 *)
565 echo "Oops? $filename"
566 false
567 ;;
568 esac &&
569 basename=$(expr "$filename" : ".*/\(.*\)") &&
570 test -f "sub/$basename"
571'
572
573test_expect_success 'format-patch from a subdirectory (3)' '
9800a754
JH
574 rm -f 0* &&
575 filename=$(
576 rm -rf sub &&
577 mkdir -p sub/dir &&
578 cd sub/dir &&
91c8b825 579 git format-patch -1 -o "$TRASH_DIRECTORY"
9800a754
JH
580 ) &&
581 basename=$(expr "$filename" : ".*/\(.*\)") &&
582 test -f "$basename"
583'
584
f044fe2d
SB
585test_expect_success 'format-patch --in-reply-to' '
586 git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
587 grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
588 grep "^References: <baz@foo.bar>" patch8
589'
590
591test_expect_success 'format-patch --signoff' '
592 git format-patch -1 --signoff --stdout |
593 grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
594'
595
02bc5b03
BG
596echo "fatal: --name-only does not make sense" > expect.name-only
597echo "fatal: --name-status does not make sense" > expect.name-status
598echo "fatal: --check does not make sense" > expect.check
599
600test_expect_success 'options no longer allowed for format-patch' '
601 test_must_fail git format-patch --name-only 2> output &&
602 test_cmp expect.name-only output &&
603 test_must_fail git format-patch --name-status 2> output &&
604 test_cmp expect.name-status output &&
605 test_must_fail git format-patch --check 2> output &&
606 test_cmp expect.check output'
607
608test_expect_success 'format-patch --numstat should produce a patch' '
4fa80cf0
JS
609 git format-patch --numstat --stdout master..side > output &&
610 test 6 = $(grep "^diff --git a/" output | wc -l)'
02bc5b03 611
7e93d3b9
FC
612test_expect_success 'format-patch -- <path>' '
613 git format-patch master..side -- file 2>error &&
614 ! grep "Use .--" error
615'
616
657ab61e
KB
617test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
618 git format-patch --ignore-if-in-upstream HEAD
619'
620
ece3c67f 621test_done