rebase: use correct base for --keep-base when a branch is given
[alt-git.git] / t / t4150-am.sh
blobcdad4b688078adc24da922bce14e130982f4484e
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 pre-applypatch hook' '
349 rm -fr .git/rebase-apply &&
350 git reset --hard &&
351 git checkout first &&
352 test_hook pre-applypatch <<-\EOF &&
353 git diff first >diff.actual
354 exit 0
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
364 test_expect_success 'am with failing pre-applypatch hook' '
365 rm -fr .git/rebase-apply &&
366 git reset --hard &&
367 git checkout first &&
368 test_hook pre-applypatch <<-\EOF &&
369 exit 1
371 test_must_fail git am patch1 &&
372 test_path_is_dir .git/rebase-apply &&
373 git diff --exit-code second &&
374 test_cmp_rev first HEAD
377 test_expect_success 'am with post-applypatch hook' '
378 rm -fr .git/rebase-apply &&
379 git reset --hard &&
380 git checkout first &&
381 test_hook post-applypatch <<-\EOF &&
382 git rev-parse HEAD >head.actual
383 git diff second >diff.actual
384 exit 0
386 git am patch1 &&
387 test_path_is_missing .git/rebase-apply &&
388 test_cmp_rev second HEAD &&
389 git rev-parse second >head.expected &&
390 test_cmp head.expected head.actual &&
391 git diff second >diff.expected &&
392 test_cmp diff.expected diff.actual
395 test_expect_success 'am with failing post-applypatch hook' '
396 rm -fr .git/rebase-apply &&
397 git reset --hard &&
398 git checkout first &&
399 test_hook post-applypatch <<-\EOF &&
400 git rev-parse HEAD >head.actual
401 exit 1
403 git am patch1 &&
404 test_path_is_missing .git/rebase-apply &&
405 git diff --exit-code second &&
406 test_cmp_rev second HEAD &&
407 git rev-parse second >head.expected &&
408 test_cmp head.expected head.actual
411 test_expect_success 'am --scissors cuts the message at the scissors line' '
412 rm -fr .git/rebase-apply &&
413 git reset --hard &&
414 git checkout second &&
415 git am --scissors patch-with-scissors-line.eml &&
416 test_path_is_missing .git/rebase-apply &&
417 git diff --exit-code expected-for-scissors &&
418 test_cmp_rev expected-for-scissors HEAD
421 test_expect_success 'am --no-scissors overrides mailinfo.scissors' '
422 rm -fr .git/rebase-apply &&
423 git reset --hard &&
424 git checkout second &&
425 test_config mailinfo.scissors true &&
426 git am --no-scissors patch-with-scissors-line.eml &&
427 test_path_is_missing .git/rebase-apply &&
428 git diff --exit-code expected-for-no-scissors &&
429 test_cmp_rev expected-for-no-scissors HEAD
432 test_expect_success 'setup: new author and committer' '
433 GIT_AUTHOR_NAME="Another Thor" &&
434 GIT_AUTHOR_EMAIL="a.thor@example.com" &&
435 GIT_COMMITTER_NAME="Co M Miter" &&
436 GIT_COMMITTER_EMAIL="c.miter@example.com" &&
437 export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
440 compare () {
441 a=$(git cat-file commit "$2" | grep "^$1 ") &&
442 b=$(git cat-file commit "$3" | grep "^$1 ") &&
443 test "$a" = "$b"
446 test_expect_success 'am changes committer and keeps author' '
447 test_tick &&
448 rm -fr .git/rebase-apply &&
449 git reset --hard &&
450 git checkout first &&
451 git am patch2 &&
452 test_path_is_missing .git/rebase-apply &&
453 test "$(git rev-parse main^^)" = "$(git rev-parse HEAD^^)" &&
454 git diff --exit-code main..HEAD &&
455 git diff --exit-code main^..HEAD^ &&
456 compare author main HEAD &&
457 compare author main^ HEAD^ &&
458 test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
459 "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
462 test_expect_success 'am --signoff adds Signed-off-by: line' '
463 rm -fr .git/rebase-apply &&
464 git reset --hard &&
465 git checkout -b topic_2 first &&
466 git am --signoff <patch2 &&
468 printf "third\n\nSigned-off-by: %s <%s>\n\n" \
469 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" &&
470 cat msg &&
471 printf "Signed-off-by: %s <%s>\n\n" \
472 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL"
473 } >expected-log &&
474 git log --pretty=%B -2 HEAD >actual &&
475 test_cmp expected-log actual
478 test_expect_success 'am stays in branch' '
479 echo refs/heads/topic_2 >expected &&
480 git symbolic-ref HEAD >actual &&
481 test_cmp expected actual
484 test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
485 git format-patch --stdout first >patch3 &&
486 git reset --hard first &&
487 git am --signoff <patch3 &&
488 git log --pretty=%B -2 HEAD >actual &&
489 test_cmp expected-log actual
492 test_expect_success 'am --signoff adds Signed-off-by: if another author is preset' '
493 NAME="A N Other" &&
494 EMAIL="a.n.other@example.com" &&
496 printf "third\n\nSigned-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
497 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
498 "$NAME" "$EMAIL" &&
499 cat msg &&
500 printf "Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
501 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
502 "$NAME" "$EMAIL"
503 } >expected-log &&
504 git reset --hard first &&
505 GIT_COMMITTER_NAME="$NAME" GIT_COMMITTER_EMAIL="$EMAIL" \
506 git am --signoff <patch3 &&
507 git log --pretty=%B -2 HEAD >actual &&
508 test_cmp expected-log actual
511 test_expect_success 'am --signoff duplicates Signed-off-by: if it is not the last one' '
512 NAME="A N Other" &&
513 EMAIL="a.n.other@example.com" &&
515 printf "third\n\nSigned-off-by: %s <%s>\n\
516 Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
517 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
518 "$NAME" "$EMAIL" \
519 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" &&
520 cat msg &&
521 printf "Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\
522 Signed-off-by: %s <%s>\n\n" \
523 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
524 "$NAME" "$EMAIL" \
525 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL"
526 } >expected-log &&
527 git format-patch --stdout first >patch3 &&
528 git reset --hard first &&
529 git am --signoff <patch3 &&
530 git log --pretty=%B -2 HEAD >actual &&
531 test_cmp expected-log actual
534 test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
535 git format-patch --stdout HEAD^ >tmp &&
536 sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," tmp >patch4 &&
537 git reset --hard HEAD^ &&
538 git am <patch4 &&
539 git rev-parse HEAD >expected &&
540 git rev-parse topic_2 >actual &&
541 test_cmp expected actual
544 test_expect_success 'am --keep really keeps the subject' '
545 rm -fr .git/rebase-apply &&
546 git reset --hard &&
547 git checkout HEAD^ &&
548 git am --keep patch4 &&
549 test_path_is_missing .git/rebase-apply &&
550 git cat-file commit HEAD >actual &&
551 grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
554 test_expect_success 'am --keep-non-patch really keeps the non-patch part' '
555 rm -fr .git/rebase-apply &&
556 git reset --hard &&
557 git checkout HEAD^ &&
558 git am --keep-non-patch patch4 &&
559 test_path_is_missing .git/rebase-apply &&
560 git cat-file commit HEAD >actual &&
561 grep "^\[foo\] third" actual
564 test_expect_success 'setup am -3' '
565 rm -fr .git/rebase-apply &&
566 git reset --hard &&
567 git checkout -b base3way topic_2 &&
568 sed -n -e "3,\$p" msg >file &&
569 head -n 9 msg >>file &&
570 git add file &&
571 test_tick &&
572 git commit -m "copied stuff"
575 test_expect_success 'am -3 falls back to 3-way merge' '
576 rm -fr .git/rebase-apply &&
577 git reset --hard &&
578 git checkout -b lorem2 base3way &&
579 git am -3 lorem-move.patch &&
580 test_path_is_missing .git/rebase-apply &&
581 git diff --exit-code lorem
584 test_expect_success 'am -3 -p0 can read --no-prefix patch' '
585 rm -fr .git/rebase-apply &&
586 git reset --hard &&
587 git checkout -b lorem3 base3way &&
588 git am -3 -p0 lorem-zero.patch &&
589 test_path_is_missing .git/rebase-apply &&
590 git diff --exit-code lorem
593 test_expect_success 'am with config am.threeWay falls back to 3-way merge' '
594 rm -fr .git/rebase-apply &&
595 git reset --hard &&
596 git checkout -b lorem4 base3way &&
597 test_config am.threeWay 1 &&
598 git am lorem-move.patch &&
599 test_path_is_missing .git/rebase-apply &&
600 git diff --exit-code lorem
603 test_expect_success 'am with config am.threeWay overridden by --no-3way' '
604 rm -fr .git/rebase-apply &&
605 git reset --hard &&
606 git checkout -b lorem5 base3way &&
607 test_config am.threeWay 1 &&
608 test_must_fail git am --no-3way lorem-move.patch &&
609 test_path_is_dir .git/rebase-apply
612 test_expect_success 'am can rename a file' '
613 grep "^rename from" rename.patch &&
614 rm -fr .git/rebase-apply &&
615 git reset --hard &&
616 git checkout lorem^0 &&
617 git am rename.patch &&
618 test_path_is_missing .git/rebase-apply &&
619 git update-index --refresh &&
620 git diff --exit-code rename
623 test_expect_success 'am -3 can rename a file' '
624 grep "^rename from" rename.patch &&
625 rm -fr .git/rebase-apply &&
626 git reset --hard &&
627 git checkout lorem^0 &&
628 git am -3 rename.patch &&
629 test_path_is_missing .git/rebase-apply &&
630 git update-index --refresh &&
631 git diff --exit-code rename
634 test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '
635 grep "^rename from" rename-add.patch &&
636 rm -fr .git/rebase-apply &&
637 git reset --hard &&
638 git checkout lorem^0 &&
639 git am -3 rename-add.patch &&
640 test_path_is_missing .git/rebase-apply &&
641 git update-index --refresh &&
642 git diff --exit-code rename
645 test_expect_success 'am -3 -q is quiet' '
646 rm -fr .git/rebase-apply &&
647 git checkout -f lorem2 &&
648 git reset base3way --hard &&
649 git am -3 -q lorem-move.patch >output.out 2>&1 &&
650 test_must_be_empty output.out
653 test_expect_success 'am pauses on conflict' '
654 rm -fr .git/rebase-apply &&
655 git reset --hard &&
656 git checkout lorem2^^ &&
657 test_must_fail git am lorem-move.patch &&
658 test -d .git/rebase-apply
661 test_expect_success 'am --show-current-patch' '
662 git am --show-current-patch >actual.patch &&
663 test_cmp .git/rebase-apply/0001 actual.patch
666 test_expect_success 'am --show-current-patch=raw' '
667 git am --show-current-patch=raw >actual.patch &&
668 test_cmp .git/rebase-apply/0001 actual.patch
671 test_expect_success 'am --show-current-patch=diff' '
672 git am --show-current-patch=diff >actual.patch &&
673 test_cmp .git/rebase-apply/patch actual.patch
676 test_expect_success 'am accepts repeated --show-current-patch' '
677 git am --show-current-patch --show-current-patch=raw >actual.patch &&
678 test_cmp .git/rebase-apply/0001 actual.patch
681 test_expect_success 'am detects incompatible --show-current-patch' '
682 test_must_fail git am --show-current-patch=raw --show-current-patch=diff &&
683 test_must_fail git am --show-current-patch --show-current-patch=diff
686 test_expect_success 'am --skip works' '
687 echo goodbye >expected &&
688 git am --skip &&
689 test_path_is_missing .git/rebase-apply &&
690 git diff --exit-code lorem2^^ -- file &&
691 test_cmp expected another
694 test_expect_success 'am --abort removes a stray directory' '
695 mkdir .git/rebase-apply &&
696 git am --abort &&
697 test_path_is_missing .git/rebase-apply
700 test_expect_success 'am refuses patches when paused' '
701 rm -fr .git/rebase-apply &&
702 git reset --hard &&
703 git checkout lorem2^^ &&
705 test_must_fail git am lorem-move.patch &&
706 test_path_is_dir .git/rebase-apply &&
707 test_cmp_rev lorem2^^ HEAD &&
709 test_must_fail git am <lorem-move.patch &&
710 test_path_is_dir .git/rebase-apply &&
711 test_cmp_rev lorem2^^ HEAD
714 test_expect_success 'am --resolved works' '
715 echo goodbye >expected &&
716 rm -fr .git/rebase-apply &&
717 git reset --hard &&
718 git checkout lorem2^^ &&
719 test_must_fail git am lorem-move.patch &&
720 test -d .git/rebase-apply &&
721 echo resolved >>file &&
722 git add file &&
723 git am --resolved &&
724 test_path_is_missing .git/rebase-apply &&
725 test_cmp expected another
728 test_expect_success 'am --resolved fails if index has no changes' '
729 rm -fr .git/rebase-apply &&
730 git reset --hard &&
731 git checkout lorem2^^ &&
732 test_must_fail git am lorem-move.patch &&
733 test_path_is_dir .git/rebase-apply &&
734 test_cmp_rev lorem2^^ HEAD &&
735 test_must_fail git am --resolved &&
736 test_path_is_dir .git/rebase-apply &&
737 test_cmp_rev lorem2^^ HEAD
740 test_expect_success 'am --resolved fails if index has unmerged entries' '
741 rm -fr .git/rebase-apply &&
742 git reset --hard &&
743 git checkout second &&
744 test_must_fail git am -3 lorem-move.patch &&
745 test_path_is_dir .git/rebase-apply &&
746 test_cmp_rev second HEAD &&
747 test_must_fail git am --resolved >err &&
748 test_path_is_dir .git/rebase-apply &&
749 test_cmp_rev second HEAD &&
750 test_i18ngrep "still have unmerged paths" err
753 test_expect_success 'am takes patches from a Pine mailbox' '
754 rm -fr .git/rebase-apply &&
755 git reset --hard &&
756 git checkout first &&
757 cat pine patch1 | git am &&
758 test_path_is_missing .git/rebase-apply &&
759 git diff --exit-code main^..HEAD
762 test_expect_success 'am fails on mail without patch' '
763 rm -fr .git/rebase-apply &&
764 git reset --hard &&
765 test_must_fail git am <failmail &&
766 git am --abort &&
767 test_path_is_missing .git/rebase-apply
770 test_expect_success 'am fails on empty patch' '
771 rm -fr .git/rebase-apply &&
772 git reset --hard &&
773 echo "---" >>failmail &&
774 test_must_fail git am <failmail &&
775 git am --skip &&
776 test_path_is_missing .git/rebase-apply
779 test_expect_success 'am works from stdin in subdirectory' '
780 rm -fr subdir &&
781 rm -fr .git/rebase-apply &&
782 git reset --hard &&
783 git checkout first &&
785 mkdir -p subdir &&
786 cd subdir &&
787 git am <../patch1
788 ) &&
789 git diff --exit-code second
792 test_expect_success 'am works from file (relative path given) in subdirectory' '
793 rm -fr subdir &&
794 rm -fr .git/rebase-apply &&
795 git reset --hard &&
796 git checkout first &&
798 mkdir -p subdir &&
799 cd subdir &&
800 git am ../patch1
801 ) &&
802 git diff --exit-code second
805 test_expect_success 'am works from file (absolute path given) in subdirectory' '
806 rm -fr subdir &&
807 rm -fr .git/rebase-apply &&
808 git reset --hard &&
809 git checkout first &&
810 P=$(pwd) &&
812 mkdir -p subdir &&
813 cd subdir &&
814 git am "$P/patch1"
815 ) &&
816 git diff --exit-code second
819 test_expect_success 'am --committer-date-is-author-date' '
820 rm -fr .git/rebase-apply &&
821 git reset --hard &&
822 git checkout first &&
823 test_tick &&
824 git am --committer-date-is-author-date patch1 &&
825 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
826 sed -ne "/^author /s/.*> //p" head1 >at &&
827 sed -ne "/^committer /s/.*> //p" head1 >ct &&
828 test_cmp at ct
831 test_expect_success 'am without --committer-date-is-author-date' '
832 rm -fr .git/rebase-apply &&
833 git reset --hard &&
834 git checkout first &&
835 test_tick &&
836 git am patch1 &&
837 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
838 sed -ne "/^author /s/.*> //p" head1 >at &&
839 sed -ne "/^committer /s/.*> //p" head1 >ct &&
840 ! test_cmp at ct
843 # This checks for +0000 because TZ is set to UTC and that should
844 # show up when the current time is used. The date in message is set
845 # by test_tick that uses -0700 timezone; if this feature does not
846 # work, we will see that instead of +0000.
847 test_expect_success 'am --ignore-date' '
848 rm -fr .git/rebase-apply &&
849 git reset --hard &&
850 git checkout first &&
851 test_tick &&
852 git am --ignore-date patch1 &&
853 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
854 sed -ne "/^author /s/.*> //p" head1 >at &&
855 grep "+0000" at
858 test_expect_success 'am into an unborn branch' '
859 git rev-parse first^{tree} >expected &&
860 rm -fr .git/rebase-apply &&
861 git reset --hard &&
862 rm -fr subdir &&
863 mkdir subdir &&
864 git format-patch --numbered-files -o subdir -1 first &&
866 cd subdir &&
867 git init &&
868 git am 1
869 ) &&
871 cd subdir &&
872 git rev-parse HEAD^{tree} >../actual
873 ) &&
874 test_cmp expected actual
877 test_expect_success 'am newline in subject' '
878 rm -fr .git/rebase-apply &&
879 git reset --hard &&
880 git checkout first &&
881 test_tick &&
882 sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
883 git am <patchnl >output.out 2>&1 &&
884 test_i18ngrep "^Applying: second \\\n foo$" output.out
887 test_expect_success 'am -q is quiet' '
888 rm -fr .git/rebase-apply &&
889 git reset --hard &&
890 git checkout first &&
891 test_tick &&
892 git am -q <patch1 >output.out 2>&1 &&
893 test_must_be_empty output.out
896 test_expect_success 'am empty-file does not infloop' '
897 rm -fr .git/rebase-apply &&
898 git reset --hard &&
899 touch empty-file &&
900 test_tick &&
901 test_must_fail git am empty-file 2>actual &&
902 echo Patch format detection failed. >expected &&
903 test_cmp expected actual
906 test_expect_success 'am --message-id really adds the message id' '
907 rm -fr .git/rebase-apply &&
908 git reset --hard &&
909 git checkout HEAD^ &&
910 git am --message-id patch1.eml &&
911 test_path_is_missing .git/rebase-apply &&
912 git cat-file commit HEAD | tail -n1 >actual &&
913 grep Message-Id patch1.eml >expected &&
914 test_cmp expected actual
917 test_expect_success 'am.messageid really adds the message id' '
918 rm -fr .git/rebase-apply &&
919 git reset --hard &&
920 git checkout HEAD^ &&
921 test_config am.messageid true &&
922 git am patch1.eml &&
923 test_path_is_missing .git/rebase-apply &&
924 git cat-file commit HEAD | tail -n1 >actual &&
925 grep Message-Id patch1.eml >expected &&
926 test_cmp expected actual
929 test_expect_success 'am --message-id -s signs off after the message id' '
930 rm -fr .git/rebase-apply &&
931 git reset --hard &&
932 git checkout HEAD^ &&
933 git am -s --message-id patch1.eml &&
934 test_path_is_missing .git/rebase-apply &&
935 git cat-file commit HEAD | tail -n2 | head -n1 >actual &&
936 grep Message-Id patch1.eml >expected &&
937 test_cmp expected actual
940 test_expect_success 'am -3 works with rerere' '
941 rm -fr .git/rebase-apply &&
942 git reset --hard &&
944 # make patches one->two and two->three...
945 test_commit one file &&
946 test_commit two file &&
947 test_commit three file &&
948 git format-patch -2 --stdout >seq.patch &&
950 # and create a situation that conflicts...
951 git reset --hard one &&
952 test_commit other file &&
954 # enable rerere...
955 test_config rerere.enabled true &&
956 test_when_finished "rm -rf .git/rr-cache" &&
958 # ...and apply. Our resolution is to skip the first
959 # patch, and the rerere the second one.
960 test_must_fail git am -3 seq.patch &&
961 test_must_fail git am --skip &&
962 echo resolved >file &&
963 git add file &&
964 git am --resolved &&
966 # now apply again, and confirm that rerere engaged (we still
967 # expect failure from am because rerere does not auto-commit
968 # for us).
969 git reset --hard other &&
970 test_must_fail git am -3 seq.patch &&
971 test_must_fail git am --skip &&
972 echo resolved >expect &&
973 test_cmp expect file
976 test_expect_success 'am -s unexpected trailer block' '
977 rm -fr .git/rebase-apply &&
978 git reset --hard &&
979 echo signed >file &&
980 git add file &&
981 cat >msg <<-EOF &&
982 subject here
984 Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
985 [jc: tweaked log message]
986 Signed-off-by: J C H <j@c.h>
988 git commit -F msg &&
989 git cat-file commit HEAD | sed -e "1,/^$/d" >original &&
990 git format-patch --stdout -1 >patch &&
992 git reset --hard HEAD^ &&
993 git am -s patch &&
995 cat original &&
996 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
997 ) >expect &&
998 git cat-file commit HEAD | sed -e "1,/^$/d" >actual &&
999 test_cmp expect actual &&
1001 cat >msg <<-\EOF &&
1002 subject here
1004 We make sure that there is a blank line between the log
1005 message proper and Signed-off-by: line added.
1007 git reset HEAD^ &&
1008 git commit -F msg file &&
1009 git cat-file commit HEAD | sed -e "1,/^$/d" >original &&
1010 git format-patch --stdout -1 >patch &&
1012 git reset --hard HEAD^ &&
1013 git am -s patch &&
1016 cat original &&
1017 echo &&
1018 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
1019 ) >expect &&
1020 git cat-file commit HEAD | sed -e "1,/^$/d" >actual &&
1021 test_cmp expect actual
1024 test_expect_success 'am --patch-format=mboxrd handles mboxrd' '
1025 rm -fr .git/rebase-apply &&
1026 git checkout -f first &&
1027 echo mboxrd >>file &&
1028 git add file &&
1029 cat >msg <<-\INPUT_END &&
1030 mboxrd should escape the body
1032 From could trip up a loose mbox parser
1033 >From extra escape for reversibility
1034 INPUT_END
1035 git commit -F msg &&
1036 git format-patch --pretty=mboxrd --stdout -1 >mboxrd1 &&
1037 grep "^>From could trip up a loose mbox parser" mboxrd1 &&
1038 git checkout -f first &&
1039 git am --patch-format=mboxrd mboxrd1 &&
1040 git cat-file commit HEAD | tail -n4 >out &&
1041 test_cmp msg out
1044 test_expect_success 'am works with multi-line in-body headers' '
1045 FORTY="String that has a length of more than forty characters" &&
1046 LONG="$FORTY $FORTY" &&
1047 rm -fr .git/rebase-apply &&
1048 git checkout -f first &&
1049 echo one >> file &&
1050 git commit -am "$LONG
1052 Body test" --author="$LONG <long@example.com>" &&
1053 git format-patch --stdout -1 >patch &&
1054 # bump from, date, and subject down to in-body header
1055 perl -lpe "
1056 if (/^From:/) {
1057 print \"From: x <x\@example.com>\";
1058 print \"Date: Sat, 1 Jan 2000 00:00:00 +0000\";
1059 print \"Subject: x\n\";
1061 " patch >msg &&
1062 git checkout HEAD^ &&
1063 git am msg &&
1064 # Ensure that the author and full message are present
1065 git cat-file commit HEAD | grep "^author.*long@example.com" &&
1066 git cat-file commit HEAD | grep "^$LONG$"
1069 test_expect_success 'am --quit keeps HEAD where it is' '
1070 mkdir .git/rebase-apply &&
1071 >.git/rebase-apply/last &&
1072 >.git/rebase-apply/next &&
1073 git rev-parse HEAD^ >.git/ORIG_HEAD &&
1074 git rev-parse HEAD >expected &&
1075 git am --quit &&
1076 test_path_is_missing .git/rebase-apply &&
1077 git rev-parse HEAD >actual &&
1078 test_cmp expected actual
1081 test_expect_success 'am and .gitattibutes' '
1082 test_create_repo attributes &&
1084 cd attributes &&
1085 test_commit init &&
1086 git config filter.test.clean "sed -e '\''s/smudged/clean/g'\''" &&
1087 git config filter.test.smudge "sed -e '\''s/clean/smudged/g'\''" &&
1089 test_commit second &&
1090 git checkout -b test HEAD^ &&
1092 echo "*.txt filter=test conflict-marker-size=10" >.gitattributes &&
1093 git add .gitattributes &&
1094 test_commit third &&
1096 echo "This text is smudged." >a.txt &&
1097 git add a.txt &&
1098 test_commit fourth &&
1100 git checkout -b removal HEAD^ &&
1101 git rm .gitattributes &&
1102 git add -u &&
1103 test_commit fifth &&
1104 git cherry-pick test &&
1106 git checkout -b conflict third &&
1107 echo "This text is different." >a.txt &&
1108 git add a.txt &&
1109 test_commit sixth &&
1111 git checkout test &&
1112 git format-patch --stdout main..HEAD >patches &&
1113 git reset --hard main &&
1114 git am patches &&
1115 grep "smudged" a.txt &&
1117 git checkout removal &&
1118 git reset --hard &&
1119 git format-patch --stdout main..HEAD >patches &&
1120 git reset --hard main &&
1121 git am patches &&
1122 grep "clean" a.txt &&
1124 git checkout conflict &&
1125 git reset --hard &&
1126 git format-patch --stdout main..HEAD >patches &&
1127 git reset --hard fourth &&
1128 test_must_fail git am -3 patches &&
1129 grep "<<<<<<<<<<" a.txt
1133 test_expect_success 'apply binary blob in partial clone' '
1134 printf "\\000" >binary &&
1135 git add binary &&
1136 git commit -m "binary blob" &&
1137 git format-patch --stdout -m HEAD^ >patch &&
1139 test_create_repo server &&
1140 test_config -C server uploadpack.allowfilter 1 &&
1141 test_config -C server uploadpack.allowanysha1inwant 1 &&
1142 git clone --filter=blob:none "file://$(pwd)/server" client &&
1143 test_when_finished "rm -rf client" &&
1145 # Exercise to make sure that it works
1146 git -C client am ../patch
1149 test_expect_success 'an empty input file is error regardless of --empty option' '
1150 test_when_finished "git am --abort || :" &&
1151 test_must_fail git am --empty=drop empty.patch 2>actual &&
1152 echo "Patch format detection failed." >expected &&
1153 test_cmp expected actual
1156 test_expect_success 'invalid when passing the --empty option alone' '
1157 test_when_finished "git am --abort || :" &&
1158 git checkout empty-commit^ &&
1159 test_must_fail git am --empty empty-commit.patch 2>err &&
1160 echo "error: invalid value for '\''--empty'\'': '\''empty-commit.patch'\''" >expected &&
1161 test_cmp expected err
1164 test_expect_success 'a message without a patch is an error (default)' '
1165 test_when_finished "git am --abort || :" &&
1166 test_must_fail git am empty-commit.patch >err &&
1167 grep "Patch is empty" err
1170 test_expect_success 'a message without a patch is an error where an explicit "--empty=stop" is given' '
1171 test_when_finished "git am --abort || :" &&
1172 test_must_fail git am --empty=stop empty-commit.patch >err &&
1173 grep "Patch is empty." err
1176 test_expect_success 'a message without a patch will be skipped when "--empty=drop" is given' '
1177 git am --empty=drop empty-commit.patch >output &&
1178 git rev-parse empty-commit^ >expected &&
1179 git rev-parse HEAD >actual &&
1180 test_cmp expected actual &&
1181 grep "Skipping: empty commit" output
1184 test_expect_success 'record as an empty commit when meeting e-mail message that lacks a patch' '
1185 git am --empty=keep empty-commit.patch >output &&
1186 test_path_is_missing .git/rebase-apply &&
1187 git show empty-commit --format="%B" >expected &&
1188 git show HEAD --format="%B" >actual &&
1189 grep -f actual expected &&
1190 grep "Creating an empty commit: empty commit" output
1193 test_expect_success 'skip an empty patch in the middle of an am session' '
1194 git checkout empty-commit^ &&
1195 test_must_fail git am empty-commit.patch >err &&
1196 grep "Patch is empty." err &&
1197 grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err &&
1198 git am --skip &&
1199 test_path_is_missing .git/rebase-apply &&
1200 git rev-parse empty-commit^ >expected &&
1201 git rev-parse HEAD >actual &&
1202 test_cmp expected actual
1205 test_expect_success 'record an empty patch as an empty commit in the middle of an am session' '
1206 git checkout empty-commit^ &&
1207 test_must_fail git am empty-commit.patch >err &&
1208 grep "Patch is empty." err &&
1209 grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err &&
1210 git am --allow-empty >output &&
1211 grep "No changes - recorded it as an empty commit." output &&
1212 test_path_is_missing .git/rebase-apply &&
1213 git show empty-commit --format="%B" >expected &&
1214 git show HEAD --format="%B" >actual &&
1215 grep -f actual expected
1218 test_expect_success 'create an non-empty commit when the index IS changed though "--allow-empty" is given' '
1219 git checkout empty-commit^ &&
1220 test_must_fail git am empty-commit.patch >err &&
1221 : >empty-file &&
1222 git add empty-file &&
1223 git am --allow-empty &&
1224 git show empty-commit --format="%B" >expected &&
1225 git show HEAD --format="%B" >actual &&
1226 grep -f actual expected &&
1227 git diff HEAD^..HEAD --name-only
1230 test_expect_success 'cannot create empty commits when there is a clean index due to merge conflicts' '
1231 test_when_finished "git am --abort || :" &&
1232 git rev-parse HEAD >expected &&
1233 test_must_fail git am seq.patch &&
1234 test_must_fail git am --allow-empty >err &&
1235 ! grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err &&
1236 git rev-parse HEAD >actual &&
1237 test_cmp actual expected
1240 test_expect_success 'cannot create empty commits when there is unmerged index due to merge conflicts' '
1241 test_when_finished "git am --abort || :" &&
1242 git rev-parse HEAD >expected &&
1243 test_must_fail git am -3 seq.patch &&
1244 test_must_fail git am --allow-empty >err &&
1245 ! grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err &&
1246 git rev-parse HEAD >actual &&
1247 test_cmp actual expected
1250 test_done