test-delta: read input into a heap buffer
[git] / t / t4150-am.sh
1 #!/bin/sh
2
3 test_description='git am running'
4
5 . ./test-lib.sh
6
7 test_expect_success 'setup: messages' '
8         cat >msg <<-\EOF &&
9         second
10
11         Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, sed diam nonumy
12         eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
13         voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita
14         kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem
15         ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
16         tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At
17         vero eos et accusam et justo duo dolores et ea rebum.
18
19         EOF
20         qz_to_tab_space <<-\EOF >>msg &&
21         QDuis autem vel eum iriure dolor in hendrerit in vulputate velit
22         Qesse molestie consequat, vel illum dolore eu feugiat nulla facilisis
23         Qat vero eros et accumsan et iusto odio dignissim qui blandit
24         Qpraesent luptatum zzril delenit augue duis dolore te feugait nulla
25         Qfacilisi.
26         EOF
27         cat >>msg <<-\EOF &&
28
29         Lorem ipsum dolor sit amet,
30         consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
31         laoreet dolore magna aliquam erat volutpat.
32
33           git
34           ---
35           +++
36
37         Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit
38         lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure
39         dolor in hendrerit in vulputate velit esse molestie consequat, vel illum
40         dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
41         dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te
42         feugait nulla facilisi.
43
44         Reported-by: A N Other <a.n.other@example.com>
45         EOF
46
47         cat >failmail <<-\EOF &&
48         From foo@example.com Fri May 23 10:43:49 2008
49         From:   foo@example.com
50         To:     bar@example.com
51         Subject: Re: [RFC/PATCH] git-foo.sh
52         Date:   Fri, 23 May 2008 05:23:42 +0200
53
54         Sometimes we have to find out that there'\''s nothing left.
55
56         EOF
57
58         cat >pine <<-\EOF &&
59         From MAILER-DAEMON Fri May 23 10:43:49 2008
60         Date: 23 May 2008 05:23:42 +0200
61         From: Mail System Internal Data <MAILER-DAEMON@example.com>
62         Subject: DON'\''T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA
63         Message-ID: <foo-0001@example.com>
64
65         This text is part of the internal format of your mail folder, and is not
66         a real message.  It is created automatically by the mail system software.
67         If deleted, important folder data will be lost, and it will be re-created
68         with the data reset to initial values.
69
70         EOF
71
72         cat >msg-without-scissors-line <<-\EOF &&
73         Test that git-am --scissors cuts at the scissors line
74
75         This line should be included in the commit message.
76         EOF
77
78         printf "Subject: " >subject-prefix &&
79
80         cat - subject-prefix msg-without-scissors-line >msg-with-scissors-line <<-\EOF &&
81         This line should not be included in the commit message with --scissors enabled.
82
83          - - >8 - - remove everything above this line - - >8 - -
84
85         EOF
86
87         signoff="Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
88 '
89
90 test_expect_success setup '
91         echo hello >file &&
92         git add file &&
93         test_tick &&
94         git commit -m first &&
95         git tag first &&
96
97         echo world >>file &&
98         git add file &&
99         test_tick &&
100         git commit -F msg &&
101         git tag second &&
102
103         git format-patch --stdout first >patch1 &&
104         {
105                 echo "Message-Id: <1226501681-24923-1-git-send-email-bda@mnsspb.ru>" &&
106                 echo "X-Fake-Field: Line One" &&
107                 echo "X-Fake-Field: Line Two" &&
108                 echo "X-Fake-Field: Line Three" &&
109                 git format-patch --stdout first | sed -e "1d"
110         } > patch1.eml &&
111         {
112                 echo "X-Fake-Field: Line One" &&
113                 echo "X-Fake-Field: Line Two" &&
114                 echo "X-Fake-Field: Line Three" &&
115                 git format-patch --stdout first | sed -e "1d"
116         } | append_cr >patch1-crlf.eml &&
117         {
118                 printf "%255s\\n" ""
119                 echo "X-Fake-Field: Line One" &&
120                 echo "X-Fake-Field: Line Two" &&
121                 echo "X-Fake-Field: Line Three" &&
122                 git format-patch --stdout first | sed -e "1d"
123         } > patch1-ws.eml &&
124         {
125                 sed -ne "1p" msg &&
126                 echo &&
127                 echo "From: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" &&
128                 echo "Date: $GIT_AUTHOR_DATE" &&
129                 echo &&
130                 sed -e "1,2d" msg &&
131                 echo "---" &&
132                 git diff-tree --no-commit-id --stat -p second
133         } >patch1-stgit.eml &&
134         mkdir stgit-series &&
135         cp patch1-stgit.eml stgit-series/patch &&
136         {
137                 echo "# This series applies on GIT commit $(git rev-parse first)" &&
138                 echo "patch"
139         } >stgit-series/series &&
140         {
141                 echo "# HG changeset patch" &&
142                 echo "# User $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" &&
143                 echo "# Date $test_tick 25200" &&
144                 echo "#      $(git show --pretty="%aD" -s second)" &&
145                 echo "# Node ID $ZERO_OID" &&
146                 echo "# Parent  $ZERO_OID" &&
147                 cat msg &&
148                 echo &&
149                 git diff-tree --no-commit-id -p second
150         } >patch1-hg.eml &&
151
152
153         echo file >file &&
154         git add file &&
155         git commit -F msg-without-scissors-line &&
156         git tag expected-for-scissors &&
157         git reset --hard HEAD^ &&
158
159         echo file >file &&
160         git add file &&
161         git commit -F msg-with-scissors-line &&
162         git tag expected-for-no-scissors &&
163         git format-patch --stdout expected-for-no-scissors^ >patch-with-scissors-line.eml &&
164         git reset --hard HEAD^ &&
165
166         sed -n -e "3,\$p" msg >file &&
167         git add file &&
168         test_tick &&
169         git commit -m third &&
170
171         git format-patch --stdout first >patch2 &&
172
173         git checkout -b lorem &&
174         sed -n -e "11,\$p" msg >file &&
175         head -n 9 msg >>file &&
176         test_tick &&
177         git commit -a -m "moved stuff" &&
178
179         echo goodbye >another &&
180         git add another &&
181         test_tick &&
182         git commit -m "added another file" &&
183
184         git format-patch --stdout master >lorem-move.patch &&
185         git format-patch --no-prefix --stdout master >lorem-zero.patch &&
186
187         git checkout -b rename &&
188         git mv file renamed &&
189         git commit -m "renamed a file" &&
190
191         git format-patch -M --stdout lorem >rename.patch &&
192
193         git reset --soft lorem^ &&
194         git commit -m "renamed a file and added another" &&
195
196         git format-patch -M --stdout lorem^ >rename-add.patch &&
197
198         # reset time
199         sane_unset test_tick &&
200         test_tick
201 '
202
203 test_expect_success 'am applies patch correctly' '
204         rm -fr .git/rebase-apply &&
205         git reset --hard &&
206         git checkout first &&
207         test_tick &&
208         git am <patch1 &&
209         test_path_is_missing .git/rebase-apply &&
210         git diff --exit-code second &&
211         test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
212         test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
213 '
214
215 test_expect_success 'am fails if index is dirty' '
216         test_when_finished "rm -f dirtyfile" &&
217         rm -fr .git/rebase-apply &&
218         git reset --hard &&
219         git checkout first &&
220         echo dirtyfile >dirtyfile &&
221         git add dirtyfile &&
222         test_must_fail git am patch1 &&
223         test_path_is_dir .git/rebase-apply &&
224         test_cmp_rev first HEAD
225 '
226
227 test_expect_success 'am applies patch e-mail not in a mbox' '
228         rm -fr .git/rebase-apply &&
229         git reset --hard &&
230         git checkout first &&
231         git am patch1.eml &&
232         test_path_is_missing .git/rebase-apply &&
233         git diff --exit-code second &&
234         test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
235         test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
236 '
237
238 test_expect_success 'am applies patch e-mail not in a mbox with CRLF' '
239         rm -fr .git/rebase-apply &&
240         git reset --hard &&
241         git checkout first &&
242         git am patch1-crlf.eml &&
243         test_path_is_missing .git/rebase-apply &&
244         git diff --exit-code second &&
245         test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
246         test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
247 '
248
249 test_expect_success 'am applies patch e-mail with preceding whitespace' '
250         rm -fr .git/rebase-apply &&
251         git reset --hard &&
252         git checkout first &&
253         git am patch1-ws.eml &&
254         test_path_is_missing .git/rebase-apply &&
255         git diff --exit-code second &&
256         test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
257         test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
258 '
259
260 test_expect_success 'am applies stgit patch' '
261         rm -fr .git/rebase-apply &&
262         git checkout -f first &&
263         git am patch1-stgit.eml &&
264         test_path_is_missing .git/rebase-apply &&
265         git diff --exit-code second &&
266         test_cmp_rev second HEAD &&
267         test_cmp_rev second^ HEAD^
268 '
269
270 test_expect_success 'am --patch-format=stgit applies stgit patch' '
271         rm -fr .git/rebase-apply &&
272         git checkout -f first &&
273         git am --patch-format=stgit <patch1-stgit.eml &&
274         test_path_is_missing .git/rebase-apply &&
275         git diff --exit-code second &&
276         test_cmp_rev second HEAD &&
277         test_cmp_rev second^ HEAD^
278 '
279
280 test_expect_success 'am applies stgit series' '
281         rm -fr .git/rebase-apply &&
282         git checkout -f first &&
283         git am stgit-series/series &&
284         test_path_is_missing .git/rebase-apply &&
285         git diff --exit-code second &&
286         test_cmp_rev second HEAD &&
287         test_cmp_rev second^ HEAD^
288 '
289
290 test_expect_success 'am applies hg patch' '
291         rm -fr .git/rebase-apply &&
292         git checkout -f first &&
293         git am patch1-hg.eml &&
294         test_path_is_missing .git/rebase-apply &&
295         git diff --exit-code second &&
296         test_cmp_rev second HEAD &&
297         test_cmp_rev second^ HEAD^
298 '
299
300 test_expect_success 'am --patch-format=hg applies hg patch' '
301         rm -fr .git/rebase-apply &&
302         git checkout -f first &&
303         git am --patch-format=hg <patch1-hg.eml &&
304         test_path_is_missing .git/rebase-apply &&
305         git diff --exit-code second &&
306         test_cmp_rev second HEAD &&
307         test_cmp_rev second^ HEAD^
308 '
309
310 test_expect_success 'am with applypatch-msg hook' '
311         test_when_finished "rm -f .git/hooks/applypatch-msg" &&
312         rm -fr .git/rebase-apply &&
313         git reset --hard &&
314         git checkout first &&
315         mkdir -p .git/hooks &&
316         write_script .git/hooks/applypatch-msg <<-\EOF &&
317         cat "$1" >actual-msg &&
318         echo hook-message >"$1"
319         EOF
320         git am patch1 &&
321         test_path_is_missing .git/rebase-apply &&
322         git diff --exit-code second &&
323         echo hook-message >expected &&
324         git log -1 --format=format:%B >actual &&
325         test_cmp expected actual &&
326         git log -1 --format=format:%B second >expected &&
327         test_cmp expected actual-msg
328 '
329
330 test_expect_success 'am with failing applypatch-msg hook' '
331         test_when_finished "rm -f .git/hooks/applypatch-msg" &&
332         rm -fr .git/rebase-apply &&
333         git reset --hard &&
334         git checkout first &&
335         mkdir -p .git/hooks &&
336         write_script .git/hooks/applypatch-msg <<-\EOF &&
337         exit 1
338         EOF
339         test_must_fail git am patch1 &&
340         test_path_is_dir .git/rebase-apply &&
341         git diff --exit-code first &&
342         test_cmp_rev first HEAD
343 '
344
345 test_expect_success 'am with pre-applypatch hook' '
346         test_when_finished "rm -f .git/hooks/pre-applypatch" &&
347         rm -fr .git/rebase-apply &&
348         git reset --hard &&
349         git checkout first &&
350         mkdir -p .git/hooks &&
351         write_script .git/hooks/pre-applypatch <<-\EOF &&
352         git diff first >diff.actual
353         exit 0
354         EOF
355         git am patch1 &&
356         test_path_is_missing .git/rebase-apply &&
357         git diff --exit-code second &&
358         test_cmp_rev second HEAD &&
359         git diff first..second >diff.expected &&
360         test_cmp diff.expected diff.actual
361 '
362
363 test_expect_success 'am with failing pre-applypatch hook' '
364         test_when_finished "rm -f .git/hooks/pre-applypatch" &&
365         rm -fr .git/rebase-apply &&
366         git reset --hard &&
367         git checkout first &&
368         mkdir -p .git/hooks &&
369         write_script .git/hooks/pre-applypatch <<-\EOF &&
370         exit 1
371         EOF
372         test_must_fail git am patch1 &&
373         test_path_is_dir .git/rebase-apply &&
374         git diff --exit-code second &&
375         test_cmp_rev first HEAD
376 '
377
378 test_expect_success 'am with post-applypatch hook' '
379         test_when_finished "rm -f .git/hooks/post-applypatch" &&
380         rm -fr .git/rebase-apply &&
381         git reset --hard &&
382         git checkout first &&
383         mkdir -p .git/hooks &&
384         write_script .git/hooks/post-applypatch <<-\EOF &&
385         git rev-parse HEAD >head.actual
386         git diff second >diff.actual
387         exit 0
388         EOF
389         git am patch1 &&
390         test_path_is_missing .git/rebase-apply &&
391         test_cmp_rev second HEAD &&
392         git rev-parse second >head.expected &&
393         test_cmp head.expected head.actual &&
394         git diff second >diff.expected &&
395         test_cmp diff.expected diff.actual
396 '
397
398 test_expect_success 'am with failing post-applypatch hook' '
399         test_when_finished "rm -f .git/hooks/post-applypatch" &&
400         rm -fr .git/rebase-apply &&
401         git reset --hard &&
402         git checkout first &&
403         mkdir -p .git/hooks &&
404         write_script .git/hooks/post-applypatch <<-\EOF &&
405         git rev-parse HEAD >head.actual
406         exit 1
407         EOF
408         git am patch1 &&
409         test_path_is_missing .git/rebase-apply &&
410         git diff --exit-code second &&
411         test_cmp_rev second HEAD &&
412         git rev-parse second >head.expected &&
413         test_cmp head.expected head.actual
414 '
415
416 test_expect_success 'am --scissors cuts the message at the scissors line' '
417         rm -fr .git/rebase-apply &&
418         git reset --hard &&
419         git checkout second &&
420         git am --scissors patch-with-scissors-line.eml &&
421         test_path_is_missing .git/rebase-apply &&
422         git diff --exit-code expected-for-scissors &&
423         test_cmp_rev expected-for-scissors HEAD
424 '
425
426 test_expect_success 'am --no-scissors overrides mailinfo.scissors' '
427         rm -fr .git/rebase-apply &&
428         git reset --hard &&
429         git checkout second &&
430         test_config mailinfo.scissors true &&
431         git am --no-scissors patch-with-scissors-line.eml &&
432         test_path_is_missing .git/rebase-apply &&
433         git diff --exit-code expected-for-no-scissors &&
434         test_cmp_rev expected-for-no-scissors HEAD
435 '
436
437 test_expect_success 'setup: new author and committer' '
438         GIT_AUTHOR_NAME="Another Thor" &&
439         GIT_AUTHOR_EMAIL="a.thor@example.com" &&
440         GIT_COMMITTER_NAME="Co M Miter" &&
441         GIT_COMMITTER_EMAIL="c.miter@example.com" &&
442         export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
443 '
444
445 compare () {
446         a=$(git cat-file commit "$2" | grep "^$1 ") &&
447         b=$(git cat-file commit "$3" | grep "^$1 ") &&
448         test "$a" = "$b"
449 }
450
451 test_expect_success 'am changes committer and keeps author' '
452         test_tick &&
453         rm -fr .git/rebase-apply &&
454         git reset --hard &&
455         git checkout first &&
456         git am patch2 &&
457         test_path_is_missing .git/rebase-apply &&
458         test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" &&
459         git diff --exit-code master..HEAD &&
460         git diff --exit-code master^..HEAD^ &&
461         compare author master HEAD &&
462         compare author master^ HEAD^ &&
463         test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
464              "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
465 '
466
467 test_expect_success 'am --signoff adds Signed-off-by: line' '
468         rm -fr .git/rebase-apply &&
469         git reset --hard &&
470         git checkout -b master2 first &&
471         git am --signoff <patch2 &&
472         {
473                 printf "third\n\nSigned-off-by: %s <%s>\n\n" \
474                         "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" &&
475                 cat msg &&
476                 printf "Signed-off-by: %s <%s>\n\n" \
477                         "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL"
478         } >expected-log &&
479         git log --pretty=%B -2 HEAD >actual &&
480         test_cmp expected-log actual
481 '
482
483 test_expect_success 'am stays in branch' '
484         echo refs/heads/master2 >expected &&
485         git symbolic-ref HEAD >actual &&
486         test_cmp expected actual
487 '
488
489 test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
490         git format-patch --stdout first >patch3 &&
491         git reset --hard first &&
492         git am --signoff <patch3 &&
493         git log --pretty=%B -2 HEAD >actual &&
494         test_cmp expected-log actual
495 '
496
497 test_expect_success 'am --signoff adds Signed-off-by: if another author is preset' '
498         NAME="A N Other" &&
499         EMAIL="a.n.other@example.com" &&
500         {
501                 printf "third\n\nSigned-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
502                         "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
503                         "$NAME" "$EMAIL" &&
504                 cat msg &&
505                 printf "Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
506                         "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
507                         "$NAME" "$EMAIL"
508         } >expected-log &&
509         git reset --hard first &&
510         GIT_COMMITTER_NAME="$NAME" GIT_COMMITTER_EMAIL="$EMAIL" \
511                 git am --signoff <patch3 &&
512         git log --pretty=%B -2 HEAD >actual &&
513         test_cmp expected-log actual
514 '
515
516 test_expect_success 'am --signoff duplicates Signed-off-by: if it is not the last one' '
517         NAME="A N Other" &&
518         EMAIL="a.n.other@example.com" &&
519         {
520                 printf "third\n\nSigned-off-by: %s <%s>\n\
521 Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
522                         "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
523                         "$NAME" "$EMAIL" \
524                         "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" &&
525                 cat msg &&
526                 printf "Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\
527 Signed-off-by: %s <%s>\n\n" \
528                         "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
529                         "$NAME" "$EMAIL" \
530                         "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL"
531         } >expected-log &&
532         git format-patch --stdout first >patch3 &&
533         git reset --hard first &&
534         git am --signoff <patch3 &&
535         git log --pretty=%B -2 HEAD >actual &&
536         test_cmp expected-log actual
537 '
538
539 test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
540         git format-patch --stdout HEAD^ >tmp &&
541         sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," tmp >patch4 &&
542         git reset --hard HEAD^ &&
543         git am <patch4 &&
544         git rev-parse HEAD >expected &&
545         git rev-parse master2 >actual &&
546         test_cmp expected actual
547 '
548
549 test_expect_success 'am --keep really keeps the subject' '
550         rm -fr .git/rebase-apply &&
551         git reset --hard &&
552         git checkout HEAD^ &&
553         git am --keep patch4 &&
554         test_path_is_missing .git/rebase-apply &&
555         git cat-file commit HEAD >actual &&
556         grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
557 '
558
559 test_expect_success 'am --keep-non-patch really keeps the non-patch part' '
560         rm -fr .git/rebase-apply &&
561         git reset --hard &&
562         git checkout HEAD^ &&
563         git am --keep-non-patch patch4 &&
564         test_path_is_missing .git/rebase-apply &&
565         git cat-file commit HEAD >actual &&
566         grep "^\[foo\] third" actual
567 '
568
569 test_expect_success 'setup am -3' '
570         rm -fr .git/rebase-apply &&
571         git reset --hard &&
572         git checkout -b base3way master2 &&
573         sed -n -e "3,\$p" msg >file &&
574         head -n 9 msg >>file &&
575         git add file &&
576         test_tick &&
577         git commit -m "copied stuff"
578 '
579
580 test_expect_success 'am -3 falls back to 3-way merge' '
581         rm -fr .git/rebase-apply &&
582         git reset --hard &&
583         git checkout -b lorem2 base3way &&
584         git am -3 lorem-move.patch &&
585         test_path_is_missing .git/rebase-apply &&
586         git diff --exit-code lorem
587 '
588
589 test_expect_success 'am -3 -p0 can read --no-prefix patch' '
590         rm -fr .git/rebase-apply &&
591         git reset --hard &&
592         git checkout -b lorem3 base3way &&
593         git am -3 -p0 lorem-zero.patch &&
594         test_path_is_missing .git/rebase-apply &&
595         git diff --exit-code lorem
596 '
597
598 test_expect_success 'am with config am.threeWay falls back to 3-way merge' '
599         rm -fr .git/rebase-apply &&
600         git reset --hard &&
601         git checkout -b lorem4 base3way &&
602         test_config am.threeWay 1 &&
603         git am lorem-move.patch &&
604         test_path_is_missing .git/rebase-apply &&
605         git diff --exit-code lorem
606 '
607
608 test_expect_success 'am with config am.threeWay overridden by --no-3way' '
609         rm -fr .git/rebase-apply &&
610         git reset --hard &&
611         git checkout -b lorem5 base3way &&
612         test_config am.threeWay 1 &&
613         test_must_fail git am --no-3way lorem-move.patch &&
614         test_path_is_dir .git/rebase-apply
615 '
616
617 test_expect_success 'am can rename a file' '
618         grep "^rename from" rename.patch &&
619         rm -fr .git/rebase-apply &&
620         git reset --hard &&
621         git checkout lorem^0 &&
622         git am rename.patch &&
623         test_path_is_missing .git/rebase-apply &&
624         git update-index --refresh &&
625         git diff --exit-code rename
626 '
627
628 test_expect_success 'am -3 can rename a file' '
629         grep "^rename from" rename.patch &&
630         rm -fr .git/rebase-apply &&
631         git reset --hard &&
632         git checkout lorem^0 &&
633         git am -3 rename.patch &&
634         test_path_is_missing .git/rebase-apply &&
635         git update-index --refresh &&
636         git diff --exit-code rename
637 '
638
639 test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '
640         grep "^rename from" rename-add.patch &&
641         rm -fr .git/rebase-apply &&
642         git reset --hard &&
643         git checkout lorem^0 &&
644         git am -3 rename-add.patch &&
645         test_path_is_missing .git/rebase-apply &&
646         git update-index --refresh &&
647         git diff --exit-code rename
648 '
649
650 test_expect_success 'am -3 -q is quiet' '
651         rm -fr .git/rebase-apply &&
652         git checkout -f lorem2 &&
653         git reset base3way --hard &&
654         git am -3 -q lorem-move.patch >output.out 2>&1 &&
655         test_must_be_empty output.out
656 '
657
658 test_expect_success 'am pauses on conflict' '
659         rm -fr .git/rebase-apply &&
660         git reset --hard &&
661         git checkout lorem2^^ &&
662         test_must_fail git am lorem-move.patch &&
663         test -d .git/rebase-apply
664 '
665
666 test_expect_success 'am --show-current-patch' '
667         git am --show-current-patch >actual.patch &&
668         test_cmp .git/rebase-apply/0001 actual.patch
669 '
670
671 test_expect_success 'am --skip works' '
672         echo goodbye >expected &&
673         git am --skip &&
674         test_path_is_missing .git/rebase-apply &&
675         git diff --exit-code lorem2^^ -- file &&
676         test_cmp expected another
677 '
678
679 test_expect_success 'am --abort removes a stray directory' '
680         mkdir .git/rebase-apply &&
681         git am --abort &&
682         test_path_is_missing .git/rebase-apply
683 '
684
685 test_expect_success 'am refuses patches when paused' '
686         rm -fr .git/rebase-apply &&
687         git reset --hard &&
688         git checkout lorem2^^ &&
689
690         test_must_fail git am lorem-move.patch &&
691         test_path_is_dir .git/rebase-apply &&
692         test_cmp_rev lorem2^^ HEAD &&
693
694         test_must_fail git am <lorem-move.patch &&
695         test_path_is_dir .git/rebase-apply &&
696         test_cmp_rev lorem2^^ HEAD
697 '
698
699 test_expect_success 'am --resolved works' '
700         echo goodbye >expected &&
701         rm -fr .git/rebase-apply &&
702         git reset --hard &&
703         git checkout lorem2^^ &&
704         test_must_fail git am lorem-move.patch &&
705         test -d .git/rebase-apply &&
706         echo resolved >>file &&
707         git add file &&
708         git am --resolved &&
709         test_path_is_missing .git/rebase-apply &&
710         test_cmp expected another
711 '
712
713 test_expect_success 'am --resolved fails if index has no changes' '
714         rm -fr .git/rebase-apply &&
715         git reset --hard &&
716         git checkout lorem2^^ &&
717         test_must_fail git am lorem-move.patch &&
718         test_path_is_dir .git/rebase-apply &&
719         test_cmp_rev lorem2^^ HEAD &&
720         test_must_fail git am --resolved &&
721         test_path_is_dir .git/rebase-apply &&
722         test_cmp_rev lorem2^^ HEAD
723 '
724
725 test_expect_success 'am --resolved fails if index has unmerged entries' '
726         rm -fr .git/rebase-apply &&
727         git reset --hard &&
728         git checkout second &&
729         test_must_fail git am -3 lorem-move.patch &&
730         test_path_is_dir .git/rebase-apply &&
731         test_cmp_rev second HEAD &&
732         test_must_fail git am --resolved >err &&
733         test_path_is_dir .git/rebase-apply &&
734         test_cmp_rev second HEAD &&
735         test_i18ngrep "still have unmerged paths" err
736 '
737
738 test_expect_success 'am takes patches from a Pine mailbox' '
739         rm -fr .git/rebase-apply &&
740         git reset --hard &&
741         git checkout first &&
742         cat pine patch1 | git am &&
743         test_path_is_missing .git/rebase-apply &&
744         git diff --exit-code master^..HEAD
745 '
746
747 test_expect_success 'am fails on mail without patch' '
748         rm -fr .git/rebase-apply &&
749         git reset --hard &&
750         test_must_fail git am <failmail &&
751         git am --abort &&
752         test_path_is_missing .git/rebase-apply
753 '
754
755 test_expect_success 'am fails on empty patch' '
756         rm -fr .git/rebase-apply &&
757         git reset --hard &&
758         echo "---" >>failmail &&
759         test_must_fail git am <failmail &&
760         git am --skip &&
761         test_path_is_missing .git/rebase-apply
762 '
763
764 test_expect_success 'am works from stdin in subdirectory' '
765         rm -fr subdir &&
766         rm -fr .git/rebase-apply &&
767         git reset --hard &&
768         git checkout first &&
769         (
770                 mkdir -p subdir &&
771                 cd subdir &&
772                 git am <../patch1
773         ) &&
774         git diff --exit-code second
775 '
776
777 test_expect_success 'am works from file (relative path given) in subdirectory' '
778         rm -fr subdir &&
779         rm -fr .git/rebase-apply &&
780         git reset --hard &&
781         git checkout first &&
782         (
783                 mkdir -p subdir &&
784                 cd subdir &&
785                 git am ../patch1
786         ) &&
787         git diff --exit-code second
788 '
789
790 test_expect_success 'am works from file (absolute path given) in subdirectory' '
791         rm -fr subdir &&
792         rm -fr .git/rebase-apply &&
793         git reset --hard &&
794         git checkout first &&
795         P=$(pwd) &&
796         (
797                 mkdir -p subdir &&
798                 cd subdir &&
799                 git am "$P/patch1"
800         ) &&
801         git diff --exit-code second
802 '
803
804 test_expect_success 'am --committer-date-is-author-date' '
805         rm -fr .git/rebase-apply &&
806         git reset --hard &&
807         git checkout first &&
808         test_tick &&
809         git am --committer-date-is-author-date patch1 &&
810         git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
811         sed -ne "/^author /s/.*> //p" head1 >at &&
812         sed -ne "/^committer /s/.*> //p" head1 >ct &&
813         test_cmp at ct
814 '
815
816 test_expect_success 'am without --committer-date-is-author-date' '
817         rm -fr .git/rebase-apply &&
818         git reset --hard &&
819         git checkout first &&
820         test_tick &&
821         git am patch1 &&
822         git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
823         sed -ne "/^author /s/.*> //p" head1 >at &&
824         sed -ne "/^committer /s/.*> //p" head1 >ct &&
825         ! test_cmp at ct
826 '
827
828 # This checks for +0000 because TZ is set to UTC and that should
829 # show up when the current time is used. The date in message is set
830 # by test_tick that uses -0700 timezone; if this feature does not
831 # work, we will see that instead of +0000.
832 test_expect_success 'am --ignore-date' '
833         rm -fr .git/rebase-apply &&
834         git reset --hard &&
835         git checkout first &&
836         test_tick &&
837         git am --ignore-date patch1 &&
838         git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
839         sed -ne "/^author /s/.*> //p" head1 >at &&
840         grep "+0000" at
841 '
842
843 test_expect_success 'am into an unborn branch' '
844         git rev-parse first^{tree} >expected &&
845         rm -fr .git/rebase-apply &&
846         git reset --hard &&
847         rm -fr subdir &&
848         mkdir subdir &&
849         git format-patch --numbered-files -o subdir -1 first &&
850         (
851                 cd subdir &&
852                 git init &&
853                 git am 1
854         ) &&
855         (
856                 cd subdir &&
857                 git rev-parse HEAD^{tree} >../actual
858         ) &&
859         test_cmp expected actual
860 '
861
862 test_expect_success 'am newline in subject' '
863         rm -fr .git/rebase-apply &&
864         git reset --hard &&
865         git checkout first &&
866         test_tick &&
867         sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
868         git am <patchnl >output.out 2>&1 &&
869         test_i18ngrep "^Applying: second \\\n foo$" output.out
870 '
871
872 test_expect_success 'am -q is quiet' '
873         rm -fr .git/rebase-apply &&
874         git reset --hard &&
875         git checkout first &&
876         test_tick &&
877         git am -q <patch1 >output.out 2>&1 &&
878         test_must_be_empty output.out
879 '
880
881 test_expect_success 'am empty-file does not infloop' '
882         rm -fr .git/rebase-apply &&
883         git reset --hard &&
884         touch empty-file &&
885         test_tick &&
886         test_must_fail git am empty-file 2>actual &&
887         echo Patch format detection failed. >expected &&
888         test_i18ncmp expected actual
889 '
890
891 test_expect_success 'am --message-id really adds the message id' '
892         rm -fr .git/rebase-apply &&
893         git reset --hard &&
894         git checkout HEAD^ &&
895         git am --message-id patch1.eml &&
896         test_path_is_missing .git/rebase-apply &&
897         git cat-file commit HEAD | tail -n1 >actual &&
898         grep Message-Id patch1.eml >expected &&
899         test_cmp expected actual
900 '
901
902 test_expect_success 'am.messageid really adds the message id' '
903         rm -fr .git/rebase-apply &&
904         git reset --hard &&
905         git checkout HEAD^ &&
906         test_config am.messageid true &&
907         git am patch1.eml &&
908         test_path_is_missing .git/rebase-apply &&
909         git cat-file commit HEAD | tail -n1 >actual &&
910         grep Message-Id patch1.eml >expected &&
911         test_cmp expected actual
912 '
913
914 test_expect_success 'am --message-id -s signs off after the message id' '
915         rm -fr .git/rebase-apply &&
916         git reset --hard &&
917         git checkout HEAD^ &&
918         git am -s --message-id patch1.eml &&
919         test_path_is_missing .git/rebase-apply &&
920         git cat-file commit HEAD | tail -n2 | head -n1 >actual &&
921         grep Message-Id patch1.eml >expected &&
922         test_cmp expected actual
923 '
924
925 test_expect_success 'am -3 works with rerere' '
926         rm -fr .git/rebase-apply &&
927         git reset --hard &&
928
929         # make patches one->two and two->three...
930         test_commit one file &&
931         test_commit two file &&
932         test_commit three file &&
933         git format-patch -2 --stdout >seq.patch &&
934
935         # and create a situation that conflicts...
936         git reset --hard one &&
937         test_commit other file &&
938
939         # enable rerere...
940         test_config rerere.enabled true &&
941         test_when_finished "rm -rf .git/rr-cache" &&
942
943         # ...and apply. Our resolution is to skip the first
944         # patch, and the rerere the second one.
945         test_must_fail git am -3 seq.patch &&
946         test_must_fail git am --skip &&
947         echo resolved >file &&
948         git add file &&
949         git am --resolved &&
950
951         # now apply again, and confirm that rerere engaged (we still
952         # expect failure from am because rerere does not auto-commit
953         # for us).
954         git reset --hard other &&
955         test_must_fail git am -3 seq.patch &&
956         test_must_fail git am --skip &&
957         echo resolved >expect &&
958         test_cmp expect file
959 '
960
961 test_expect_success 'am -s unexpected trailer block' '
962         rm -fr .git/rebase-apply &&
963         git reset --hard &&
964         echo signed >file &&
965         git add file &&
966         cat >msg <<-EOF &&
967         subject here
968
969         Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
970         [jc: tweaked log message]
971         Signed-off-by: J C H <j@c.h>
972         EOF
973         git commit -F msg &&
974         git cat-file commit HEAD | sed -e '1,/^$/d' >original &&
975         git format-patch --stdout -1 >patch &&
976
977         git reset --hard HEAD^ &&
978         git am -s patch &&
979         (
980                 cat original &&
981                 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
982         ) >expect &&
983         git cat-file commit HEAD | sed -e '1,/^$/d' >actual &&
984         test_cmp expect actual &&
985
986         cat >msg <<-\EOF &&
987         subject here
988
989         We make sure that there is a blank line between the log
990         message proper and Signed-off-by: line added.
991         EOF
992         git reset HEAD^ &&
993         git commit -F msg file &&
994         git cat-file commit HEAD | sed -e '1,/^$/d' >original &&
995         git format-patch --stdout -1 >patch &&
996
997         git reset --hard HEAD^ &&
998         git am -s patch &&
999
1000         (
1001                 cat original &&
1002                 echo &&
1003                 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
1004         ) >expect &&
1005         git cat-file commit HEAD | sed -e '1,/^$/d' >actual &&
1006         test_cmp expect actual
1007 '
1008
1009 test_expect_success 'am --patch-format=mboxrd handles mboxrd' '
1010         rm -fr .git/rebase-apply &&
1011         git checkout -f first &&
1012         echo mboxrd >>file &&
1013         git add file &&
1014         cat >msg <<-\INPUT_END &&
1015         mboxrd should escape the body
1016
1017         From could trip up a loose mbox parser
1018         >From extra escape for reversibility
1019         INPUT_END
1020         git commit -F msg &&
1021         git format-patch --pretty=mboxrd --stdout -1 >mboxrd1 &&
1022         grep "^>From could trip up a loose mbox parser" mboxrd1 &&
1023         git checkout -f first &&
1024         git am --patch-format=mboxrd mboxrd1 &&
1025         git cat-file commit HEAD | tail -n4 >out &&
1026         test_cmp msg out
1027 '
1028
1029 test_expect_success 'am works with multi-line in-body headers' '
1030         FORTY="String that has a length of more than forty characters" &&
1031         LONG="$FORTY $FORTY" &&
1032         rm -fr .git/rebase-apply &&
1033         git checkout -f first &&
1034         echo one >> file &&
1035         git commit -am "$LONG
1036
1037     Body test" --author="$LONG <long@example.com>" &&
1038         git format-patch --stdout -1 >patch &&
1039         # bump from, date, and subject down to in-body header
1040         perl -lpe "
1041                 if (/^From:/) {
1042                         print \"From: x <x\@example.com>\";
1043                         print \"Date: Sat, 1 Jan 2000 00:00:00 +0000\";
1044                         print \"Subject: x\n\";
1045                 }
1046         " patch >msg &&
1047         git checkout HEAD^ &&
1048         git am msg &&
1049         # Ensure that the author and full message are present
1050         git cat-file commit HEAD | grep "^author.*long@example.com" &&
1051         git cat-file commit HEAD | grep "^$LONG$"
1052 '
1053
1054 test_expect_success 'am --quit keeps HEAD where it is' '
1055         mkdir .git/rebase-apply &&
1056         >.git/rebase-apply/last &&
1057         >.git/rebase-apply/next &&
1058         git rev-parse HEAD^ >.git/ORIG_HEAD &&
1059         git rev-parse HEAD >expected &&
1060         git am --quit &&
1061         test_path_is_missing .git/rebase-apply &&
1062         git rev-parse HEAD >actual &&
1063         test_cmp expected actual
1064 '
1065
1066 test_done