Code

t4014-format-patch: Call test_tick before committing
[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         test_tick &&
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 &&
20         test_chmod +x elif &&
21         test_tick &&
22         git commit -m "Side changes #1" &&
24         for i in D E F; do echo "$i"; done >>file &&
25         git update-index file &&
26         test_tick &&
27         git commit -m "Side changes #2" &&
28         git tag C2 &&
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 &&
32         test_tick &&
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 &&
37         test_tick &&
38         git commit -m "Master accepts moral equivalent of #2"
40 '
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` &&
46         test $cnt = 3
48 '
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` &&
55         test $cnt = 2
57 '
59 test_expect_success "format-patch result applies" '
61         git checkout -b rebuild-0 master &&
62         git am -3 patch0 &&
63         cnt=`git rev-list master.. | wc -l` &&
64         test $cnt = 2
65 '
67 test_expect_success "format-patch --ignore-if-in-upstream result applies" '
69         git checkout -b rebuild-1 master &&
70         git am -3 patch1 &&
71         cnt=`git rev-list master.. | wc -l` &&
72         test $cnt = 2
73 '
75 test_expect_success 'commit did not screw up the log message' '
77         git cat-file commit side | grep "^Side .* with .* backslash-n"
79 '
81 test_expect_success 'format-patch did not screw up the log message' '
83         grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
84         grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
86 '
88 test_expect_success 'replay did not screw up the log message' '
90         git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"
92 '
94 test_expect_success 'extra headers' '
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 &&
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
107 test_expect_success 'extra headers without newlines' '
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 &&
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
118 test_expect_success 'extra headers with multiple To:s' '
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 &&
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
128 test_expect_success 'additional command line cc' '
130         git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" &&
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
136 test_expect_success 'command line headers' '
138         git config --unset-all format.headers &&
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
143 test_expect_success 'configuration headers and command line headers' '
145         git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" &&
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
151 test_expect_success 'command line To: header' '
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
158 test_expect_success 'configuration To: header' '
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
165 test_expect_success '--no-to overrides config.to' '
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
174 test_expect_success '--no-to and --to replaces config.to' '
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
185 test_expect_success '--no-cc overrides config.cc' '
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
194 test_expect_success '--no-add-headers overrides config.headers' '
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
203 test_expect_success 'multiple files' '
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
211 check_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
234 cat >> expect.no-threading <<EOF
235 ---
236 ---
237 ---
238 EOF
240 test_expect_success 'no threading' '
241         git checkout side &&
242         check_threading expect.no-threading master
245 cat > expect.thread <<EOF
246 ---
247 Message-Id: <0>
248 ---
249 Message-Id: <1>
250 In-Reply-To: <0>
251 References: <0>
252 ---
253 Message-Id: <2>
254 In-Reply-To: <0>
255 References: <0>
256 EOF
258 test_expect_success 'thread' '
259         check_threading expect.thread --thread master
262 cat > expect.in-reply-to <<EOF
263 ---
264 Message-Id: <0>
265 In-Reply-To: <1>
266 References: <1>
267 ---
268 Message-Id: <2>
269 In-Reply-To: <1>
270 References: <1>
271 ---
272 Message-Id: <3>
273 In-Reply-To: <1>
274 References: <1>
275 EOF
277 test_expect_success 'thread in-reply-to' '
278         check_threading expect.in-reply-to --in-reply-to="<test.message>" \
279                 --thread master
282 cat > expect.cover-letter <<EOF
283 ---
284 Message-Id: <0>
285 ---
286 Message-Id: <1>
287 In-Reply-To: <0>
288 References: <0>
289 ---
290 Message-Id: <2>
291 In-Reply-To: <0>
292 References: <0>
293 ---
294 Message-Id: <3>
295 In-Reply-To: <0>
296 References: <0>
297 EOF
299 test_expect_success 'thread cover-letter' '
300         check_threading expect.cover-letter --cover-letter --thread master
303 cat > expect.cl-irt <<EOF
304 ---
305 Message-Id: <0>
306 In-Reply-To: <1>
307 References: <1>
308 ---
309 Message-Id: <2>
310 In-Reply-To: <0>
311 References: <1>
312         <0>
313 ---
314 Message-Id: <3>
315 In-Reply-To: <0>
316 References: <1>
317         <0>
318 ---
319 Message-Id: <4>
320 In-Reply-To: <0>
321 References: <1>
322         <0>
323 EOF
325 test_expect_success 'thread cover-letter in-reply-to' '
326         check_threading expect.cl-irt --cover-letter \
327                 --in-reply-to="<test.message>" --thread master
330 test_expect_success 'thread explicit shallow' '
331         check_threading expect.cl-irt --cover-letter \
332                 --in-reply-to="<test.message>" --thread=shallow master
335 cat > expect.deep <<EOF
336 ---
337 Message-Id: <0>
338 ---
339 Message-Id: <1>
340 In-Reply-To: <0>
341 References: <0>
342 ---
343 Message-Id: <2>
344 In-Reply-To: <1>
345 References: <0>
346         <1>
347 EOF
349 test_expect_success 'thread deep' '
350         check_threading expect.deep --thread=deep master
353 cat > expect.deep-irt <<EOF
354 ---
355 Message-Id: <0>
356 In-Reply-To: <1>
357 References: <1>
358 ---
359 Message-Id: <2>
360 In-Reply-To: <0>
361 References: <1>
362         <0>
363 ---
364 Message-Id: <3>
365 In-Reply-To: <2>
366 References: <1>
367         <0>
368         <2>
369 EOF
371 test_expect_success 'thread deep in-reply-to' '
372         check_threading expect.deep-irt  --thread=deep \
373                 --in-reply-to="<test.message>" master
376 cat > expect.deep-cl <<EOF
377 ---
378 Message-Id: <0>
379 ---
380 Message-Id: <1>
381 In-Reply-To: <0>
382 References: <0>
383 ---
384 Message-Id: <2>
385 In-Reply-To: <1>
386 References: <0>
387         <1>
388 ---
389 Message-Id: <3>
390 In-Reply-To: <2>
391 References: <0>
392         <1>
393         <2>
394 EOF
396 test_expect_success 'thread deep cover-letter' '
397         check_threading expect.deep-cl --cover-letter --thread=deep master
400 cat > expect.deep-cl-irt <<EOF
401 ---
402 Message-Id: <0>
403 In-Reply-To: <1>
404 References: <1>
405 ---
406 Message-Id: <2>
407 In-Reply-To: <0>
408 References: <1>
409         <0>
410 ---
411 Message-Id: <3>
412 In-Reply-To: <2>
413 References: <1>
414         <0>
415         <2>
416 ---
417 Message-Id: <4>
418 In-Reply-To: <3>
419 References: <1>
420         <0>
421         <2>
422         <3>
423 EOF
425 test_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
430 test_expect_success 'thread via config' '
431         git config format.thread true &&
432         check_threading expect.thread master
435 test_expect_success 'thread deep via config' '
436         git config format.thread deep &&
437         check_threading expect.deep master
440 test_expect_success 'thread config + override' '
441         git config format.thread deep &&
442         check_threading expect.thread --thread master
445 test_expect_success 'thread config + --no-thread' '
446         git config format.thread deep &&
447         check_threading expect.no-threading --no-thread master
450 test_expect_success 'excessive subject' '
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
461 test_expect_success 'cover-letter inherits diff options' '
463         git mv file foo &&
464         git commit -m foo &&
465         git format-patch --cover-letter -1 &&
466         ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
467         git format-patch --cover-letter -1 -M &&
468         grep "file => foo .* 0 *\$" 0000-cover-letter.patch
472 cat > 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
480 EOF
482 test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
484         git format-patch --cover-letter -2 &&
485         sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output &&
486         test_cmp expect output
490 cat > expect << EOF
491 ---
492  file |   16 ++++++++++++++++
493  1 files changed, 16 insertions(+), 0 deletions(-)
495 diff --git a/file b/file
496 index 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
505 EOF
507 test_expect_success 'format-patch respects -U' '
509         git format-patch -U4 -2 &&
510         sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
511         test_cmp expect output
515 cat > expect << EOF
517 diff --git a/file b/file
518 index 40f36c6..2dc5c23 100644
519 --- a/file
520 +++ b/file
521 @@ -14,3 +14,19 @@ C
522  D
523  E
524  F
525 +5
526 EOF
528 test_expect_success 'format-patch -p suppresses stat' '
530         git format-patch -p -2 &&
531         sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
532         test_cmp expect output
536 test_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"
554 test_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"
573 test_expect_success 'format-patch from a subdirectory (3)' '
574         rm -f 0* &&
575         filename=$(
576                 rm -rf sub &&
577                 mkdir -p sub/dir &&
578                 cd sub/dir &&
579                 git format-patch -1 -o "$TRASH_DIRECTORY"
580         ) &&
581         basename=$(expr "$filename" : ".*/\(.*\)") &&
582         test -f "$basename"
585 test_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
591 test_expect_success 'format-patch --signoff' '
592         git format-patch -1 --signoff --stdout |
593         grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
596 echo "fatal: --name-only does not make sense" > expect.name-only
597 echo "fatal: --name-status does not make sense" > expect.name-status
598 echo "fatal: --check does not make sense" > expect.check
600 test_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'
608 test_expect_success 'format-patch --numstat should produce a patch' '
609         git format-patch --numstat --stdout master..side > output &&
610         test 6 = $(grep "^diff --git a/" output | wc -l)'
612 test_expect_success 'format-patch -- <path>' '
613         git format-patch master..side -- file 2>error &&
614         ! grep "Use .--" error
617 test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
618         git format-patch --ignore-if-in-upstream HEAD
621 test_done