3 test_description
='git am running'
7 test_expect_success
'setup: messages' '
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.
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
29 Lorem ipsum dolor sit amet,
30 consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
31 laoreet dolore magna aliquam erat volutpat.
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.
45 cat >failmail <<-\EOF &&
46 From foo@example.com Fri May 23 10:43:49 2008
49 Subject: Re: [RFC/PATCH] git-foo.sh
50 Date: Fri, 23 May 2008 05:23:42 +0200
52 Sometimes we have to find out that there'\''s nothing left.
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>
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.
70 signoff="Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
73 test_expect_success setup
'
77 git commit -m first &&
83 git commit -s -F msg &&
86 git format-patch --stdout first >patch1 &&
88 echo "Message-Id: <1226501681-24923-1-git-send-email-bda@mnsspb.ru>" &&
89 echo "X-Fake-Field: Line One" &&
90 echo "X-Fake-Field: Line Two" &&
91 echo "X-Fake-Field: Line Three" &&
92 git format-patch --stdout first | sed -e "1d"
95 echo "X-Fake-Field: Line One" &&
96 echo "X-Fake-Field: Line Two" &&
97 echo "X-Fake-Field: Line Three" &&
98 git format-patch --stdout first | sed -e "1d"
99 } | append_cr >patch1-crlf.eml &&
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"
108 sed -n -e "3,\$p" msg >file &&
111 git commit -m third &&
113 git format-patch --stdout first >patch2 &&
115 git checkout -b lorem &&
116 sed -n -e "11,\$p" msg >file &&
117 head -n 9 msg >>file &&
119 git commit -a -m "moved stuff" &&
121 echo goodbye >another &&
124 git commit -m "added another file" &&
126 git format-patch --stdout master >lorem-move.patch &&
127 git format-patch --no-prefix --stdout master >lorem-zero.patch &&
129 git checkout -b rename &&
130 git mv file renamed &&
131 git commit -m "renamed a file" &&
133 git format-patch -M --stdout lorem >rename.patch &&
135 git reset --soft lorem^ &&
136 git commit -m "renamed a file and added another" &&
138 git format-patch -M --stdout lorem^ >rename-add.patch &&
141 sane_unset test_tick &&
145 test_expect_success
'am applies patch correctly' '
146 rm -fr .git/rebase-apply &&
148 git checkout first &&
151 test_path_is_missing .git/rebase-apply &&
152 git diff --exit-code second &&
153 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
154 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
157 test_expect_success
'am fails if index is dirty' '
158 test_when_finished "rm -f dirtyfile" &&
159 rm -fr .git/rebase-apply &&
161 git checkout first &&
162 echo dirtyfile >dirtyfile &&
164 test_must_fail git am patch1 &&
165 test_path_is_dir .git/rebase-apply &&
166 test_cmp_rev first HEAD
169 test_expect_success
'am applies patch e-mail not in a mbox' '
170 rm -fr .git/rebase-apply &&
172 git checkout first &&
174 test_path_is_missing .git/rebase-apply &&
175 git diff --exit-code second &&
176 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
177 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
180 test_expect_success
'am applies patch e-mail not in a mbox with CRLF' '
181 rm -fr .git/rebase-apply &&
183 git checkout first &&
184 git am patch1-crlf.eml &&
185 test_path_is_missing .git/rebase-apply &&
186 git diff --exit-code second &&
187 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
188 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
191 test_expect_success
'am applies patch e-mail with preceding whitespace' '
192 rm -fr .git/rebase-apply &&
194 git checkout first &&
195 git am patch1-ws.eml &&
196 test_path_is_missing .git/rebase-apply &&
197 git diff --exit-code second &&
198 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
199 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
202 test_expect_success
'am with applypatch-msg hook' '
203 test_when_finished "rm -f .git/hooks/applypatch-msg" &&
204 rm -fr .git/rebase-apply &&
206 git checkout first &&
207 mkdir -p .git/hooks &&
208 write_script .git/hooks/applypatch-msg <<-\EOF &&
209 cat "$1" >actual-msg &&
210 echo hook-message >"$1"
213 test_path_is_missing .git/rebase-apply &&
214 git diff --exit-code second &&
215 echo hook-message >expected &&
216 git log -1 --format=format:%B >actual &&
217 test_cmp expected actual &&
218 git log -1 --format=format:%B second >expected &&
219 test_cmp expected actual-msg
222 test_expect_success
'am with failing applypatch-msg hook' '
223 test_when_finished "rm -f .git/hooks/applypatch-msg" &&
224 rm -fr .git/rebase-apply &&
226 git checkout first &&
227 mkdir -p .git/hooks &&
228 write_script .git/hooks/applypatch-msg <<-\EOF &&
231 test_must_fail git am patch1 &&
232 test_path_is_dir .git/rebase-apply &&
233 git diff --exit-code first &&
234 test_cmp_rev first HEAD
237 test_expect_success
'am with pre-applypatch hook' '
238 test_when_finished "rm -f .git/hooks/pre-applypatch" &&
239 rm -fr .git/rebase-apply &&
241 git checkout first &&
242 mkdir -p .git/hooks &&
243 write_script .git/hooks/pre-applypatch <<-\EOF &&
244 git diff first >diff.actual
248 test_path_is_missing .git/rebase-apply &&
249 git diff --exit-code second &&
250 test_cmp_rev second HEAD &&
251 git diff first..second >diff.expected &&
252 test_cmp diff.expected diff.actual
255 test_expect_success
'am with failing pre-applypatch hook' '
256 test_when_finished "rm -f .git/hooks/pre-applypatch" &&
257 rm -fr .git/rebase-apply &&
259 git checkout first &&
260 mkdir -p .git/hooks &&
261 write_script .git/hooks/pre-applypatch <<-\EOF &&
264 test_must_fail git am patch1 &&
265 test_path_is_dir .git/rebase-apply &&
266 git diff --exit-code second &&
267 test_cmp_rev first HEAD
270 test_expect_success
'am with post-applypatch hook' '
271 test_when_finished "rm -f .git/hooks/post-applypatch" &&
272 rm -fr .git/rebase-apply &&
274 git checkout first &&
275 mkdir -p .git/hooks &&
276 write_script .git/hooks/post-applypatch <<-\EOF &&
277 git rev-parse HEAD >head.actual
278 git diff second >diff.actual
282 test_path_is_missing .git/rebase-apply &&
283 test_cmp_rev second HEAD &&
284 git rev-parse second >head.expected &&
285 test_cmp head.expected head.actual &&
286 git diff second >diff.expected &&
287 test_cmp diff.expected diff.actual
290 test_expect_success
'am with failing post-applypatch hook' '
291 test_when_finished "rm -f .git/hooks/post-applypatch" &&
292 rm -fr .git/rebase-apply &&
294 git checkout first &&
295 mkdir -p .git/hooks &&
296 write_script .git/hooks/post-applypatch <<-\EOF &&
297 git rev-parse HEAD >head.actual
301 test_path_is_missing .git/rebase-apply &&
302 git diff --exit-code second &&
303 test_cmp_rev second HEAD &&
304 git rev-parse second >head.expected &&
305 test_cmp head.expected head.actual
308 test_expect_success
'setup: new author and committer' '
309 GIT_AUTHOR_NAME="Another Thor" &&
310 GIT_AUTHOR_EMAIL="a.thor@example.com" &&
311 GIT_COMMITTER_NAME="Co M Miter" &&
312 GIT_COMMITTER_EMAIL="c.miter@example.com" &&
313 export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
317 a
=$
(git cat-file commit
"$2" |
grep "^$1 ") &&
318 b
=$
(git cat-file commit
"$3" |
grep "^$1 ") &&
322 test_expect_success
'am changes committer and keeps author' '
324 rm -fr .git/rebase-apply &&
326 git checkout first &&
328 test_path_is_missing .git/rebase-apply &&
329 test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" &&
330 git diff --exit-code master..HEAD &&
331 git diff --exit-code master^..HEAD^ &&
332 compare author master HEAD &&
333 compare author master^ HEAD^ &&
334 test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
335 "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
338 test_expect_success
'am --signoff adds Signed-off-by: line' '
339 rm -fr .git/rebase-apply &&
341 git checkout -b master2 first &&
342 git am --signoff <patch2 &&
343 printf "%s\n" "$signoff" >expected &&
344 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >>expected &&
345 git cat-file commit HEAD^ | grep "Signed-off-by:" >actual &&
346 test_cmp expected actual &&
347 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected &&
348 git cat-file commit HEAD | grep "Signed-off-by:" >actual &&
349 test_cmp expected actual
352 test_expect_success
'am stays in branch' '
353 echo refs/heads/master2 >expected &&
354 git symbolic-ref HEAD >actual &&
355 test_cmp expected actual
358 test_expect_success
'am --signoff does not add Signed-off-by: line if already there' '
359 git format-patch --stdout HEAD^ >patch3 &&
360 sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," patch3 >patch4 &&
361 rm -fr .git/rebase-apply &&
363 git checkout HEAD^ &&
364 git am --signoff patch4 &&
365 git cat-file commit HEAD >actual &&
366 test $(grep -c "^Signed-off-by:" actual) -eq 1
369 test_expect_success
'am without --keep removes Re: and [PATCH] stuff' '
370 git rev-parse HEAD >expected &&
371 git rev-parse master2 >actual &&
372 test_cmp expected actual
375 test_expect_success
'am --keep really keeps the subject' '
376 rm -fr .git/rebase-apply &&
378 git checkout HEAD^ &&
379 git am --keep patch4 &&
380 test_path_is_missing .git/rebase-apply &&
381 git cat-file commit HEAD >actual &&
382 grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
385 test_expect_success
'am --keep-non-patch really keeps the non-patch part' '
386 rm -fr .git/rebase-apply &&
388 git checkout HEAD^ &&
389 git am --keep-non-patch patch4 &&
390 test_path_is_missing .git/rebase-apply &&
391 git cat-file commit HEAD >actual &&
392 grep "^\[foo\] third" actual
395 test_expect_success
'setup am -3' '
396 rm -fr .git/rebase-apply &&
398 git checkout -b base3way master2 &&
399 sed -n -e "3,\$p" msg >file &&
400 head -n 9 msg >>file &&
403 git commit -m "copied stuff"
406 test_expect_success
'am -3 falls back to 3-way merge' '
407 rm -fr .git/rebase-apply &&
409 git checkout -b lorem2 base3way &&
410 git am -3 lorem-move.patch &&
411 test_path_is_missing .git/rebase-apply &&
412 git diff --exit-code lorem
415 test_expect_success
'am -3 -p0 can read --no-prefix patch' '
416 rm -fr .git/rebase-apply &&
418 git checkout -b lorem3 base3way &&
419 git am -3 -p0 lorem-zero.patch &&
420 test_path_is_missing .git/rebase-apply &&
421 git diff --exit-code lorem
424 test_expect_success
'am with config am.threeWay falls back to 3-way merge' '
425 rm -fr .git/rebase-apply &&
427 git checkout -b lorem4 base3way &&
428 test_config am.threeWay 1 &&
429 git am lorem-move.patch &&
430 test_path_is_missing .git/rebase-apply &&
431 git diff --exit-code lorem
434 test_expect_success
'am with config am.threeWay overridden by --no-3way' '
435 rm -fr .git/rebase-apply &&
437 git checkout -b lorem5 base3way &&
438 test_config am.threeWay 1 &&
439 test_must_fail git am --no-3way lorem-move.patch &&
440 test_path_is_dir .git/rebase-apply
443 test_expect_success
'am can rename a file' '
444 grep "^rename from" rename.patch &&
445 rm -fr .git/rebase-apply &&
447 git checkout lorem^0 &&
448 git am rename.patch &&
449 test_path_is_missing .git/rebase-apply &&
450 git update-index --refresh &&
451 git diff --exit-code rename
454 test_expect_success
'am -3 can rename a file' '
455 grep "^rename from" rename.patch &&
456 rm -fr .git/rebase-apply &&
458 git checkout lorem^0 &&
459 git am -3 rename.patch &&
460 test_path_is_missing .git/rebase-apply &&
461 git update-index --refresh &&
462 git diff --exit-code rename
465 test_expect_success
'am -3 can rename a file after falling back to 3-way merge' '
466 grep "^rename from" rename-add.patch &&
467 rm -fr .git/rebase-apply &&
469 git checkout lorem^0 &&
470 git am -3 rename-add.patch &&
471 test_path_is_missing .git/rebase-apply &&
472 git update-index --refresh &&
473 git diff --exit-code rename
476 test_expect_success
'am -3 -q is quiet' '
477 rm -fr .git/rebase-apply &&
478 git checkout -f lorem2 &&
479 git reset base3way --hard &&
480 git am -3 -q lorem-move.patch >output.out 2>&1 &&
484 test_expect_success
'am pauses on conflict' '
485 rm -fr .git/rebase-apply &&
487 git checkout lorem2^^ &&
488 test_must_fail git am lorem-move.patch &&
489 test -d .git/rebase-apply
492 test_expect_success
'am --skip works' '
493 echo goodbye >expected &&
495 test_path_is_missing .git/rebase-apply &&
496 git diff --exit-code lorem2^^ -- file &&
497 test_cmp expected another
500 test_expect_success
'am --abort removes a stray directory' '
501 mkdir .git/rebase-apply &&
503 test_path_is_missing .git/rebase-apply
506 test_expect_success
'am refuses patches when paused' '
507 rm -fr .git/rebase-apply &&
509 git checkout lorem2^^ &&
511 test_must_fail git am lorem-move.patch &&
512 test_path_is_dir .git/rebase-apply &&
513 test_cmp_rev lorem2^^ HEAD &&
515 test_must_fail git am <lorem-move.patch &&
516 test_path_is_dir .git/rebase-apply &&
517 test_cmp_rev lorem2^^ HEAD
520 test_expect_success
'am --resolved works' '
521 echo goodbye >expected &&
522 rm -fr .git/rebase-apply &&
524 git checkout lorem2^^ &&
525 test_must_fail git am lorem-move.patch &&
526 test -d .git/rebase-apply &&
527 echo resolved >>file &&
530 test_path_is_missing .git/rebase-apply &&
531 test_cmp expected another
534 test_expect_success
'am --resolved fails if index has no changes' '
535 rm -fr .git/rebase-apply &&
537 git checkout lorem2^^ &&
538 test_must_fail git am lorem-move.patch &&
539 test_path_is_dir .git/rebase-apply &&
540 test_cmp_rev lorem2^^ HEAD &&
541 test_must_fail git am --resolved &&
542 test_path_is_dir .git/rebase-apply &&
543 test_cmp_rev lorem2^^ HEAD
546 test_expect_success
'am --resolved fails if index has unmerged entries' '
547 rm -fr .git/rebase-apply &&
549 git checkout second &&
550 test_must_fail git am -3 lorem-move.patch &&
551 test_path_is_dir .git/rebase-apply &&
552 test_cmp_rev second HEAD &&
553 test_must_fail git am --resolved >err &&
554 test_path_is_dir .git/rebase-apply &&
555 test_cmp_rev second HEAD &&
556 test_i18ngrep "still have unmerged paths" err
559 test_expect_success
'am takes patches from a Pine mailbox' '
560 rm -fr .git/rebase-apply &&
562 git checkout first &&
563 cat pine patch1 | git am &&
564 test_path_is_missing .git/rebase-apply &&
565 git diff --exit-code master^..HEAD
568 test_expect_success
'am fails on mail without patch' '
569 rm -fr .git/rebase-apply &&
571 test_must_fail git am <failmail &&
573 test_path_is_missing .git/rebase-apply
576 test_expect_success
'am fails on empty patch' '
577 rm -fr .git/rebase-apply &&
579 echo "---" >>failmail &&
580 test_must_fail git am <failmail &&
582 test_path_is_missing .git/rebase-apply
585 test_expect_success
'am works from stdin in subdirectory' '
587 rm -fr .git/rebase-apply &&
589 git checkout first &&
595 git diff --exit-code second
598 test_expect_success
'am works from file (relative path given) in subdirectory' '
600 rm -fr .git/rebase-apply &&
602 git checkout first &&
608 git diff --exit-code second
611 test_expect_success
'am works from file (absolute path given) in subdirectory' '
613 rm -fr .git/rebase-apply &&
615 git checkout first &&
622 git diff --exit-code second
625 test_expect_success
'am --committer-date-is-author-date' '
626 rm -fr .git/rebase-apply &&
628 git checkout first &&
630 git am --committer-date-is-author-date patch1 &&
631 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
632 sed -ne "/^author /s/.*> //p" head1 >at &&
633 sed -ne "/^committer /s/.*> //p" head1 >ct &&
637 test_expect_success
'am without --committer-date-is-author-date' '
638 rm -fr .git/rebase-apply &&
640 git checkout first &&
643 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
644 sed -ne "/^author /s/.*> //p" head1 >at &&
645 sed -ne "/^committer /s/.*> //p" head1 >ct &&
649 # This checks for +0000 because TZ is set to UTC and that should
650 # show up when the current time is used. The date in message is set
651 # by test_tick that uses -0700 timezone; if this feature does not
652 # work, we will see that instead of +0000.
653 test_expect_success
'am --ignore-date' '
654 rm -fr .git/rebase-apply &&
656 git checkout first &&
658 git am --ignore-date patch1 &&
659 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
660 sed -ne "/^author /s/.*> //p" head1 >at &&
664 test_expect_success
'am into an unborn branch' '
665 git rev-parse first^{tree} >expected &&
666 rm -fr .git/rebase-apply &&
670 git format-patch --numbered-files -o subdir -1 first &&
678 git rev-parse HEAD^{tree} >../actual
680 test_cmp expected actual
683 test_expect_success
'am newline in subject' '
684 rm -fr .git/rebase-apply &&
686 git checkout first &&
688 sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
689 git am <patchnl >output.out 2>&1 &&
690 test_i18ngrep "^Applying: second \\\n foo$" output.out
693 test_expect_success
'am -q is quiet' '
694 rm -fr .git/rebase-apply &&
696 git checkout first &&
698 git am -q <patch1 >output.out 2>&1 &&
702 test_expect_success
'am empty-file does not infloop' '
703 rm -fr .git/rebase-apply &&
707 test_must_fail git am empty-file 2>actual &&
708 echo Patch format detection failed. >expected &&
709 test_i18ncmp expected actual
712 test_expect_success
'am --message-id really adds the message id' '
713 rm -fr .git/rebase-apply &&
715 git checkout HEAD^ &&
716 git am --message-id patch1.eml &&
717 test_path_is_missing .git/rebase-apply &&
718 git cat-file commit HEAD | tail -n1 >actual &&
719 grep Message-Id patch1.eml >expected &&
720 test_cmp expected actual
723 test_expect_success
'am.messageid really adds the message id' '
724 rm -fr .git/rebase-apply &&
726 git checkout HEAD^ &&
727 test_config am.messageid true &&
729 test_path_is_missing .git/rebase-apply &&
730 git cat-file commit HEAD | tail -n1 >actual &&
731 grep Message-Id patch1.eml >expected &&
732 test_cmp expected actual
735 test_expect_success
'am --message-id -s signs off after the message id' '
736 rm -fr .git/rebase-apply &&
738 git checkout HEAD^ &&
739 git am -s --message-id patch1.eml &&
740 test_path_is_missing .git/rebase-apply &&
741 git cat-file commit HEAD | tail -n2 | head -n1 >actual &&
742 grep Message-Id patch1.eml >expected &&
743 test_cmp expected actual