Merge branch 'jd/prompt-upstream-mark'
[alt-git.git] / t / t4150-am.sh
blob159fae8d0162a3d1f0543d28a9817f156b45df5c
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 test_when_finished "rm -f .git/hooks/applypatch-msg" &&
319 rm -fr .git/rebase-apply &&
320 git reset --hard &&
321 git checkout first &&
322 mkdir -p .git/hooks &&
323 write_script .git/hooks/applypatch-msg <<-\EOF &&
324 cat "$1" >actual-msg &&
325 echo hook-message >"$1"
327 git am patch1 &&
328 test_path_is_missing .git/rebase-apply &&
329 git diff --exit-code second &&
330 echo hook-message >expected &&
331 git log -1 --format=format:%B >actual &&
332 test_cmp expected actual &&
333 git log -1 --format=format:%B second >expected &&
334 test_cmp expected actual-msg
337 test_expect_success 'am with failing applypatch-msg hook' '
338 test_when_finished "rm -f .git/hooks/applypatch-msg" &&
339 rm -fr .git/rebase-apply &&
340 git reset --hard &&
341 git checkout first &&
342 mkdir -p .git/hooks &&
343 write_script .git/hooks/applypatch-msg <<-\EOF &&
344 exit 1
346 test_must_fail git am patch1 &&
347 test_path_is_dir .git/rebase-apply &&
348 git diff --exit-code first &&
349 test_cmp_rev first HEAD
352 test_expect_success 'am with pre-applypatch hook' '
353 test_when_finished "rm -f .git/hooks/pre-applypatch" &&
354 rm -fr .git/rebase-apply &&
355 git reset --hard &&
356 git checkout first &&
357 mkdir -p .git/hooks &&
358 write_script .git/hooks/pre-applypatch <<-\EOF &&
359 git diff first >diff.actual
360 exit 0
362 git am patch1 &&
363 test_path_is_missing .git/rebase-apply &&
364 git diff --exit-code second &&
365 test_cmp_rev second HEAD &&
366 git diff first..second >diff.expected &&
367 test_cmp diff.expected diff.actual
370 test_expect_success 'am with failing pre-applypatch hook' '
371 test_when_finished "rm -f .git/hooks/pre-applypatch" &&
372 rm -fr .git/rebase-apply &&
373 git reset --hard &&
374 git checkout first &&
375 mkdir -p .git/hooks &&
376 write_script .git/hooks/pre-applypatch <<-\EOF &&
377 exit 1
379 test_must_fail git am patch1 &&
380 test_path_is_dir .git/rebase-apply &&
381 git diff --exit-code second &&
382 test_cmp_rev first HEAD
385 test_expect_success 'am with post-applypatch hook' '
386 test_when_finished "rm -f .git/hooks/post-applypatch" &&
387 rm -fr .git/rebase-apply &&
388 git reset --hard &&
389 git checkout first &&
390 mkdir -p .git/hooks &&
391 write_script .git/hooks/post-applypatch <<-\EOF &&
392 git rev-parse HEAD >head.actual
393 git diff second >diff.actual
394 exit 0
396 git am patch1 &&
397 test_path_is_missing .git/rebase-apply &&
398 test_cmp_rev second HEAD &&
399 git rev-parse second >head.expected &&
400 test_cmp head.expected head.actual &&
401 git diff second >diff.expected &&
402 test_cmp diff.expected diff.actual
405 test_expect_success 'am with failing post-applypatch hook' '
406 test_when_finished "rm -f .git/hooks/post-applypatch" &&
407 rm -fr .git/rebase-apply &&
408 git reset --hard &&
409 git checkout first &&
410 mkdir -p .git/hooks &&
411 write_script .git/hooks/post-applypatch <<-\EOF &&
412 git rev-parse HEAD >head.actual
413 exit 1
415 git am patch1 &&
416 test_path_is_missing .git/rebase-apply &&
417 git diff --exit-code second &&
418 test_cmp_rev second HEAD &&
419 git rev-parse second >head.expected &&
420 test_cmp head.expected head.actual
423 test_expect_success 'am --scissors cuts the message at the scissors line' '
424 rm -fr .git/rebase-apply &&
425 git reset --hard &&
426 git checkout second &&
427 git am --scissors patch-with-scissors-line.eml &&
428 test_path_is_missing .git/rebase-apply &&
429 git diff --exit-code expected-for-scissors &&
430 test_cmp_rev expected-for-scissors HEAD
433 test_expect_success 'am --no-scissors overrides mailinfo.scissors' '
434 rm -fr .git/rebase-apply &&
435 git reset --hard &&
436 git checkout second &&
437 test_config mailinfo.scissors true &&
438 git am --no-scissors patch-with-scissors-line.eml &&
439 test_path_is_missing .git/rebase-apply &&
440 git diff --exit-code expected-for-no-scissors &&
441 test_cmp_rev expected-for-no-scissors HEAD
444 test_expect_success 'setup: new author and committer' '
445 GIT_AUTHOR_NAME="Another Thor" &&
446 GIT_AUTHOR_EMAIL="a.thor@example.com" &&
447 GIT_COMMITTER_NAME="Co M Miter" &&
448 GIT_COMMITTER_EMAIL="c.miter@example.com" &&
449 export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
452 compare () {
453 a=$(git cat-file commit "$2" | grep "^$1 ") &&
454 b=$(git cat-file commit "$3" | grep "^$1 ") &&
455 test "$a" = "$b"
458 test_expect_success 'am changes committer and keeps author' '
459 test_tick &&
460 rm -fr .git/rebase-apply &&
461 git reset --hard &&
462 git checkout first &&
463 git am patch2 &&
464 test_path_is_missing .git/rebase-apply &&
465 test "$(git rev-parse main^^)" = "$(git rev-parse HEAD^^)" &&
466 git diff --exit-code main..HEAD &&
467 git diff --exit-code main^..HEAD^ &&
468 compare author main HEAD &&
469 compare author main^ HEAD^ &&
470 test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
471 "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
474 test_expect_success 'am --signoff adds Signed-off-by: line' '
475 rm -fr .git/rebase-apply &&
476 git reset --hard &&
477 git checkout -b topic_2 first &&
478 git am --signoff <patch2 &&
480 printf "third\n\nSigned-off-by: %s <%s>\n\n" \
481 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" &&
482 cat msg &&
483 printf "Signed-off-by: %s <%s>\n\n" \
484 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL"
485 } >expected-log &&
486 git log --pretty=%B -2 HEAD >actual &&
487 test_cmp expected-log actual
490 test_expect_success 'am stays in branch' '
491 echo refs/heads/topic_2 >expected &&
492 git symbolic-ref HEAD >actual &&
493 test_cmp expected actual
496 test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
497 git format-patch --stdout first >patch3 &&
498 git reset --hard first &&
499 git am --signoff <patch3 &&
500 git log --pretty=%B -2 HEAD >actual &&
501 test_cmp expected-log actual
504 test_expect_success 'am --signoff adds Signed-off-by: if another author is preset' '
505 NAME="A N Other" &&
506 EMAIL="a.n.other@example.com" &&
508 printf "third\n\nSigned-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
509 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
510 "$NAME" "$EMAIL" &&
511 cat msg &&
512 printf "Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
513 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
514 "$NAME" "$EMAIL"
515 } >expected-log &&
516 git reset --hard first &&
517 GIT_COMMITTER_NAME="$NAME" GIT_COMMITTER_EMAIL="$EMAIL" \
518 git am --signoff <patch3 &&
519 git log --pretty=%B -2 HEAD >actual &&
520 test_cmp expected-log actual
523 test_expect_success 'am --signoff duplicates Signed-off-by: if it is not the last one' '
524 NAME="A N Other" &&
525 EMAIL="a.n.other@example.com" &&
527 printf "third\n\nSigned-off-by: %s <%s>\n\
528 Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\n" \
529 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
530 "$NAME" "$EMAIL" \
531 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" &&
532 cat msg &&
533 printf "Signed-off-by: %s <%s>\nSigned-off-by: %s <%s>\n\
534 Signed-off-by: %s <%s>\n\n" \
535 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL" \
536 "$NAME" "$EMAIL" \
537 "$GIT_COMMITTER_NAME" "$GIT_COMMITTER_EMAIL"
538 } >expected-log &&
539 git format-patch --stdout first >patch3 &&
540 git reset --hard first &&
541 git am --signoff <patch3 &&
542 git log --pretty=%B -2 HEAD >actual &&
543 test_cmp expected-log actual
546 test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
547 git format-patch --stdout HEAD^ >tmp &&
548 sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," tmp >patch4 &&
549 git reset --hard HEAD^ &&
550 git am <patch4 &&
551 git rev-parse HEAD >expected &&
552 git rev-parse topic_2 >actual &&
553 test_cmp expected actual
556 test_expect_success 'am --keep really keeps the subject' '
557 rm -fr .git/rebase-apply &&
558 git reset --hard &&
559 git checkout HEAD^ &&
560 git am --keep patch4 &&
561 test_path_is_missing .git/rebase-apply &&
562 git cat-file commit HEAD >actual &&
563 grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
566 test_expect_success 'am --keep-non-patch really keeps the non-patch part' '
567 rm -fr .git/rebase-apply &&
568 git reset --hard &&
569 git checkout HEAD^ &&
570 git am --keep-non-patch patch4 &&
571 test_path_is_missing .git/rebase-apply &&
572 git cat-file commit HEAD >actual &&
573 grep "^\[foo\] third" actual
576 test_expect_success 'setup am -3' '
577 rm -fr .git/rebase-apply &&
578 git reset --hard &&
579 git checkout -b base3way topic_2 &&
580 sed -n -e "3,\$p" msg >file &&
581 head -n 9 msg >>file &&
582 git add file &&
583 test_tick &&
584 git commit -m "copied stuff"
587 test_expect_success 'am -3 falls back to 3-way merge' '
588 rm -fr .git/rebase-apply &&
589 git reset --hard &&
590 git checkout -b lorem2 base3way &&
591 git am -3 lorem-move.patch &&
592 test_path_is_missing .git/rebase-apply &&
593 git diff --exit-code lorem
596 test_expect_success 'am -3 -p0 can read --no-prefix patch' '
597 rm -fr .git/rebase-apply &&
598 git reset --hard &&
599 git checkout -b lorem3 base3way &&
600 git am -3 -p0 lorem-zero.patch &&
601 test_path_is_missing .git/rebase-apply &&
602 git diff --exit-code lorem
605 test_expect_success 'am with config am.threeWay falls back to 3-way merge' '
606 rm -fr .git/rebase-apply &&
607 git reset --hard &&
608 git checkout -b lorem4 base3way &&
609 test_config am.threeWay 1 &&
610 git am lorem-move.patch &&
611 test_path_is_missing .git/rebase-apply &&
612 git diff --exit-code lorem
615 test_expect_success 'am with config am.threeWay overridden by --no-3way' '
616 rm -fr .git/rebase-apply &&
617 git reset --hard &&
618 git checkout -b lorem5 base3way &&
619 test_config am.threeWay 1 &&
620 test_must_fail git am --no-3way lorem-move.patch &&
621 test_path_is_dir .git/rebase-apply
624 test_expect_success 'am can rename a file' '
625 grep "^rename from" rename.patch &&
626 rm -fr .git/rebase-apply &&
627 git reset --hard &&
628 git checkout lorem^0 &&
629 git am rename.patch &&
630 test_path_is_missing .git/rebase-apply &&
631 git update-index --refresh &&
632 git diff --exit-code rename
635 test_expect_success 'am -3 can rename a file' '
636 grep "^rename from" rename.patch &&
637 rm -fr .git/rebase-apply &&
638 git reset --hard &&
639 git checkout lorem^0 &&
640 git am -3 rename.patch &&
641 test_path_is_missing .git/rebase-apply &&
642 git update-index --refresh &&
643 git diff --exit-code rename
646 test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '
647 grep "^rename from" rename-add.patch &&
648 rm -fr .git/rebase-apply &&
649 git reset --hard &&
650 git checkout lorem^0 &&
651 git am -3 rename-add.patch &&
652 test_path_is_missing .git/rebase-apply &&
653 git update-index --refresh &&
654 git diff --exit-code rename
657 test_expect_success 'am -3 -q is quiet' '
658 rm -fr .git/rebase-apply &&
659 git checkout -f lorem2 &&
660 git reset base3way --hard &&
661 git am -3 -q lorem-move.patch >output.out 2>&1 &&
662 test_must_be_empty output.out
665 test_expect_success 'am pauses on conflict' '
666 rm -fr .git/rebase-apply &&
667 git reset --hard &&
668 git checkout lorem2^^ &&
669 test_must_fail git am lorem-move.patch &&
670 test -d .git/rebase-apply
673 test_expect_success 'am --show-current-patch' '
674 git am --show-current-patch >actual.patch &&
675 test_cmp .git/rebase-apply/0001 actual.patch
678 test_expect_success 'am --show-current-patch=raw' '
679 git am --show-current-patch=raw >actual.patch &&
680 test_cmp .git/rebase-apply/0001 actual.patch
683 test_expect_success 'am --show-current-patch=diff' '
684 git am --show-current-patch=diff >actual.patch &&
685 test_cmp .git/rebase-apply/patch actual.patch
688 test_expect_success 'am accepts repeated --show-current-patch' '
689 git am --show-current-patch --show-current-patch=raw >actual.patch &&
690 test_cmp .git/rebase-apply/0001 actual.patch
693 test_expect_success 'am detects incompatible --show-current-patch' '
694 test_must_fail git am --show-current-patch=raw --show-current-patch=diff &&
695 test_must_fail git am --show-current-patch --show-current-patch=diff
698 test_expect_success 'am --skip works' '
699 echo goodbye >expected &&
700 git am --skip &&
701 test_path_is_missing .git/rebase-apply &&
702 git diff --exit-code lorem2^^ -- file &&
703 test_cmp expected another
706 test_expect_success 'am --abort removes a stray directory' '
707 mkdir .git/rebase-apply &&
708 git am --abort &&
709 test_path_is_missing .git/rebase-apply
712 test_expect_success 'am refuses patches when paused' '
713 rm -fr .git/rebase-apply &&
714 git reset --hard &&
715 git checkout lorem2^^ &&
717 test_must_fail git am lorem-move.patch &&
718 test_path_is_dir .git/rebase-apply &&
719 test_cmp_rev lorem2^^ HEAD &&
721 test_must_fail git am <lorem-move.patch &&
722 test_path_is_dir .git/rebase-apply &&
723 test_cmp_rev lorem2^^ HEAD
726 test_expect_success 'am --resolved works' '
727 echo goodbye >expected &&
728 rm -fr .git/rebase-apply &&
729 git reset --hard &&
730 git checkout lorem2^^ &&
731 test_must_fail git am lorem-move.patch &&
732 test -d .git/rebase-apply &&
733 echo resolved >>file &&
734 git add file &&
735 git am --resolved &&
736 test_path_is_missing .git/rebase-apply &&
737 test_cmp expected another
740 test_expect_success 'am --resolved fails if index has no changes' '
741 rm -fr .git/rebase-apply &&
742 git reset --hard &&
743 git checkout lorem2^^ &&
744 test_must_fail git am lorem-move.patch &&
745 test_path_is_dir .git/rebase-apply &&
746 test_cmp_rev lorem2^^ HEAD &&
747 test_must_fail git am --resolved &&
748 test_path_is_dir .git/rebase-apply &&
749 test_cmp_rev lorem2^^ HEAD
752 test_expect_success 'am --resolved fails if index has unmerged entries' '
753 rm -fr .git/rebase-apply &&
754 git reset --hard &&
755 git checkout second &&
756 test_must_fail git am -3 lorem-move.patch &&
757 test_path_is_dir .git/rebase-apply &&
758 test_cmp_rev second HEAD &&
759 test_must_fail git am --resolved >err &&
760 test_path_is_dir .git/rebase-apply &&
761 test_cmp_rev second HEAD &&
762 test_i18ngrep "still have unmerged paths" err
765 test_expect_success 'am takes patches from a Pine mailbox' '
766 rm -fr .git/rebase-apply &&
767 git reset --hard &&
768 git checkout first &&
769 cat pine patch1 | git am &&
770 test_path_is_missing .git/rebase-apply &&
771 git diff --exit-code main^..HEAD
774 test_expect_success 'am fails on mail without patch' '
775 rm -fr .git/rebase-apply &&
776 git reset --hard &&
777 test_must_fail git am <failmail &&
778 git am --abort &&
779 test_path_is_missing .git/rebase-apply
782 test_expect_success 'am fails on empty patch' '
783 rm -fr .git/rebase-apply &&
784 git reset --hard &&
785 echo "---" >>failmail &&
786 test_must_fail git am <failmail &&
787 git am --skip &&
788 test_path_is_missing .git/rebase-apply
791 test_expect_success 'am works from stdin in subdirectory' '
792 rm -fr subdir &&
793 rm -fr .git/rebase-apply &&
794 git reset --hard &&
795 git checkout first &&
797 mkdir -p subdir &&
798 cd subdir &&
799 git am <../patch1
800 ) &&
801 git diff --exit-code second
804 test_expect_success 'am works from file (relative path given) in subdirectory' '
805 rm -fr subdir &&
806 rm -fr .git/rebase-apply &&
807 git reset --hard &&
808 git checkout first &&
810 mkdir -p subdir &&
811 cd subdir &&
812 git am ../patch1
813 ) &&
814 git diff --exit-code second
817 test_expect_success 'am works from file (absolute path given) in subdirectory' '
818 rm -fr subdir &&
819 rm -fr .git/rebase-apply &&
820 git reset --hard &&
821 git checkout first &&
822 P=$(pwd) &&
824 mkdir -p subdir &&
825 cd subdir &&
826 git am "$P/patch1"
827 ) &&
828 git diff --exit-code second
831 test_expect_success 'am --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 --committer-date-is-author-date 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 test_expect_success 'am without --committer-date-is-author-date' '
844 rm -fr .git/rebase-apply &&
845 git reset --hard &&
846 git checkout first &&
847 test_tick &&
848 git am patch1 &&
849 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
850 sed -ne "/^author /s/.*> //p" head1 >at &&
851 sed -ne "/^committer /s/.*> //p" head1 >ct &&
852 ! test_cmp at ct
855 # This checks for +0000 because TZ is set to UTC and that should
856 # show up when the current time is used. The date in message is set
857 # by test_tick that uses -0700 timezone; if this feature does not
858 # work, we will see that instead of +0000.
859 test_expect_success 'am --ignore-date' '
860 rm -fr .git/rebase-apply &&
861 git reset --hard &&
862 git checkout first &&
863 test_tick &&
864 git am --ignore-date patch1 &&
865 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
866 sed -ne "/^author /s/.*> //p" head1 >at &&
867 grep "+0000" at
870 test_expect_success 'am into an unborn branch' '
871 git rev-parse first^{tree} >expected &&
872 rm -fr .git/rebase-apply &&
873 git reset --hard &&
874 rm -fr subdir &&
875 mkdir subdir &&
876 git format-patch --numbered-files -o subdir -1 first &&
878 cd subdir &&
879 git init &&
880 git am 1
881 ) &&
883 cd subdir &&
884 git rev-parse HEAD^{tree} >../actual
885 ) &&
886 test_cmp expected actual
889 test_expect_success 'am newline in subject' '
890 rm -fr .git/rebase-apply &&
891 git reset --hard &&
892 git checkout first &&
893 test_tick &&
894 sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
895 git am <patchnl >output.out 2>&1 &&
896 test_i18ngrep "^Applying: second \\\n foo$" output.out
899 test_expect_success 'am -q is quiet' '
900 rm -fr .git/rebase-apply &&
901 git reset --hard &&
902 git checkout first &&
903 test_tick &&
904 git am -q <patch1 >output.out 2>&1 &&
905 test_must_be_empty output.out
908 test_expect_success 'am empty-file does not infloop' '
909 rm -fr .git/rebase-apply &&
910 git reset --hard &&
911 touch empty-file &&
912 test_tick &&
913 test_must_fail git am empty-file 2>actual &&
914 echo Patch format detection failed. >expected &&
915 test_cmp expected actual
918 test_expect_success 'am --message-id really adds the message id' '
919 rm -fr .git/rebase-apply &&
920 git reset --hard &&
921 git checkout HEAD^ &&
922 git am --message-id 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.messageid really adds the message id' '
930 rm -fr .git/rebase-apply &&
931 git reset --hard &&
932 git checkout HEAD^ &&
933 test_config am.messageid true &&
934 git am patch1.eml &&
935 test_path_is_missing .git/rebase-apply &&
936 git cat-file commit HEAD | tail -n1 >actual &&
937 grep Message-Id patch1.eml >expected &&
938 test_cmp expected actual
941 test_expect_success 'am --message-id -s signs off after the message id' '
942 rm -fr .git/rebase-apply &&
943 git reset --hard &&
944 git checkout HEAD^ &&
945 git am -s --message-id patch1.eml &&
946 test_path_is_missing .git/rebase-apply &&
947 git cat-file commit HEAD | tail -n2 | head -n1 >actual &&
948 grep Message-Id patch1.eml >expected &&
949 test_cmp expected actual
952 test_expect_success 'am -3 works with rerere' '
953 rm -fr .git/rebase-apply &&
954 git reset --hard &&
956 # make patches one->two and two->three...
957 test_commit one file &&
958 test_commit two file &&
959 test_commit three file &&
960 git format-patch -2 --stdout >seq.patch &&
962 # and create a situation that conflicts...
963 git reset --hard one &&
964 test_commit other file &&
966 # enable rerere...
967 test_config rerere.enabled true &&
968 test_when_finished "rm -rf .git/rr-cache" &&
970 # ...and apply. Our resolution is to skip the first
971 # patch, and the rerere the second one.
972 test_must_fail git am -3 seq.patch &&
973 test_must_fail git am --skip &&
974 echo resolved >file &&
975 git add file &&
976 git am --resolved &&
978 # now apply again, and confirm that rerere engaged (we still
979 # expect failure from am because rerere does not auto-commit
980 # for us).
981 git reset --hard other &&
982 test_must_fail git am -3 seq.patch &&
983 test_must_fail git am --skip &&
984 echo resolved >expect &&
985 test_cmp expect file
988 test_expect_success 'am -s unexpected trailer block' '
989 rm -fr .git/rebase-apply &&
990 git reset --hard &&
991 echo signed >file &&
992 git add file &&
993 cat >msg <<-EOF &&
994 subject here
996 Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
997 [jc: tweaked log message]
998 Signed-off-by: J C H <j@c.h>
1000 git commit -F msg &&
1001 git cat-file commit HEAD | sed -e "1,/^$/d" >original &&
1002 git format-patch --stdout -1 >patch &&
1004 git reset --hard HEAD^ &&
1005 git am -s patch &&
1007 cat original &&
1008 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
1009 ) >expect &&
1010 git cat-file commit HEAD | sed -e "1,/^$/d" >actual &&
1011 test_cmp expect actual &&
1013 cat >msg <<-\EOF &&
1014 subject here
1016 We make sure that there is a blank line between the log
1017 message proper and Signed-off-by: line added.
1019 git reset HEAD^ &&
1020 git commit -F msg file &&
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 &&
1028 cat original &&
1029 echo &&
1030 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
1031 ) >expect &&
1032 git cat-file commit HEAD | sed -e "1,/^$/d" >actual &&
1033 test_cmp expect actual
1036 test_expect_success 'am --patch-format=mboxrd handles mboxrd' '
1037 rm -fr .git/rebase-apply &&
1038 git checkout -f first &&
1039 echo mboxrd >>file &&
1040 git add file &&
1041 cat >msg <<-\INPUT_END &&
1042 mboxrd should escape the body
1044 From could trip up a loose mbox parser
1045 >From extra escape for reversibility
1046 INPUT_END
1047 git commit -F msg &&
1048 git format-patch --pretty=mboxrd --stdout -1 >mboxrd1 &&
1049 grep "^>From could trip up a loose mbox parser" mboxrd1 &&
1050 git checkout -f first &&
1051 git am --patch-format=mboxrd mboxrd1 &&
1052 git cat-file commit HEAD | tail -n4 >out &&
1053 test_cmp msg out
1056 test_expect_success 'am works with multi-line in-body headers' '
1057 FORTY="String that has a length of more than forty characters" &&
1058 LONG="$FORTY $FORTY" &&
1059 rm -fr .git/rebase-apply &&
1060 git checkout -f first &&
1061 echo one >> file &&
1062 git commit -am "$LONG
1064 Body test" --author="$LONG <long@example.com>" &&
1065 git format-patch --stdout -1 >patch &&
1066 # bump from, date, and subject down to in-body header
1067 perl -lpe "
1068 if (/^From:/) {
1069 print \"From: x <x\@example.com>\";
1070 print \"Date: Sat, 1 Jan 2000 00:00:00 +0000\";
1071 print \"Subject: x\n\";
1073 " patch >msg &&
1074 git checkout HEAD^ &&
1075 git am msg &&
1076 # Ensure that the author and full message are present
1077 git cat-file commit HEAD | grep "^author.*long@example.com" &&
1078 git cat-file commit HEAD | grep "^$LONG$"
1081 test_expect_success 'am --quit keeps HEAD where it is' '
1082 mkdir .git/rebase-apply &&
1083 >.git/rebase-apply/last &&
1084 >.git/rebase-apply/next &&
1085 git rev-parse HEAD^ >.git/ORIG_HEAD &&
1086 git rev-parse HEAD >expected &&
1087 git am --quit &&
1088 test_path_is_missing .git/rebase-apply &&
1089 git rev-parse HEAD >actual &&
1090 test_cmp expected actual
1093 test_expect_success 'am and .gitattibutes' '
1094 test_create_repo attributes &&
1096 cd attributes &&
1097 test_commit init &&
1098 git config filter.test.clean "sed -e '\''s/smudged/clean/g'\''" &&
1099 git config filter.test.smudge "sed -e '\''s/clean/smudged/g'\''" &&
1101 test_commit second &&
1102 git checkout -b test HEAD^ &&
1104 echo "*.txt filter=test conflict-marker-size=10" >.gitattributes &&
1105 git add .gitattributes &&
1106 test_commit third &&
1108 echo "This text is smudged." >a.txt &&
1109 git add a.txt &&
1110 test_commit fourth &&
1112 git checkout -b removal HEAD^ &&
1113 git rm .gitattributes &&
1114 git add -u &&
1115 test_commit fifth &&
1116 git cherry-pick test &&
1118 git checkout -b conflict third &&
1119 echo "This text is different." >a.txt &&
1120 git add a.txt &&
1121 test_commit sixth &&
1123 git checkout test &&
1124 git format-patch --stdout main..HEAD >patches &&
1125 git reset --hard main &&
1126 git am patches &&
1127 grep "smudged" a.txt &&
1129 git checkout removal &&
1130 git reset --hard &&
1131 git format-patch --stdout main..HEAD >patches &&
1132 git reset --hard main &&
1133 git am patches &&
1134 grep "clean" a.txt &&
1136 git checkout conflict &&
1137 git reset --hard &&
1138 git format-patch --stdout main..HEAD >patches &&
1139 git reset --hard fourth &&
1140 test_must_fail git am -3 patches &&
1141 grep "<<<<<<<<<<" a.txt
1145 test_expect_success 'apply binary blob in partial clone' '
1146 printf "\\000" >binary &&
1147 git add binary &&
1148 git commit -m "binary blob" &&
1149 git format-patch --stdout -m HEAD^ >patch &&
1151 test_create_repo server &&
1152 test_config -C server uploadpack.allowfilter 1 &&
1153 test_config -C server uploadpack.allowanysha1inwant 1 &&
1154 git clone --filter=blob:none "file://$(pwd)/server" client &&
1155 test_when_finished "rm -rf client" &&
1157 # Exercise to make sure that it works
1158 git -C client am ../patch
1161 test_expect_success 'an empty input file is error regardless of --empty option' '
1162 test_when_finished "git am --abort || :" &&
1163 test_must_fail git am --empty=drop empty.patch 2>actual &&
1164 echo "Patch format detection failed." >expected &&
1165 test_cmp expected actual
1168 test_expect_success 'invalid when passing the --empty option alone' '
1169 test_when_finished "git am --abort || :" &&
1170 git checkout empty-commit^ &&
1171 test_must_fail git am --empty empty-commit.patch 2>err &&
1172 echo "error: invalid value for '\''--empty'\'': '\''empty-commit.patch'\''" >expected &&
1173 test_cmp expected err
1176 test_expect_success 'a message without a patch is an error (default)' '
1177 test_when_finished "git am --abort || :" &&
1178 test_must_fail git am empty-commit.patch >err &&
1179 grep "Patch is empty" err
1182 test_expect_success 'a message without a patch is an error where an explicit "--empty=stop" is given' '
1183 test_when_finished "git am --abort || :" &&
1184 test_must_fail git am --empty=stop empty-commit.patch >err &&
1185 grep "Patch is empty." err
1188 test_expect_success 'a message without a patch will be skipped when "--empty=drop" is given' '
1189 git am --empty=drop empty-commit.patch >output &&
1190 git rev-parse empty-commit^ >expected &&
1191 git rev-parse HEAD >actual &&
1192 test_cmp expected actual &&
1193 grep "Skipping: empty commit" output
1196 test_expect_success 'record as an empty commit when meeting e-mail message that lacks a patch' '
1197 git am --empty=keep empty-commit.patch >output &&
1198 test_path_is_missing .git/rebase-apply &&
1199 git show empty-commit --format="%B" >expected &&
1200 git show HEAD --format="%B" >actual &&
1201 grep -f actual expected &&
1202 grep "Creating an empty commit: empty commit" output
1205 test_expect_success 'skip an empty patch 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 --skip &&
1211 test_path_is_missing .git/rebase-apply &&
1212 git rev-parse empty-commit^ >expected &&
1213 git rev-parse HEAD >actual &&
1214 test_cmp expected actual
1217 test_expect_success 'record an empty patch as an empty commit in the middle of an am session' '
1218 git checkout empty-commit^ &&
1219 test_must_fail git am empty-commit.patch >err &&
1220 grep "Patch is empty." err &&
1221 grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err &&
1222 git am --allow-empty >output &&
1223 grep "No changes - recorded it as an empty commit." output &&
1224 test_path_is_missing .git/rebase-apply &&
1225 git show empty-commit --format="%B" >expected &&
1226 git show HEAD --format="%B" >actual &&
1227 grep -f actual expected
1230 test_expect_success 'create an non-empty commit when the index IS changed though "--allow-empty" is given' '
1231 git checkout empty-commit^ &&
1232 test_must_fail git am empty-commit.patch >err &&
1233 : >empty-file &&
1234 git add empty-file &&
1235 git am --allow-empty &&
1236 git show empty-commit --format="%B" >expected &&
1237 git show HEAD --format="%B" >actual &&
1238 grep -f actual expected &&
1239 git diff HEAD^..HEAD --name-only
1242 test_expect_success 'cannot create empty commits when there is a clean index due to merge conflicts' '
1243 test_when_finished "git am --abort || :" &&
1244 git rev-parse HEAD >expected &&
1245 test_must_fail git am seq.patch &&
1246 test_must_fail git am --allow-empty >err &&
1247 ! grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err &&
1248 git rev-parse HEAD >actual &&
1249 test_cmp actual expected
1252 test_expect_success 'cannot create empty commits when there is unmerged index due to merge conflicts' '
1253 test_when_finished "git am --abort || :" &&
1254 git rev-parse HEAD >expected &&
1255 test_must_fail git am -3 seq.patch &&
1256 test_must_fail git am --allow-empty >err &&
1257 ! grep "To record the empty patch as an empty commit, run \"git am --allow-empty\"." err &&
1258 git rev-parse HEAD >actual &&
1259 test_cmp actual expected
1262 test_done