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