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