3 test_description='git am running'
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
10 test_expect_success 'setup: messages' '
14 Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, sed diam nonumy
15 eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
16 voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita
17 kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem
18 ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
19 tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At
20 vero eos et accusam et justo duo dolores et ea rebum.
23 qz_to_tab_space <<-\EOF >>msg &&
24 QDuis autem vel eum iriure dolor in hendrerit in vulputate velit
25 Qesse molestie consequat, vel illum dolore eu feugiat nulla facilisis
26 Qat vero eros et accumsan et iusto odio dignissim qui blandit
27 Qpraesent luptatum zzril delenit augue duis dolore te feugait nulla
32 Lorem ipsum dolor sit amet,
33 consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
34 laoreet dolore magna aliquam erat volutpat.
40 Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit
41 lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure
42 dolor in hendrerit in vulputate velit esse molestie consequat, vel illum
43 dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
44 dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te
45 feugait nulla facilisi.
47 Reported-by: A N Other <a.n.other@example.com>
50 cat >failmail <<-\EOF &&
51 From foo@example.com Fri May 23 10:43:49 2008
54 Subject: Re: [RFC/PATCH] git-foo.sh
55 Date: Fri, 23 May 2008 05:23:42 +0200
57 Sometimes we have to find out that there'\''s nothing left.
62 From MAILER-DAEMON Fri May 23 10:43:49 2008
63 Date: 23 May 2008 05:23:42 +0200
64 From: Mail System Internal Data <MAILER-DAEMON@example.com>
65 Subject: DON'\''T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA
66 Message-ID: <foo-0001@example.com>
68 This text is part of the internal format of your mail folder, and is not
69 a real message. It is created automatically by the mail system software.
70 If deleted, important folder data will be lost, and it will be re-created
71 with the data reset to initial values.
75 cat >msg-without-scissors-line <<-\EOF &&
76 Test that git-am --scissors cuts at the scissors line
78 This line should be included in the commit message.
81 printf "Subject: " >subject-prefix &&
83 cat - subject-prefix msg-without-scissors-line >msg-with-scissors-line <<-\EOF
84 This line should not be included in the commit message with --scissors enabled.
86 - - >8 - - remove everything above this line - - >8 - -
91 test_expect_success setup '
95 git commit -m first &&
104 git format-patch --stdout first >patch1 &&
106 echo "Message-Id: <1226501681-24923-1-git-send-email-bda@mnsspb.ru>" &&
107 echo "X-Fake-Field: Line One" &&
108 echo "X-Fake-Field: Line Two" &&
109 echo "X-Fake-Field: Line Three" &&
110 git format-patch --stdout first | sed -e "1d"
113 echo "X-Fake-Field: Line One" &&
114 echo "X-Fake-Field: Line Two" &&
115 echo "X-Fake-Field: Line Three" &&
116 git format-patch --stdout first | sed -e "1d"
117 } | append_cr >patch1-crlf.eml &&
120 echo "X-Fake-Field: Line One" &&
121 echo "X-Fake-Field: Line Two" &&
122 echo "X-Fake-Field: Line Three" &&
123 git format-patch --stdout first | sed -e "1d"
128 echo "From: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" &&
129 echo "Date: $GIT_AUTHOR_DATE" &&
133 git diff-tree --no-commit-id --stat -p second
134 } >patch1-stgit.eml &&
135 mkdir stgit-series &&
136 cp patch1-stgit.eml stgit-series/patch &&
138 echo "# This series applies on GIT commit $(git rev-parse first)" &&
140 } >stgit-series/series &&
142 echo "# HG changeset patch" &&
143 echo "# User $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" &&
144 echo "# Date $test_tick 25200" &&
145 echo "# $(git show --pretty="%aD" -s second)" &&
146 echo "# Node ID $ZERO_OID" &&
147 echo "# Parent $ZERO_OID" &&
150 git diff-tree --no-commit-id -p second
156 git commit -F msg-without-scissors-line &&
157 git tag expected-for-scissors &&
158 git reset --hard HEAD^ &&
162 git commit -F msg-with-scissors-line &&
163 git tag expected-for-no-scissors &&
164 git format-patch --stdout expected-for-no-scissors^ >patch-with-scissors-line.eml &&
165 git reset --hard HEAD^ &&
167 sed -n -e "3,\$p" msg >file &&
170 git commit -m third &&
172 git format-patch --stdout first >patch2 &&
174 git checkout -b lorem &&
175 sed -n -e "11,\$p" msg >file &&
176 head -n 9 msg >>file &&
178 git commit -a -m "moved stuff" &&
180 echo goodbye >another &&
183 git commit -m "added another file" &&
185 git format-patch --stdout main >lorem-move.patch &&
186 git format-patch --no-prefix --stdout main >lorem-zero.patch &&
188 git checkout -b rename &&
189 git mv file renamed &&
190 git commit -m "renamed a file" &&
192 git format-patch -M --stdout lorem >rename.patch &&
194 git reset --soft lorem^ &&
195 git commit -m "renamed a file and added another" &&
197 git format-patch -M --stdout lorem^ >rename-add.patch &&
200 sane_unset test_tick &&
204 test_expect_success 'am applies patch correctly' '
205 rm -fr .git/rebase-apply &&
207 git checkout first &&
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^)"
216 test_expect_success 'am fails if index is dirty' '
217 test_when_finished "rm -f dirtyfile" &&
218 rm -fr .git/rebase-apply &&
220 git checkout first &&
221 echo dirtyfile >dirtyfile &&
223 test_must_fail git am patch1 &&
224 test_path_is_dir .git/rebase-apply &&
225 test_cmp_rev first HEAD
228 test_expect_success 'am applies patch e-mail not in a mbox' '
229 rm -fr .git/rebase-apply &&
231 git checkout first &&
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^)"
239 test_expect_success 'am applies patch e-mail not in a mbox with CRLF' '
240 rm -fr .git/rebase-apply &&
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^)"
250 test_expect_success 'am applies patch e-mail with preceding whitespace' '
251 rm -fr .git/rebase-apply &&
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^)"
261 test_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^
271 test_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^
281 test_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^
291 test_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^
301 test_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^
311 test_expect_success 'am with applypatch-msg hook' '
312 test_when_finished "rm -f .git/hooks/applypatch-msg" &&
313 rm -fr .git/rebase-apply &&
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"
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
331 test_expect_success 'am with failing applypatch-msg hook' '
332 test_when_finished "rm -f .git/hooks/applypatch-msg" &&
333 rm -fr .git/rebase-apply &&
335 git checkout first &&
336 mkdir -p .git/hooks &&
337 write_script .git/hooks/applypatch-msg <<-\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
346 test_expect_success 'am with pre-applypatch hook' '
347 test_when_finished "rm -f .git/hooks/pre-applypatch" &&
348 rm -fr .git/rebase-apply &&
350 git checkout first &&
351 mkdir -p .git/hooks &&
352 write_script .git/hooks/pre-applypatch <<-\EOF &&
353 git diff first >diff.actual
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
364 test_expect_success 'am with failing pre-applypatch hook' '
365 test_when_finished "rm -f .git/hooks/pre-applypatch" &&
366 rm -fr .git/rebase-apply &&
368 git checkout first &&
369 mkdir -p .git/hooks &&
370 write_script .git/hooks/pre-applypatch <<-\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
379 test_expect_success 'am with post-applypatch hook' '
380 test_when_finished "rm -f .git/hooks/post-applypatch" &&
381 rm -fr .git/rebase-apply &&
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
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
399 test_expect_success 'am with failing post-applypatch hook' '
400 test_when_finished "rm -f .git/hooks/post-applypatch" &&
401 rm -fr .git/rebase-apply &&
403 git checkout first &&
404 mkdir -p .git/hooks &&
405 write_script .git/hooks/post-applypatch <<-\EOF &&
406 git rev-parse HEAD >head.actual
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
417 test_expect_success 'am --scissors cuts the message at the scissors line' '
418 rm -fr .git/rebase-apply &&
420 git checkout second &&
421 git am --scissors patch-with-scissors-line.eml &&
422 test_path_is_missing .git/rebase-apply &&
423 git diff --exit-code expected-for-scissors &&
424 test_cmp_rev expected-for-scissors HEAD
427 test_expect_success 'am --no-scissors overrides mailinfo.scissors' '
428 rm -fr .git/rebase-apply &&
430 git checkout second &&
431 test_config mailinfo.scissors true &&
432 git am --no-scissors patch-with-scissors-line.eml &&
433 test_path_is_missing .git/rebase-apply &&
434 git diff --exit-code expected-for-no-scissors &&
435 test_cmp_rev expected-for-no-scissors HEAD
438 test_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
447 a=$(git cat-file commit "$2" | grep "^$1 ") &&
448 b=$(git cat-file commit "$3" | grep "^$1 ") &&
452 test_expect_success 'am changes committer and keeps author' '
454 rm -fr .git/rebase-apply &&
456 git checkout first &&
458 test_path_is_missing .git/rebase-apply &&
459 test "$(git rev-parse main^^)" = "$(git rev-parse HEAD^^)" &&
460 git diff --exit-code main..HEAD &&
461 git diff --exit-code main^..HEAD^ &&
462 compare author main HEAD &&
463 compare author main^ HEAD^ &&
464 test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
465 "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
468 test_expect_success 'am --signoff adds Signed-off-by: line' '
469 rm -fr .git/rebase-apply &&
471 git checkout -b topic_2 first &&
472 git am --signoff <patch2 &&
474 printf "third\n\nSigned-off-by: %s <%s>\n\n" \
475 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" &&
477 printf "Signed-off-by: %s <%s>\n\n" \
478 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL"
480 git log --pretty=%B -2 HEAD >actual &&
481 test_cmp expected-log actual
484 test_expect_success 'am stays in branch' '
485 echo refs/heads/topic_2 >expected &&
486 git symbolic-ref HEAD >actual &&
487 test_cmp expected actual
490 test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
491 git format-patch --stdout first >patch3 &&
492 git reset --hard first &&
493 git am --signoff <patch3 &&
494 git log --pretty=%B -2 HEAD >actual &&
495 test_cmp expected-log actual
498 test_expect_success 'am --signoff adds Signed-off-by: if another author is preset' '
500 EMAIL="a.n.other@example.com" &&
502 printf "third\n\nSigned-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
503 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
506 printf "Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
507 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
510 git reset --hard first &&
511 GIT_COMMITTER_NAME="$NAME" GIT_COMMITTER_EMAIL="$EMAIL" \
512 git am --signoff <patch3 &&
513 git log --pretty=%B -2 HEAD >actual &&
514 test_cmp expected-log actual
517 test_expect_success 'am --signoff duplicates Signed-off-by: if it is not the last one' '
519 EMAIL="a.n.other@example.com" &&
521 printf "third\n\nSigned-off-by: %s <%s>\n\
522 Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
523 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
525 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" &&
527 printf "Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\
528 Signed-off-by: %s <%s>\n\n" \
529 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
531 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL"
533 git format-patch --stdout first >patch3 &&
534 git reset --hard first &&
535 git am --signoff <patch3 &&
536 git log --pretty=%B -2 HEAD >actual &&
537 test_cmp expected-log actual
540 test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
541 git format-patch --stdout HEAD^ >tmp &&
542 sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," tmp >patch4 &&
543 git reset --hard HEAD^ &&
545 git rev-parse HEAD >expected &&
546 git rev-parse topic_2 >actual &&
547 test_cmp expected actual
550 test_expect_success 'am --keep really keeps the subject' '
551 rm -fr .git/rebase-apply &&
553 git checkout HEAD^ &&
554 git am --keep patch4 &&
555 test_path_is_missing .git/rebase-apply &&
556 git cat-file commit HEAD >actual &&
557 grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
560 test_expect_success 'am --keep-non-patch really keeps the non-patch part' '
561 rm -fr .git/rebase-apply &&
563 git checkout HEAD^ &&
564 git am --keep-non-patch patch4 &&
565 test_path_is_missing .git/rebase-apply &&
566 git cat-file commit HEAD >actual &&
567 grep "^\[foo\] third" actual
570 test_expect_success 'setup am -3' '
571 rm -fr .git/rebase-apply &&
573 git checkout -b base3way topic_2 &&
574 sed -n -e "3,\$p" msg >file &&
575 head -n 9 msg >>file &&
578 git commit -m "copied stuff"
581 test_expect_success 'am -3 falls back to 3-way merge' '
582 rm -fr .git/rebase-apply &&
584 git checkout -b lorem2 base3way &&
585 git am -3 lorem-move.patch &&
586 test_path_is_missing .git/rebase-apply &&
587 git diff --exit-code lorem
590 test_expect_success 'am -3 -p0 can read --no-prefix patch' '
591 rm -fr .git/rebase-apply &&
593 git checkout -b lorem3 base3way &&
594 git am -3 -p0 lorem-zero.patch &&
595 test_path_is_missing .git/rebase-apply &&
596 git diff --exit-code lorem
599 test_expect_success 'am with config am.threeWay falls back to 3-way merge' '
600 rm -fr .git/rebase-apply &&
602 git checkout -b lorem4 base3way &&
603 test_config am.threeWay 1 &&
604 git am lorem-move.patch &&
605 test_path_is_missing .git/rebase-apply &&
606 git diff --exit-code lorem
609 test_expect_success 'am with config am.threeWay overridden by --no-3way' '
610 rm -fr .git/rebase-apply &&
612 git checkout -b lorem5 base3way &&
613 test_config am.threeWay 1 &&
614 test_must_fail git am --no-3way lorem-move.patch &&
615 test_path_is_dir .git/rebase-apply
618 test_expect_success 'am can rename a file' '
619 grep "^rename from" rename.patch &&
620 rm -fr .git/rebase-apply &&
622 git checkout lorem^0 &&
623 git am rename.patch &&
624 test_path_is_missing .git/rebase-apply &&
625 git update-index --refresh &&
626 git diff --exit-code rename
629 test_expect_success 'am -3 can rename a file' '
630 grep "^rename from" rename.patch &&
631 rm -fr .git/rebase-apply &&
633 git checkout lorem^0 &&
634 git am -3 rename.patch &&
635 test_path_is_missing .git/rebase-apply &&
636 git update-index --refresh &&
637 git diff --exit-code rename
640 test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '
641 grep "^rename from" rename-add.patch &&
642 rm -fr .git/rebase-apply &&
644 git checkout lorem^0 &&
645 git am -3 rename-add.patch &&
646 test_path_is_missing .git/rebase-apply &&
647 git update-index --refresh &&
648 git diff --exit-code rename
651 test_expect_success 'am -3 -q is quiet' '
652 rm -fr .git/rebase-apply &&
653 git checkout -f lorem2 &&
654 git reset base3way --hard &&
655 git am -3 -q lorem-move.patch >output.out 2>&1 &&
656 test_must_be_empty output.out
659 test_expect_success 'am pauses on conflict' '
660 rm -fr .git/rebase-apply &&
662 git checkout lorem2^^ &&
663 test_must_fail git am lorem-move.patch &&
664 test -d .git/rebase-apply
667 test_expect_success 'am --show-current-patch' '
668 git am --show-current-patch >actual.patch &&
669 test_cmp .git/rebase-apply/0001 actual.patch
672 test_expect_success 'am --show-current-patch=raw' '
673 git am --show-current-patch=raw >actual.patch &&
674 test_cmp .git/rebase-apply/0001 actual.patch
677 test_expect_success 'am --show-current-patch=diff' '
678 git am --show-current-patch=diff >actual.patch &&
679 test_cmp .git/rebase-apply/patch actual.patch
682 test_expect_success 'am accepts repeated --show-current-patch' '
683 git am --show-current-patch --show-current-patch=raw >actual.patch &&
684 test_cmp .git/rebase-apply/0001 actual.patch
687 test_expect_success 'am detects incompatible --show-current-patch' '
688 test_must_fail git am --show-current-patch=raw --show-current-patch=diff &&
689 test_must_fail git am --show-current-patch --show-current-patch=diff
692 test_expect_success 'am --skip works' '
693 echo goodbye >expected &&
695 test_path_is_missing .git/rebase-apply &&
696 git diff --exit-code lorem2^^ -- file &&
697 test_cmp expected another
700 test_expect_success 'am --abort removes a stray directory' '
701 mkdir .git/rebase-apply &&
703 test_path_is_missing .git/rebase-apply
706 test_expect_success 'am refuses patches when paused' '
707 rm -fr .git/rebase-apply &&
709 git checkout lorem2^^ &&
711 test_must_fail git am lorem-move.patch &&
712 test_path_is_dir .git/rebase-apply &&
713 test_cmp_rev lorem2^^ HEAD &&
715 test_must_fail git am <lorem-move.patch &&
716 test_path_is_dir .git/rebase-apply &&
717 test_cmp_rev lorem2^^ HEAD
720 test_expect_success 'am --resolved works' '
721 echo goodbye >expected &&
722 rm -fr .git/rebase-apply &&
724 git checkout lorem2^^ &&
725 test_must_fail git am lorem-move.patch &&
726 test -d .git/rebase-apply &&
727 echo resolved >>file &&
730 test_path_is_missing .git/rebase-apply &&
731 test_cmp expected another
734 test_expect_success 'am --resolved fails if index has no changes' '
735 rm -fr .git/rebase-apply &&
737 git checkout lorem2^^ &&
738 test_must_fail git am lorem-move.patch &&
739 test_path_is_dir .git/rebase-apply &&
740 test_cmp_rev lorem2^^ HEAD &&
741 test_must_fail git am --resolved &&
742 test_path_is_dir .git/rebase-apply &&
743 test_cmp_rev lorem2^^ HEAD
746 test_expect_success 'am --resolved fails if index has unmerged entries' '
747 rm -fr .git/rebase-apply &&
749 git checkout second &&
750 test_must_fail git am -3 lorem-move.patch &&
751 test_path_is_dir .git/rebase-apply &&
752 test_cmp_rev second HEAD &&
753 test_must_fail git am --resolved >err &&
754 test_path_is_dir .git/rebase-apply &&
755 test_cmp_rev second HEAD &&
756 test_i18ngrep "still have unmerged paths" err
759 test_expect_success 'am takes patches from a Pine mailbox' '
760 rm -fr .git/rebase-apply &&
762 git checkout first &&
763 cat pine patch1 | git am &&
764 test_path_is_missing .git/rebase-apply &&
765 git diff --exit-code main^..HEAD
768 test_expect_success 'am fails on mail without patch' '
769 rm -fr .git/rebase-apply &&
771 test_must_fail git am <failmail &&
773 test_path_is_missing .git/rebase-apply
776 test_expect_success 'am fails on empty patch' '
777 rm -fr .git/rebase-apply &&
779 echo "---" >>failmail &&
780 test_must_fail git am <failmail &&
782 test_path_is_missing .git/rebase-apply
785 test_expect_success 'am works from stdin in subdirectory' '
787 rm -fr .git/rebase-apply &&
789 git checkout first &&
795 git diff --exit-code second
798 test_expect_success 'am works from file (relative path given) in subdirectory' '
800 rm -fr .git/rebase-apply &&
802 git checkout first &&
808 git diff --exit-code second
811 test_expect_success 'am works from file (absolute path given) in subdirectory' '
813 rm -fr .git/rebase-apply &&
815 git checkout first &&
822 git diff --exit-code second
825 test_expect_success 'am --committer-date-is-author-date' '
826 rm -fr .git/rebase-apply &&
828 git checkout first &&
830 git am --committer-date-is-author-date patch1 &&
831 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
832 sed -ne "/^author /s/.*> //p" head1 >at &&
833 sed -ne "/^committer /s/.*> //p" head1 >ct &&
837 test_expect_success 'am without --committer-date-is-author-date' '
838 rm -fr .git/rebase-apply &&
840 git checkout first &&
843 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
844 sed -ne "/^author /s/.*> //p" head1 >at &&
845 sed -ne "/^committer /s/.*> //p" head1 >ct &&
849 # This checks for +0000 because TZ is set to UTC and that should
850 # show up when the current time is used. The date in message is set
851 # by test_tick that uses -0700 timezone; if this feature does not
852 # work, we will see that instead of +0000.
853 test_expect_success 'am --ignore-date' '
854 rm -fr .git/rebase-apply &&
856 git checkout first &&
858 git am --ignore-date patch1 &&
859 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
860 sed -ne "/^author /s/.*> //p" head1 >at &&
864 test_expect_success 'am into an unborn branch' '
865 git rev-parse first^{tree} >expected &&
866 rm -fr .git/rebase-apply &&
870 git format-patch --numbered-files -o subdir -1 first &&
878 git rev-parse HEAD^{tree} >../actual
880 test_cmp expected actual
883 test_expect_success 'am newline in subject' '
884 rm -fr .git/rebase-apply &&
886 git checkout first &&
888 sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
889 git am <patchnl >output.out 2>&1 &&
890 test_i18ngrep "^Applying: second \\\n foo$" output.out
893 test_expect_success 'am -q is quiet' '
894 rm -fr .git/rebase-apply &&
896 git checkout first &&
898 git am -q <patch1 >output.out 2>&1 &&
899 test_must_be_empty output.out
902 test_expect_success 'am empty-file does not infloop' '
903 rm -fr .git/rebase-apply &&
907 test_must_fail git am empty-file 2>actual &&
908 echo Patch format detection failed. >expected &&
909 test_cmp expected actual
912 test_expect_success 'am --message-id really adds the message id' '
913 rm -fr .git/rebase-apply &&
915 git checkout HEAD^ &&
916 git am --message-id patch1.eml &&
917 test_path_is_missing .git/rebase-apply &&
918 git cat-file commit HEAD | tail -n1 >actual &&
919 grep Message-Id patch1.eml >expected &&
920 test_cmp expected actual
923 test_expect_success 'am.messageid really adds the message id' '
924 rm -fr .git/rebase-apply &&
926 git checkout HEAD^ &&
927 test_config am.messageid true &&
929 test_path_is_missing .git/rebase-apply &&
930 git cat-file commit HEAD | tail -n1 >actual &&
931 grep Message-Id patch1.eml >expected &&
932 test_cmp expected actual
935 test_expect_success 'am --message-id -s signs off after the message id' '
936 rm -fr .git/rebase-apply &&
938 git checkout HEAD^ &&
939 git am -s --message-id patch1.eml &&
940 test_path_is_missing .git/rebase-apply &&
941 git cat-file commit HEAD | tail -n2 | head -n1 >actual &&
942 grep Message-Id patch1.eml >expected &&
943 test_cmp expected actual
946 test_expect_success 'am -3 works with rerere' '
947 rm -fr .git/rebase-apply &&
950 # make patches one->two and two->three...
951 test_commit one file &&
952 test_commit two file &&
953 test_commit three file &&
954 git format-patch -2 --stdout >seq.patch &&
956 # and create a situation that conflicts...
957 git reset --hard one &&
958 test_commit other file &&
961 test_config rerere.enabled true &&
962 test_when_finished "rm -rf .git/rr-cache" &&
964 # ...and apply. Our resolution is to skip the first
965 # patch, and the rerere the second one.
966 test_must_fail git am -3 seq.patch &&
967 test_must_fail git am --skip &&
968 echo resolved >file &&
972 # now apply again, and confirm that rerere engaged (we still
973 # expect failure from am because rerere does not auto-commit
975 git reset --hard other &&
976 test_must_fail git am -3 seq.patch &&
977 test_must_fail git am --skip &&
978 echo resolved >expect &&
982 test_expect_success 'am -s unexpected trailer block' '
983 rm -fr .git/rebase-apply &&
990 Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
991 [jc: tweaked log message]
992 Signed-off-by: J C H <j@c.h>
995 git cat-file commit HEAD | sed -e "1,/^$/d" >original &&
996 git format-patch --stdout -1 >patch &&
998 git reset --hard HEAD^ &&
1002 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
1004 git cat-file commit HEAD | sed -e "1,/^$/d" >actual &&
1005 test_cmp expect actual &&
1010 We make sure that there is a blank line between the log
1011 message proper and Signed-off-by: line added.
1014 git commit -F msg file &&
1015 git cat-file commit HEAD | sed -e "1,/^$/d" >original &&
1016 git format-patch --stdout -1 >patch &&
1018 git reset --hard HEAD^ &&
1024 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
1026 git cat-file commit HEAD | sed -e "1,/^$/d" >actual &&
1027 test_cmp expect actual
1030 test_expect_success 'am --patch-format=mboxrd handles mboxrd' '
1031 rm -fr .git/rebase-apply &&
1032 git checkout -f first &&
1033 echo mboxrd >>file &&
1035 cat >msg <<-\INPUT_END &&
1036 mboxrd should escape the body
1038 From could trip up a loose mbox parser
1039 >From extra escape for reversibility
1041 git commit -F msg &&
1042 git format-patch --pretty=mboxrd --stdout -1 >mboxrd1 &&
1043 grep "^>From could trip up a loose mbox parser" mboxrd1 &&
1044 git checkout -f first &&
1045 git am --patch-format=mboxrd mboxrd1 &&
1046 git cat-file commit HEAD | tail -n4 >out &&
1050 test_expect_success 'am works with multi-line in-body headers' '
1051 FORTY="String that has a length of more than forty characters" &&
1052 LONG="$FORTY $FORTY" &&
1053 rm -fr .git/rebase-apply &&
1054 git checkout -f first &&
1056 git commit -am "$LONG
1058 Body test" --author="$LONG <long@example.com>" &&
1059 git format-patch --stdout -1 >patch &&
1060 # bump from, date, and subject down to in-body header
1063 print \"From: x <x\@example.com>\";
1064 print \"Date: Sat, 1 Jan 2000 00:00:00 +0000\";
1065 print \"Subject: x\n\";
1068 git checkout HEAD^ &&
1070 # Ensure that the author and full message are present
1071 git cat-file commit HEAD | grep "^author.*long@example.com" &&
1072 git cat-file commit HEAD | grep "^$LONG$"
1075 test_expect_success 'am --quit keeps HEAD where it is' '
1076 mkdir .git/rebase-apply &&
1077 >.git/rebase-apply/last &&
1078 >.git/rebase-apply/next &&
1079 git rev-parse HEAD^ >.git/ORIG_HEAD &&
1080 git rev-parse HEAD >expected &&
1082 test_path_is_missing .git/rebase-apply &&
1083 git rev-parse HEAD >actual &&
1084 test_cmp expected actual
1087 test_expect_success 'am and .gitattibutes' '
1088 test_create_repo attributes &&
1092 git config filter.test.clean "sed -e '\''s/smudged/clean/g'\''" &&
1093 git config filter.test.smudge "sed -e '\''s/clean/smudged/g'\''" &&
1095 test_commit second &&
1096 git checkout -b test HEAD^ &&
1098 echo "*.txt filter=test conflict-marker-size=10" >.gitattributes &&
1099 git add .gitattributes &&
1100 test_commit third &&
1102 echo "This text is smudged." >a.txt &&
1104 test_commit fourth &&
1106 git checkout -b removal HEAD^ &&
1107 git rm .gitattributes &&
1109 test_commit fifth &&
1110 git cherry-pick test &&
1112 git checkout -b conflict third &&
1113 echo "This text is different." >a.txt &&
1115 test_commit sixth &&
1117 git checkout test &&
1118 git format-patch --stdout main..HEAD >patches &&
1119 git reset --hard main &&
1121 grep "smudged" a.txt &&
1123 git checkout removal &&
1125 git format-patch --stdout main..HEAD >patches &&
1126 git reset --hard main &&
1128 grep "clean" a.txt &&
1130 git checkout conflict &&
1132 git format-patch --stdout main..HEAD >patches &&
1133 git reset --hard fourth &&
1134 test_must_fail git am -3 patches &&
1135 grep "<<<<<<<<<<" a.txt
1139 test_expect_success 'apply binary blob in partial clone' '
1140 printf "\\000" >binary &&
1142 git commit -m "binary blob" &&
1143 git format-patch --stdout -m HEAD^ >patch &&
1145 test_create_repo server &&
1146 test_config -C server uploadpack.allowfilter 1 &&
1147 test_config -C server uploadpack.allowanysha1inwant 1 &&
1148 git clone --filter=blob:none "file://$(pwd)/server" client &&
1149 test_when_finished "rm -rf client" &&
1151 # Exercise to make sure that it works
1152 git -C client am ../patch