setup: merge configuration of repository formats
[git/gitster.git] / t / t4150-am.sh
blob5e2b6c80eaedfcbc1600a24c425dd4127233ff32
1 #!/bin/sh
3 test_description='git am running'
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
8 . ./test-lib.sh
10 test_expect_success 'setup: messages' '
11 cat >msg <<-\EOF &&
12 second
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.
22 EOF
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
28 Qfacilisi.
29 EOF
30 cat >>msg <<-\EOF &&
32 Lorem ipsum dolor sit amet,
33 consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
34 laoreet dolore magna aliquam erat volutpat.
36 git
37 ---
38 +++
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>
48 EOF
50 cat >failmail <<-\EOF &&
51 From foo@example.com Fri May 23 10:43:49 2008
52 From: foo@example.com
53 To: bar@example.com
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.
59 EOF
61 cat >pine <<-\EOF &&
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.
73 EOF
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.
79 EOF
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 - -
88 EOF
91 test_expect_success setup '
92 echo hello >file &&
93 git add file &&
94 test_tick &&
95 git commit -m first &&
96 git tag first &&
98 echo world >>file &&
99 git add file &&
100 test_tick &&
101 git commit -F msg &&
102 git tag second &&
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"
111 } > patch1.eml &&
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 &&
119 printf "%255s\\n" "" &&
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"
124 } > patch1-ws.eml &&
126 sed -ne "1p" msg &&
127 echo &&
128 echo "From: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" &&
129 echo "Date: $GIT_AUTHOR_DATE" &&
130 echo &&
131 sed -e "1,2d" msg &&
132 echo "---" &&
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)" &&
139 echo "patch"
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" &&
148 cat msg &&
149 echo &&
150 git diff-tree --no-commit-id -p second
151 } >patch1-hg.eml &&
154 echo file >file &&
155 git add file &&
156 git commit -F msg-without-scissors-line &&
157 git tag expected-for-scissors &&
158 git reset --hard HEAD^ &&
160 echo file >file &&
161 git add file &&
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 &&
168 git add file &&
169 test_tick &&
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 &&
177 test_tick &&
178 git commit -a -m "moved stuff" &&
180 echo goodbye >another &&
181 git add another &&
182 test_tick &&
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 &&
199 git checkout -b empty-commit &&
200 git commit -m "empty commit" --allow-empty &&
202 : >empty.patch &&
203 git format-patch --always --stdout empty-commit^ >empty-commit.patch &&
205 # reset time
206 sane_unset test_tick &&
207 test_tick
210 test_expect_success 'am applies patch correctly' '
211 rm -fr .git/rebase-apply &&
212 git reset --hard &&
213 git checkout first &&
214 test_tick &&
215 git am <patch1 &&
216 test_path_is_missing .git/rebase-apply &&
217 git diff --exit-code second &&
218 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
219 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
222 test_expect_success 'am fails if index is dirty' '
223 test_when_finished "rm -f dirtyfile" &&
224 rm -fr .git/rebase-apply &&
225 git reset --hard &&
226 git checkout first &&
227 echo dirtyfile >dirtyfile &&
228 git add dirtyfile &&
229 test_must_fail git am patch1 &&
230 test_path_is_dir .git/rebase-apply &&
231 test_cmp_rev first HEAD
234 test_expect_success 'am applies patch e-mail not in a mbox' '
235 rm -fr .git/rebase-apply &&
236 git reset --hard &&
237 git checkout first &&
238 git am patch1.eml &&
239 test_path_is_missing .git/rebase-apply &&
240 git diff --exit-code second &&
241 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
242 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
245 test_expect_success 'am applies patch e-mail not in a mbox with CRLF' '
246 rm -fr .git/rebase-apply &&
247 git reset --hard &&
248 git checkout first &&
249 git am patch1-crlf.eml &&
250 test_path_is_missing .git/rebase-apply &&
251 git diff --exit-code second &&
252 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
253 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
256 test_expect_success 'am applies patch e-mail with preceding whitespace' '
257 rm -fr .git/rebase-apply &&
258 git reset --hard &&
259 git checkout first &&
260 git am patch1-ws.eml &&
261 test_path_is_missing .git/rebase-apply &&
262 git diff --exit-code second &&
263 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
264 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
267 test_expect_success 'am applies stgit patch' '
268 rm -fr .git/rebase-apply &&
269 git checkout -f first &&
270 git am patch1-stgit.eml &&
271 test_path_is_missing .git/rebase-apply &&
272 git diff --exit-code second &&
273 test_cmp_rev second HEAD &&
274 test_cmp_rev second^ HEAD^
277 test_expect_success 'am --patch-format=stgit applies stgit patch' '
278 rm -fr .git/rebase-apply &&
279 git checkout -f first &&
280 git am --patch-format=stgit <patch1-stgit.eml &&
281 test_path_is_missing .git/rebase-apply &&
282 git diff --exit-code second &&
283 test_cmp_rev second HEAD &&
284 test_cmp_rev second^ HEAD^
287 test_expect_success 'am applies stgit series' '
288 rm -fr .git/rebase-apply &&
289 git checkout -f first &&
290 git am stgit-series/series &&
291 test_path_is_missing .git/rebase-apply &&
292 git diff --exit-code second &&
293 test_cmp_rev second HEAD &&
294 test_cmp_rev second^ HEAD^
297 test_expect_success 'am applies hg patch' '
298 rm -fr .git/rebase-apply &&
299 git checkout -f first &&
300 git am patch1-hg.eml &&
301 test_path_is_missing .git/rebase-apply &&
302 git diff --exit-code second &&
303 test_cmp_rev second HEAD &&
304 test_cmp_rev second^ HEAD^
307 test_expect_success 'am --patch-format=hg applies hg patch' '
308 rm -fr .git/rebase-apply &&
309 git checkout -f first &&
310 git am --patch-format=hg <patch1-hg.eml &&
311 test_path_is_missing .git/rebase-apply &&
312 git diff --exit-code second &&
313 test_cmp_rev second HEAD &&
314 test_cmp_rev second^ HEAD^
317 test_expect_success 'am with applypatch-msg hook' '
318 rm -fr .git/rebase-apply &&
319 git reset --hard &&
320 git checkout first &&
321 test_hook applypatch-msg <<-\EOF &&
322 cat "$1" >actual-msg &&
323 echo hook-message >"$1"
325 git am patch1 &&
326 test_path_is_missing .git/rebase-apply &&
327 git diff --exit-code second &&
328 echo hook-message >expected &&
329 git log -1 --format=format:%B >actual &&
330 test_cmp expected actual &&
331 git log -1 --format=format:%B second >expected &&
332 test_cmp expected actual-msg
335 test_expect_success 'am with failing applypatch-msg hook' '
336 rm -fr .git/rebase-apply &&
337 git reset --hard &&
338 git checkout first &&
339 test_hook applypatch-msg <<-\EOF &&
340 exit 1
342 test_must_fail git am patch1 &&
343 test_path_is_dir .git/rebase-apply &&
344 git diff --exit-code first &&
345 test_cmp_rev first HEAD
348 test_expect_success 'am with failing applypatch-msg hook (no verify)' '
349 rm -fr .git/rebase-apply &&
350 git reset --hard &&
351 git checkout first &&
352 test_hook applypatch-msg <<-\EOF &&
353 echo hook-message >"$1"
354 exit 1
356 git am --no-verify patch1 &&
357 test_path_is_missing .git/rebase-apply &&
358 git diff --exit-code second &&
359 git log -1 --format=format:%B >actual &&
360 test_cmp msg actual
363 test_expect_success 'am with pre-applypatch hook' '
364 rm -fr .git/rebase-apply &&
365 git reset --hard &&
366 git checkout first &&
367 test_hook pre-applypatch <<-\EOF &&
368 git diff first >diff.actual
369 exit 0
371 git am patch1 &&
372 test_path_is_missing .git/rebase-apply &&
373 git diff --exit-code second &&
374 test_cmp_rev second HEAD &&
375 git diff first..second >diff.expected &&
376 test_cmp diff.expected diff.actual
379 test_expect_success 'am with failing pre-applypatch hook' '
380 rm -fr .git/rebase-apply &&
381 git reset --hard &&
382 git checkout first &&
383 test_hook pre-applypatch <<-\EOF &&
384 exit 1
386 test_must_fail git am patch1 &&
387 test_path_is_dir .git/rebase-apply &&
388 git diff --exit-code second &&
389 test_cmp_rev first HEAD
392 test_expect_success 'am with failing pre-applypatch hook (no verify)' '
393 rm -fr .git/rebase-apply &&
394 git reset --hard &&
395 git checkout first &&
396 touch empty-file &&
397 test_hook pre-applypatch <<-\EOF &&
398 rm empty-file
399 exit 1
401 git am --no-verify patch1 &&
402 test_path_is_missing .git/rebase-apply &&
403 test_path_is_file empty-file &&
404 git diff --exit-code second &&
405 git log -1 --format=format:%B >actual &&
406 test_cmp msg actual
409 test_expect_success 'am with post-applypatch hook' '
410 rm -fr .git/rebase-apply &&
411 git reset --hard &&
412 git checkout first &&
413 test_hook post-applypatch <<-\EOF &&
414 git rev-parse HEAD >head.actual
415 git diff second >diff.actual
416 exit 0
418 git am patch1 &&
419 test_path_is_missing .git/rebase-apply &&
420 test_cmp_rev second HEAD &&
421 git rev-parse second >head.expected &&
422 test_cmp head.expected head.actual &&
423 git diff second >diff.expected &&
424 test_cmp diff.expected diff.actual
427 test_expect_success 'am with failing post-applypatch hook' '
428 rm -fr .git/rebase-apply &&
429 git reset --hard &&
430 git checkout first &&
431 test_hook post-applypatch <<-\EOF &&
432 git rev-parse HEAD >head.actual
433 exit 1
435 git am patch1 &&
436 test_path_is_missing .git/rebase-apply &&
437 git diff --exit-code second &&
438 test_cmp_rev second HEAD &&
439 git rev-parse second >head.expected &&
440 test_cmp head.expected head.actual
443 test_expect_success 'am --scissors cuts the message at the scissors line' '
444 rm -fr .git/rebase-apply &&
445 git reset --hard &&
446 git checkout second &&
447 git am --scissors patch-with-scissors-line.eml &&
448 test_path_is_missing .git/rebase-apply &&
449 git diff --exit-code expected-for-scissors &&
450 test_cmp_rev expected-for-scissors HEAD
453 test_expect_success 'am --no-scissors overrides mailinfo.scissors' '
454 rm -fr .git/rebase-apply &&
455 git reset --hard &&
456 git checkout second &&
457 test_config mailinfo.scissors true &&
458 git am --no-scissors patch-with-scissors-line.eml &&
459 test_path_is_missing .git/rebase-apply &&
460 git diff --exit-code expected-for-no-scissors &&
461 test_cmp_rev expected-for-no-scissors HEAD
464 test_expect_success 'setup: new author and committer' '
465 GIT_AUTHOR_NAME="Another Thor" &&
466 GIT_AUTHOR_EMAIL="a.thor@example.com" &&
467 GIT_COMMITTER_NAME="Co M Miter" &&
468 GIT_COMMITTER_EMAIL="c.miter@example.com" &&
469 export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
472 compare () {
473 a=$(git cat-file commit "$2" | grep "^$1 ") &&
474 b=$(git cat-file commit "$3" | grep "^$1 ") &&
475 test "$a" = "$b"
478 test_expect_success 'am changes committer and keeps author' '
479 test_tick &&
480 rm -fr .git/rebase-apply &&
481 git reset --hard &&
482 git checkout first &&
483 git am patch2 &&
484 test_path_is_missing .git/rebase-apply &&
485 test "$(git rev-parse main^^)" = "$(git rev-parse HEAD^^)" &&
486 git diff --exit-code main..HEAD &&
487 git diff --exit-code main^..HEAD^ &&
488 compare author main HEAD &&
489 compare author main^ HEAD^ &&
490 test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
491 "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
494 test_expect_success 'am --signoff adds Signed-off-by: line' '
495 rm -fr .git/rebase-apply &&
496 git reset --hard &&
497 git checkout -b topic_2 first &&
498 git am --signoff <patch2 &&
500 printf "third\n\nSigned-off-by: %s <%s>\n\n" \
501 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" &&
502 cat msg &&
503 printf "Signed-off-by: %s <%s>\n\n" \
504 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL"
505 } >expected-log &&
506 git log --pretty=%B -2 HEAD >actual &&
507 test_cmp expected-log actual
510 test_expect_success 'am stays in branch' '
511 echo refs/heads/topic_2 >expected &&
512 git symbolic-ref HEAD >actual &&
513 test_cmp expected actual
516 test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
517 git format-patch --stdout first >patch3 &&
518 git reset --hard first &&
519 git am --signoff <patch3 &&
520 git log --pretty=%B -2 HEAD >actual &&
521 test_cmp expected-log actual
524 test_expect_success 'am --signoff adds Signed-off-by: if another author is preset' '
525 NAME="A N Other" &&
526 EMAIL="a.n.other@example.com" &&
528 printf "third\n\nSigned-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
529 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
530 "$NAME" "$EMAIL" &&
531 cat msg &&
532 printf "Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
533 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
534 "$NAME" "$EMAIL"
535 } >expected-log &&
536 git reset --hard first &&
537 GIT_COMMITTER_NAME="$NAME" GIT_COMMITTER_EMAIL="$EMAIL" \
538 git am --signoff <patch3 &&
539 git log --pretty=%B -2 HEAD >actual &&
540 test_cmp expected-log actual
543 test_expect_success 'am --signoff duplicates Signed-off-by: if it is not the last one' '
544 NAME="A N Other" &&
545 EMAIL="a.n.other@example.com" &&
547 printf "third\n\nSigned-off-by: %s <%s>\n\
548 Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
549 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
550 "$NAME" "$EMAIL" \
551 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" &&
552 cat msg &&
553 printf "Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\
554 Signed-off-by: %s <%s>\n\n" \
555 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
556 "$NAME" "$EMAIL" \
557 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL"
558 } >expected-log &&
559 git format-patch --stdout first >patch3 &&
560 git reset --hard first &&
561 git am --signoff <patch3 &&
562 git log --pretty=%B -2 HEAD >actual &&
563 test_cmp expected-log actual
566 test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
567 git format-patch --stdout HEAD^ >tmp &&
568 sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," tmp >patch4 &&
569 git reset --hard HEAD^ &&
570 git am <patch4 &&
571 git rev-parse HEAD >expected &&
572 git rev-parse topic_2 >actual &&
573 test_cmp expected actual
576 test_expect_success 'am --keep really keeps the subject' '
577 rm -fr .git/rebase-apply &&
578 git reset --hard &&
579 git checkout HEAD^ &&
580 git am --keep patch4 &&
581 test_path_is_missing .git/rebase-apply &&
582 git cat-file commit HEAD >actual &&
583 grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
586 test_expect_success 'am --keep-non-patch really keeps the non-patch part' '
587 rm -fr .git/rebase-apply &&
588 git reset --hard &&
589 git checkout HEAD^ &&
590 git am --keep-non-patch patch4 &&
591 test_path_is_missing .git/rebase-apply &&
592 git cat-file commit HEAD >actual &&
593 grep "^\[foo\] third" actual
596 test_expect_success 'setup am -3' '
597 rm -fr .git/rebase-apply &&
598 git reset --hard &&
599 git checkout -b base3way topic_2 &&
600 sed -n -e "3,\$p" msg >file &&
601 head -n 9 msg >>file &&
602 git add file &&
603 test_tick &&
604 git commit -m "copied stuff"
607 test_expect_success 'am -3 falls back to 3-way merge' '
608 rm -fr .git/rebase-apply &&
609 git reset --hard &&
610 git checkout -b lorem2 base3way &&
611 git am -3 lorem-move.patch &&
612 test_path_is_missing .git/rebase-apply &&
613 git diff --exit-code lorem
616 test_expect_success 'am -3 -p0 can read --no-prefix patch' '
617 rm -fr .git/rebase-apply &&
618 git reset --hard &&
619 git checkout -b lorem3 base3way &&
620 git am -3 -p0 lorem-zero.patch &&
621 test_path_is_missing .git/rebase-apply &&
622 git diff --exit-code lorem
625 test_expect_success 'am with config am.threeWay falls back to 3-way merge' '
626 rm -fr .git/rebase-apply &&
627 git reset --hard &&
628 git checkout -b lorem4 base3way &&
629 test_config am.threeWay 1 &&
630 git am lorem-move.patch &&
631 test_path_is_missing .git/rebase-apply &&
632 git diff --exit-code lorem
635 test_expect_success 'am with config am.threeWay overridden by --no-3way' '
636 rm -fr .git/rebase-apply &&
637 git reset --hard &&
638 git checkout -b lorem5 base3way &&
639 test_config am.threeWay 1 &&
640 test_must_fail git am --no-3way lorem-move.patch &&
641 test_path_is_dir .git/rebase-apply
644 test_expect_success 'am can rename a file' '
645 grep "^rename from" rename.patch &&
646 rm -fr .git/rebase-apply &&
647 git reset --hard &&
648 git checkout lorem^0 &&
649 git am rename.patch &&
650 test_path_is_missing .git/rebase-apply &&
651 git update-index --refresh &&
652 git diff --exit-code rename
655 test_expect_success 'am -3 can rename a file' '
656 grep "^rename from" rename.patch &&
657 rm -fr .git/rebase-apply &&
658 git reset --hard &&
659 git checkout lorem^0 &&
660 git am -3 rename.patch &&
661 test_path_is_missing .git/rebase-apply &&
662 git update-index --refresh &&
663 git diff --exit-code rename
666 test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '
667 grep "^rename from" rename-add.patch &&
668 rm -fr .git/rebase-apply &&
669 git reset --hard &&
670 git checkout lorem^0 &&
671 git am -3 rename-add.patch &&
672 test_path_is_missing .git/rebase-apply &&
673 git update-index --refresh &&
674 git diff --exit-code rename
677 test_expect_success 'am -3 -q is quiet' '
678 rm -fr .git/rebase-apply &&
679 git checkout -f lorem2 &&
680 git reset base3way --hard &&
681 git am -3 -q lorem-move.patch >output.out 2>&1 &&
682 test_must_be_empty output.out
685 test_expect_success 'am pauses on conflict' '
686 rm -fr .git/rebase-apply &&
687 git reset --hard &&
688 git checkout lorem2^^ &&
689 test_must_fail git am lorem-move.patch &&
690 test -d .git/rebase-apply
693 test_expect_success 'am --show-current-patch' '
694 git am --show-current-patch >actual.patch &&
695 test_cmp .git/rebase-apply/0001 actual.patch
698 test_expect_success 'am --show-current-patch=raw' '
699 git am --show-current-patch=raw >actual.patch &&
700 test_cmp .git/rebase-apply/0001 actual.patch
703 test_expect_success 'am --show-current-patch=diff' '
704 git am --show-current-patch=diff >actual.patch &&
705 test_cmp .git/rebase-apply/patch actual.patch
708 test_expect_success 'am accepts repeated --show-current-patch' '
709 git am --show-current-patch --show-current-patch=raw >actual.patch &&
710 test_cmp .git/rebase-apply/0001 actual.patch
713 test_expect_success 'am detects incompatible --show-current-patch' '
714 test_must_fail git am --show-current-patch=raw --show-current-patch=diff &&
715 test_must_fail git am --show-current-patch --show-current-patch=diff
718 test_expect_success 'am --skip works' '
719 echo goodbye >expected &&
720 git am --skip &&
721 test_path_is_missing .git/rebase-apply &&
722 git diff --exit-code lorem2^^ -- file &&
723 test_cmp expected another
726 test_expect_success 'am --abort removes a stray directory' '
727 mkdir .git/rebase-apply &&
728 git am --abort &&
729 test_path_is_missing .git/rebase-apply
732 test_expect_success 'am refuses patches when paused' '
733 rm -fr .git/rebase-apply &&
734 git reset --hard &&
735 git checkout lorem2^^ &&
737 test_must_fail git am lorem-move.patch &&
738 test_path_is_dir .git/rebase-apply &&
739 test_cmp_rev lorem2^^ HEAD &&
741 test_must_fail git am <lorem-move.patch &&
742 test_path_is_dir .git/rebase-apply &&
743 test_cmp_rev lorem2^^ HEAD
746 test_expect_success 'am --resolved works' '
747 echo goodbye >expected &&
748 rm -fr .git/rebase-apply &&
749 git reset --hard &&
750 git checkout lorem2^^ &&
751 test_must_fail git am lorem-move.patch &&
752 test -d .git/rebase-apply &&
753 echo resolved >>file &&
754 git add file &&
755 git am --resolved &&
756 test_path_is_missing .git/rebase-apply &&
757 test_cmp expected another
760 test_expect_success 'am --resolved fails if index has no changes' '
761 rm -fr .git/rebase-apply &&
762 git reset --hard &&
763 git checkout lorem2^^ &&
764 test_must_fail git am lorem-move.patch &&
765 test_path_is_dir .git/rebase-apply &&
766 test_cmp_rev lorem2^^ HEAD &&
767 test_must_fail git am --resolved &&
768 test_path_is_dir .git/rebase-apply &&
769 test_cmp_rev lorem2^^ HEAD
772 test_expect_success 'am --resolved fails if index has unmerged entries' '
773 rm -fr .git/rebase-apply &&
774 git reset --hard &&
775 git checkout second &&
776 test_must_fail git am -3 lorem-move.patch &&
777 test_path_is_dir .git/rebase-apply &&
778 test_cmp_rev second HEAD &&
779 test_must_fail git am --resolved >err &&
780 test_path_is_dir .git/rebase-apply &&
781 test_cmp_rev second HEAD &&
782 test_grep "still have unmerged paths" err
785 test_expect_success 'am takes patches from a Pine mailbox' '
786 rm -fr .git/rebase-apply &&
787 git reset --hard &&
788 git checkout first &&
789 cat pine patch1 | git am &&
790 test_path_is_missing .git/rebase-apply &&
791 git diff --exit-code main^..HEAD
794 test_expect_success 'am fails on mail without patch' '
795 rm -fr .git/rebase-apply &&
796 git reset --hard &&
797 test_must_fail git am <failmail &&
798 git am --abort &&
799 test_path_is_missing .git/rebase-apply
802 test_expect_success 'am fails on empty patch' '
803 rm -fr .git/rebase-apply &&
804 git reset --hard &&
805 echo "---" >>failmail &&
806 test_must_fail git am <failmail &&
807 git am --skip &&
808 test_path_is_missing .git/rebase-apply
811 test_expect_success 'am works from stdin in subdirectory' '
812 rm -fr subdir &&
813 rm -fr .git/rebase-apply &&
814 git reset --hard &&
815 git checkout first &&
817 mkdir -p subdir &&
818 cd subdir &&
819 git am <../patch1
820 ) &&
821 git diff --exit-code second
824 test_expect_success 'am works from file (relative path given) in subdirectory' '
825 rm -fr subdir &&
826 rm -fr .git/rebase-apply &&
827 git reset --hard &&
828 git checkout first &&
830 mkdir -p subdir &&
831 cd subdir &&
832 git am ../patch1
833 ) &&
834 git diff --exit-code second
837 test_expect_success 'am works from file (absolute path given) in subdirectory' '
838 rm -fr subdir &&
839 rm -fr .git/rebase-apply &&
840 git reset --hard &&
841 git checkout first &&
842 P=$(pwd) &&
844 mkdir -p subdir &&
845 cd subdir &&
846 git am "$P/patch1"
847 ) &&
848 git diff --exit-code second
851 test_expect_success 'am --committer-date-is-author-date' '
852 rm -fr .git/rebase-apply &&
853 git reset --hard &&
854 git checkout first &&
855 test_tick &&
856 git am --committer-date-is-author-date patch1 &&
857 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
858 sed -ne "/^author /s/.*> //p" head1 >at &&
859 sed -ne "/^committer /s/.*> //p" head1 >ct &&
860 test_cmp at ct
863 test_expect_success 'am without --committer-date-is-author-date' '
864 rm -fr .git/rebase-apply &&
865 git reset --hard &&
866 git checkout first &&
867 test_tick &&
868 git am patch1 &&
869 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
870 sed -ne "/^author /s/.*> //p" head1 >at &&
871 sed -ne "/^committer /s/.*> //p" head1 >ct &&
872 ! test_cmp at ct
875 # This checks for +0000 because TZ is set to UTC and that should
876 # show up when the current time is used. The date in message is set
877 # by test_tick that uses -0700 timezone; if this feature does not
878 # work, we will see that instead of +0000.
879 test_expect_success 'am --ignore-date' '
880 rm -fr .git/rebase-apply &&
881 git reset --hard &&
882 git checkout first &&
883 test_tick &&
884 git am --ignore-date patch1 &&
885 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
886 sed -ne "/^author /s/.*> //p" head1 >at &&
887 grep "+0000" at
890 test_expect_success 'am into an unborn branch' '
891 git rev-parse first^{tree} >expected &&
892 rm -fr .git/rebase-apply &&
893 git reset --hard &&
894 rm -fr subdir &&
895 mkdir subdir &&
896 git format-patch --numbered-files -o subdir -1 first &&
898 cd subdir &&
899 git init &&
900 git am 1
901 ) &&
903 cd subdir &&
904 git rev-parse HEAD^{tree} >../actual
905 ) &&
906 test_cmp expected actual
909 test_expect_success 'am newline in subject' '
910 rm -fr .git/rebase-apply &&
911 git reset --hard &&
912 git checkout first &&
913 test_tick &&
914 sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
915 git am <patchnl >output.out 2>&1 &&
916 test_grep "^Applying: second \\\n foo$" output.out
919 test_expect_success 'am -q is quiet' '
920 rm -fr .git/rebase-apply &&
921 git reset --hard &&
922 git checkout first &&
923 test_tick &&
924 git am -q <patch1 >output.out 2>&1 &&
925 test_must_be_empty output.out
928 test_expect_success 'am empty-file does not infloop' '
929 rm -fr .git/rebase-apply &&
930 git reset --hard &&
931 touch empty-file &&
932 test_tick &&
933 test_must_fail git am empty-file 2>actual &&
934 echo Patch format detection failed. >expected &&
935 test_cmp expected actual
938 test_expect_success 'am --message-id really adds the message id' '
939 rm -fr .git/rebase-apply &&
940 git reset --hard &&
941 git checkout HEAD^ &&
942 git am --message-id patch1.eml &&
943 test_path_is_missing .git/rebase-apply &&
944 git cat-file commit HEAD | tail -n1 >actual &&
945 grep Message-ID patch1.eml >expected &&
946 test_cmp expected actual
949 test_expect_success 'am.messageid really adds the message id' '
950 rm -fr .git/rebase-apply &&
951 git reset --hard &&
952 git checkout HEAD^ &&
953 test_config am.messageid true &&
954 git am patch1.eml &&
955 test_path_is_missing .git/rebase-apply &&
956 git cat-file commit HEAD | tail -n1 >actual &&
957 grep Message-ID patch1.eml >expected &&
958 test_cmp expected actual
961 test_expect_success 'am --message-id -s signs off after the message id' '
962 rm -fr .git/rebase-apply &&
963 git reset --hard &&
964 git checkout HEAD^ &&
965 git am -s --message-id patch1.eml &&
966 test_path_is_missing .git/rebase-apply &&
967 git cat-file commit HEAD | tail -n2 | head -n1 >actual &&
968 grep Message-ID patch1.eml >expected &&
969 test_cmp expected actual
972 test_expect_success 'am -3 works with rerere' '
973 rm -fr .git/rebase-apply &&
974 git reset --hard &&
976 # make patches one->two and two->three...
977 test_commit one file &&
978 test_commit two file &&
979 test_commit three file &&
980 git format-patch -2 --stdout >seq.patch &&
982 # and create a situation that conflicts...
983 git reset --hard one &&
984 test_commit other file &&
986 # enable rerere...
987 test_config rerere.enabled true &&
988 test_when_finished "rm -rf .git/rr-cache" &&
990 # ...and apply. Our resolution is to skip the first
991 # patch, and the rerere the second one.
992 test_must_fail git am -3 seq.patch &&
993 test_must_fail git am --skip &&
994 echo resolved >file &&
995 git add file &&
996 git am --resolved &&
998 # now apply again, and confirm that rerere engaged (we still
999 # expect failure from am because rerere does not auto-commit
1000 # for us).
1001 git reset --hard other &&
1002 test_must_fail git am -3 seq.patch &&
1003 test_must_fail git am --skip &&
1004 echo resolved >expect &&
1005 test_cmp expect file
1008 test_expect_success 'am -s unexpected trailer block' '
1009 rm -fr .git/rebase-apply &&
1010 git reset --hard &&
1011 echo signed >file &&
1012 git add file &&
1013 cat >msg <<-EOF &&
1014 subject here
1016 Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
1017 [jc: tweaked log message]
1018 Signed-off-by: J C H <j@c.h>
1020 git commit -F msg &&
1021 git cat-file commit HEAD | sed -e "1,/^$/d" >original &&
1022 git format-patch --stdout -1 >patch &&
1024 git reset --hard HEAD^ &&
1025 git am -s patch &&
1027 cat original &&
1028 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
1029 ) >expect &&
1030 git cat-file commit HEAD | sed -e "1,/^$/d" >actual &&
1031 test_cmp expect actual &&
1033 cat >msg <<-\EOF &&
1034 subject here
1036 We make sure that there is a blank line between the log
1037 message proper and Signed-off-by: line added.
1039 git reset HEAD^ &&
1040 git commit -F msg file &&
1041 git cat-file commit HEAD | sed -e "1,/^$/d" >original &&
1042 git format-patch --stdout -1 >patch &&
1044 git reset --hard HEAD^ &&
1045 git am -s patch &&
1048 cat original &&
1049 echo &&
1050 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
1051 ) >expect &&
1052 git cat-file commit HEAD | sed -e "1,/^$/d" >actual &&
1053 test_cmp expect actual
1056 test_expect_success 'am --patch-format=mboxrd handles mboxrd' '
1057 rm -fr .git/rebase-apply &&
1058 git checkout -f first &&
1059 echo mboxrd >>file &&
1060 git add file &&
1061 cat >msg <<-\INPUT_END &&
1062 mboxrd should escape the body
1064 From could trip up a loose mbox parser
1065 >From extra escape for reversibility
1066 INPUT_END
1067 git commit -F msg &&
1068 git -c format.mboxrd format-patch --stdout -1 >mboxrd1 &&
1069 grep "^>From could trip up a loose mbox parser" mboxrd1 &&
1070 git checkout -f first &&
1071 git am --patch-format=mboxrd mboxrd1 &&
1072 git cat-file commit HEAD | tail -n4 >out &&
1073 test_cmp msg out
1076 test_expect_success 'am works with multi-line in-body headers' '
1077 FORTY="String that has a length of more than forty characters" &&
1078 LONG="$FORTY $FORTY" &&
1079 rm -fr .git/rebase-apply &&
1080 git checkout -f first &&
1081 echo one >> file &&
1082 git commit -am "$LONG
1084 Body test" --author="$LONG <long@example.com>" &&
1085 git format-patch --stdout -1 >patch &&
1086 # bump from, date, and subject down to in-body header
1087 perl -lpe "
1088 if (/^From:/) {
1089 print \"From: x <x\@example.com>\";
1090 print \"Date: Sat, 1 Jan 2000 00:00:00 +0000\";
1091 print \"Subject: x\n\";
1093 " patch >msg &&
1094 git checkout HEAD^ &&
1095 git am msg &&
1096 # Ensure that the author and full message are present
1097 git cat-file commit HEAD | grep "^author.*long@example.com" &&
1098 git cat-file commit HEAD | grep "^$LONG$"
1101 test_expect_success 'am --quit keeps HEAD where it is' '
1102 mkdir .git/rebase-apply &&
1103 >.git/rebase-apply/last &&
1104 >.git/rebase-apply/next &&
1105 git rev-parse HEAD^ >.git/ORIG_HEAD &&
1106 git rev-parse HEAD >expected &&
1107 git am --quit &&
1108 test_path_is_missing .git/rebase-apply &&
1109 git rev-parse HEAD >actual &&
1110 test_cmp expected actual
1113 test_expect_success 'am and .gitattibutes' '
1114 test_create_repo attributes &&
1116 cd attributes &&
1117 test_commit init &&
1118 git config filter.test.clean "sed -e '\''s/smudged/clean/g'\''" &&
1119 git config filter.test.smudge "sed -e '\''s/clean/smudged/g'\''" &&
1121 test_commit second &&
1122 git checkout -b test HEAD^ &&
1124 echo "*.txt filter=test conflict-marker-size=10" >.gitattributes &&
1125 git add .gitattributes &&
1126 test_commit third &&
1128 echo "This text is smudged." >a.txt &&
1129 git add a.txt &&
1130 test_commit fourth &&
1132 git checkout -b removal HEAD^ &&
1133 git rm .gitattributes &&
1134 git add -u &&
1135 test_commit fifth &&
1136 git cherry-pick test &&
1138 git checkout -b conflict third &&
1139 echo "This text is different." >a.txt &&
1140 git add a.txt &&
1141 test_commit sixth &&
1143 git checkout test &&
1144 git format-patch --stdout main..HEAD >patches &&
1145 git reset --hard main &&
1146 git am patches &&
1147 grep "smudged" a.txt &&
1149 git checkout removal &&
1150 git reset --hard &&
1151 git format-patch --stdout main..HEAD >patches &&
1152 git reset --hard main &&
1153 git am patches &&
1154 grep "clean" a.txt &&
1156 git checkout conflict &&
1157 git reset --hard &&
1158 git format-patch --stdout main..HEAD >patches &&
1159 git reset --hard fourth &&
1160 test_must_fail git am -3 patches &&
1161 grep "<<<<<<<<<<" a.txt
1165 test_expect_success 'apply binary blob in partial clone' '
1166 printf "\\000" >binary &&
1167 git add binary &&
1168 git commit -m "binary blob" &&
1169 git format-patch --stdout -m HEAD^ >patch &&
1171 test_create_repo server &&
1172 test_config -C server uploadpack.allowfilter 1 &&
1173 test_config -C server uploadpack.allowanysha1inwant 1 &&
1174 git clone --filter=blob:none "file://$(pwd)/server" client &&
1175 test_when_finished "rm -rf client" &&
1177 # Exercise to make sure that it works
1178 git -C client am ../patch
1181 test_expect_success 'an empty input file is error regardless of --empty option' '
1182 test_when_finished "git am --abort || :" &&
1183 test_must_fail git am --empty=drop empty.patch 2>actual &&
1184 echo "Patch format detection failed." >expected &&
1185 test_cmp expected actual
1188 test_expect_success 'invalid when passing the --empty option alone' '
1189 test_when_finished "git am --abort || :" &&
1190 git checkout empty-commit^ &&
1191 test_must_fail git am --empty empty-commit.patch 2>err &&
1192 echo "error: invalid value for '\''--empty'\'': '\''empty-commit.patch'\''" >expected &&
1193 test_cmp expected err
1196 test_expect_success 'a message without a patch is an error (default)' '
1197 test_when_finished "git am --abort || :" &&
1198 test_must_fail git am empty-commit.patch >err &&
1199 grep "Patch is empty" err
1202 test_expect_success 'a message without a patch is an error where an explicit "--empty=stop" is given' '
1203 test_when_finished "git am --abort || :" &&
1204 test_must_fail git am --empty=stop empty-commit.patch >err &&
1205 grep "Patch is empty." err
1208 test_expect_success 'a message without a patch will be skipped when "--empty=drop" is given' '
1209 git am --empty=drop empty-commit.patch >output &&
1210 git rev-parse empty-commit^ >expected &&
1211 git rev-parse HEAD >actual &&
1212 test_cmp expected actual &&
1213 grep "Skipping: empty commit" output
1216 test_expect_success 'record as an empty commit when meeting e-mail message that lacks a patch' '
1217 git am --empty=keep empty-commit.patch >output &&
1218 test_path_is_missing .git/rebase-apply &&
1219 git show empty-commit --format="%B" >expected &&
1220 git show HEAD --format="%B" >actual &&
1221 grep -f actual expected &&
1222 grep "Creating an empty commit: empty commit" output
1225 test_expect_success 'skip an empty patch in the middle of an am session' '
1226 git checkout empty-commit^ &&
1227 test_must_fail git am empty-commit.patch >out 2>err &&
1228 grep "Patch is empty." out &&
1229 grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err &&
1230 git am --skip &&
1231 test_path_is_missing .git/rebase-apply &&
1232 git rev-parse empty-commit^ >expected &&
1233 git rev-parse HEAD >actual &&
1234 test_cmp expected actual
1237 test_expect_success 'record an empty patch as an empty commit in the middle of an am session' '
1238 git checkout empty-commit^ &&
1239 test_must_fail git am empty-commit.patch >out 2>err &&
1240 grep "Patch is empty." out &&
1241 grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err &&
1242 git am --allow-empty >output &&
1243 grep "No changes - recorded it as an empty commit." output &&
1244 test_path_is_missing .git/rebase-apply &&
1245 git show empty-commit --format="%B" >expected &&
1246 git show HEAD --format="%B" >actual &&
1247 grep -f actual expected
1250 test_expect_success 'create an non-empty commit when the index IS changed though "--allow-empty" is given' '
1251 git checkout empty-commit^ &&
1252 test_must_fail git am empty-commit.patch >err &&
1253 : >empty-file &&
1254 git add empty-file &&
1255 git am --allow-empty &&
1256 git show empty-commit --format="%B" >expected &&
1257 git show HEAD --format="%B" >actual &&
1258 grep -f actual expected &&
1259 git diff HEAD^..HEAD --name-only
1262 test_expect_success 'cannot create empty commits when there is a clean index due to merge conflicts' '
1263 test_when_finished "git am --abort || :" &&
1264 git rev-parse HEAD >expected &&
1265 test_must_fail git am seq.patch &&
1266 test_must_fail git am --allow-empty >err &&
1267 ! grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err &&
1268 git rev-parse HEAD >actual &&
1269 test_cmp actual expected
1272 test_expect_success 'cannot create empty commits when there is unmerged index due to merge conflicts' '
1273 test_when_finished "git am --abort || :" &&
1274 git rev-parse HEAD >expected &&
1275 test_must_fail git am -3 seq.patch &&
1276 test_must_fail git am --allow-empty >err &&
1277 ! grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err &&
1278 git rev-parse HEAD >actual &&
1279 test_cmp actual expected
1282 test_done