am: use gmtime() to parse mercurial patch date
[alt-git.git] / t / t4150-am.sh
blob4beb4b389413e06bd00a884c76c84fe5da2c78c0
1 #!/bin/sh
3 test_description='git am running'
5 . ./test-lib.sh
7 test_expect_success 'setup: messages' '
8 cat >msg <<-\EOF &&
9 second
11 Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, sed diam nonumy
12 eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
13 voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita
14 kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem
15 ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
16 tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At
17 vero eos et accusam et justo duo dolores et ea rebum.
19 EOF
20 qz_to_tab_space <<-\EOF >>msg &&
21 QDuis autem vel eum iriure dolor in hendrerit in vulputate velit
22 Qesse molestie consequat, vel illum dolore eu feugiat nulla facilisis
23 Qat vero eros et accumsan et iusto odio dignissim qui blandit
24 Qpraesent luptatum zzril delenit augue duis dolore te feugait nulla
25 Qfacilisi.
26 EOF
27 cat >>msg <<-\EOF &&
29 Lorem ipsum dolor sit amet,
30 consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
31 laoreet dolore magna aliquam erat volutpat.
33 git
34 ---
35 +++
37 Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit
38 lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure
39 dolor in hendrerit in vulputate velit esse molestie consequat, vel illum
40 dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
41 dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te
42 feugait nulla facilisi.
43 EOF
45 cat >failmail <<-\EOF &&
46 From foo@example.com Fri May 23 10:43:49 2008
47 From: foo@example.com
48 To: bar@example.com
49 Subject: Re: [RFC/PATCH] git-foo.sh
50 Date: Fri, 23 May 2008 05:23:42 +0200
52 Sometimes we have to find out that there'\''s nothing left.
54 EOF
56 cat >pine <<-\EOF &&
57 From MAILER-DAEMON Fri May 23 10:43:49 2008
58 Date: 23 May 2008 05:23:42 +0200
59 From: Mail System Internal Data <MAILER-DAEMON@example.com>
60 Subject: DON'\''T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA
61 Message-ID: <foo-0001@example.com>
63 This text is part of the internal format of your mail folder, and is not
64 a real message. It is created automatically by the mail system software.
65 If deleted, important folder data will be lost, and it will be re-created
66 with the data reset to initial values.
68 EOF
70 signoff="Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
73 test_expect_success setup '
74 echo hello >file &&
75 git add file &&
76 test_tick &&
77 git commit -m first &&
78 git tag first &&
80 echo world >>file &&
81 git add file &&
82 test_tick &&
83 git commit -s -F msg &&
84 git tag second &&
86 git format-patch --stdout first >patch1 &&
88 echo "Message-Id: <1226501681-24923-1-git-send-email-bda@mnsspb.ru>" &&
89 echo "X-Fake-Field: Line One" &&
90 echo "X-Fake-Field: Line Two" &&
91 echo "X-Fake-Field: Line Three" &&
92 git format-patch --stdout first | sed -e "1d"
93 } > patch1.eml &&
95 echo "X-Fake-Field: Line One" &&
96 echo "X-Fake-Field: Line Two" &&
97 echo "X-Fake-Field: Line Three" &&
98 git format-patch --stdout first | sed -e "1d"
99 } | append_cr >patch1-crlf.eml &&
101 printf "%255s\\n" ""
102 echo "X-Fake-Field: Line One" &&
103 echo "X-Fake-Field: Line Two" &&
104 echo "X-Fake-Field: Line Three" &&
105 git format-patch --stdout first | sed -e "1d"
106 } > patch1-ws.eml &&
108 sed -ne "1p" msg &&
109 echo &&
110 echo "From: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" &&
111 echo "Date: $GIT_AUTHOR_DATE" &&
112 echo &&
113 sed -e "1,2d" msg &&
114 echo &&
115 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" &&
116 echo "---" &&
117 git diff-tree --no-commit-id --stat -p second
118 } >patch1-stgit.eml &&
119 mkdir stgit-series &&
120 cp patch1-stgit.eml stgit-series/patch &&
122 echo "# This series applies on GIT commit $(git rev-parse first)" &&
123 echo "patch"
124 } >stgit-series/series &&
126 echo "# HG changeset patch" &&
127 echo "# User $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" &&
128 echo "# Date $test_tick 25200" &&
129 echo "# $(git show --pretty="%aD" -s second)" &&
130 echo "# Node ID $_z40" &&
131 echo "# Parent $_z40" &&
132 cat msg &&
133 echo &&
134 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" &&
135 echo &&
136 git diff-tree --no-commit-id -p second
137 } >patch1-hg.eml &&
140 sed -n -e "3,\$p" msg >file &&
141 git add file &&
142 test_tick &&
143 git commit -m third &&
145 git format-patch --stdout first >patch2 &&
147 git checkout -b lorem &&
148 sed -n -e "11,\$p" msg >file &&
149 head -n 9 msg >>file &&
150 test_tick &&
151 git commit -a -m "moved stuff" &&
153 echo goodbye >another &&
154 git add another &&
155 test_tick &&
156 git commit -m "added another file" &&
158 git format-patch --stdout master >lorem-move.patch &&
159 git format-patch --no-prefix --stdout master >lorem-zero.patch &&
161 git checkout -b rename &&
162 git mv file renamed &&
163 git commit -m "renamed a file" &&
165 git format-patch -M --stdout lorem >rename.patch &&
167 git reset --soft lorem^ &&
168 git commit -m "renamed a file and added another" &&
170 git format-patch -M --stdout lorem^ >rename-add.patch &&
172 # reset time
173 sane_unset test_tick &&
174 test_tick
177 test_expect_success 'am applies patch correctly' '
178 rm -fr .git/rebase-apply &&
179 git reset --hard &&
180 git checkout first &&
181 test_tick &&
182 git am <patch1 &&
183 test_path_is_missing .git/rebase-apply &&
184 git diff --exit-code second &&
185 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
186 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
189 test_expect_success 'am applies patch e-mail not in a mbox' '
190 rm -fr .git/rebase-apply &&
191 git reset --hard &&
192 git checkout first &&
193 git am patch1.eml &&
194 test_path_is_missing .git/rebase-apply &&
195 git diff --exit-code second &&
196 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
197 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
200 test_expect_success 'am applies patch e-mail not in a mbox with CRLF' '
201 rm -fr .git/rebase-apply &&
202 git reset --hard &&
203 git checkout first &&
204 git am patch1-crlf.eml &&
205 test_path_is_missing .git/rebase-apply &&
206 git diff --exit-code second &&
207 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
208 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
211 test_expect_success 'am applies patch e-mail with preceding whitespace' '
212 rm -fr .git/rebase-apply &&
213 git reset --hard &&
214 git checkout first &&
215 git am patch1-ws.eml &&
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 applies stgit patch' '
223 rm -fr .git/rebase-apply &&
224 git checkout -f first &&
225 git am patch1-stgit.eml &&
226 test_path_is_missing .git/rebase-apply &&
227 git diff --exit-code second &&
228 test_cmp_rev second HEAD &&
229 test_cmp_rev second^ HEAD^
232 test_expect_success 'am --patch-format=stgit applies stgit patch' '
233 rm -fr .git/rebase-apply &&
234 git checkout -f first &&
235 git am --patch-format=stgit <patch1-stgit.eml &&
236 test_path_is_missing .git/rebase-apply &&
237 git diff --exit-code second &&
238 test_cmp_rev second HEAD &&
239 test_cmp_rev second^ HEAD^
242 test_expect_success 'am applies stgit series' '
243 rm -fr .git/rebase-apply &&
244 git checkout -f first &&
245 git am stgit-series/series &&
246 test_path_is_missing .git/rebase-apply &&
247 git diff --exit-code second &&
248 test_cmp_rev second HEAD &&
249 test_cmp_rev second^ HEAD^
252 test_expect_success 'am applies hg patch' '
253 rm -fr .git/rebase-apply &&
254 git checkout -f first &&
255 git am patch1-hg.eml &&
256 test_path_is_missing .git/rebase-apply &&
257 git diff --exit-code second &&
258 test_cmp_rev second HEAD &&
259 test_cmp_rev second^ HEAD^
262 test_expect_success 'setup: new author and committer' '
263 GIT_AUTHOR_NAME="Another Thor" &&
264 GIT_AUTHOR_EMAIL="a.thor@example.com" &&
265 GIT_COMMITTER_NAME="Co M Miter" &&
266 GIT_COMMITTER_EMAIL="c.miter@example.com" &&
267 export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
270 compare () {
271 a=$(git cat-file commit "$2" | grep "^$1 ") &&
272 b=$(git cat-file commit "$3" | grep "^$1 ") &&
273 test "$a" = "$b"
276 test_expect_success 'am changes committer and keeps author' '
277 test_tick &&
278 rm -fr .git/rebase-apply &&
279 git reset --hard &&
280 git checkout first &&
281 git am patch2 &&
282 test_path_is_missing .git/rebase-apply &&
283 test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" &&
284 git diff --exit-code master..HEAD &&
285 git diff --exit-code master^..HEAD^ &&
286 compare author master HEAD &&
287 compare author master^ HEAD^ &&
288 test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
289 "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
292 test_expect_success 'am --signoff adds Signed-off-by: line' '
293 rm -fr .git/rebase-apply &&
294 git reset --hard &&
295 git checkout -b master2 first &&
296 git am --signoff <patch2 &&
297 printf "%s\n" "$signoff" >expected &&
298 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >>expected &&
299 git cat-file commit HEAD^ | grep "Signed-off-by:" >actual &&
300 test_cmp expected actual &&
301 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected &&
302 git cat-file commit HEAD | grep "Signed-off-by:" >actual &&
303 test_cmp expected actual
306 test_expect_success 'am stays in branch' '
307 echo refs/heads/master2 >expected &&
308 git symbolic-ref HEAD >actual &&
309 test_cmp expected actual
312 test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
313 git format-patch --stdout HEAD^ >patch3 &&
314 sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," patch3 >patch4 &&
315 rm -fr .git/rebase-apply &&
316 git reset --hard &&
317 git checkout HEAD^ &&
318 git am --signoff patch4 &&
319 git cat-file commit HEAD >actual &&
320 test $(grep -c "^Signed-off-by:" actual) -eq 1
323 test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
324 git rev-parse HEAD >expected &&
325 git rev-parse master2 >actual &&
326 test_cmp expected actual
329 test_expect_success 'am --keep really keeps the subject' '
330 rm -fr .git/rebase-apply &&
331 git reset --hard &&
332 git checkout HEAD^ &&
333 git am --keep patch4 &&
334 test_path_is_missing .git/rebase-apply &&
335 git cat-file commit HEAD >actual &&
336 grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
339 test_expect_success 'am --keep-non-patch really keeps the non-patch part' '
340 rm -fr .git/rebase-apply &&
341 git reset --hard &&
342 git checkout HEAD^ &&
343 git am --keep-non-patch patch4 &&
344 test_path_is_missing .git/rebase-apply &&
345 git cat-file commit HEAD >actual &&
346 grep "^\[foo\] third" actual
349 test_expect_success 'am -3 falls back to 3-way merge' '
350 rm -fr .git/rebase-apply &&
351 git reset --hard &&
352 git checkout -b lorem2 master2 &&
353 sed -n -e "3,\$p" msg >file &&
354 head -n 9 msg >>file &&
355 git add file &&
356 test_tick &&
357 git commit -m "copied stuff" &&
358 git am -3 lorem-move.patch &&
359 test_path_is_missing .git/rebase-apply &&
360 git diff --exit-code lorem
363 test_expect_success 'am -3 -p0 can read --no-prefix patch' '
364 rm -fr .git/rebase-apply &&
365 git reset --hard &&
366 git checkout -b lorem3 master2 &&
367 sed -n -e "3,\$p" msg >file &&
368 head -n 9 msg >>file &&
369 git add file &&
370 test_tick &&
371 git commit -m "copied stuff" &&
372 git am -3 -p0 lorem-zero.patch &&
373 test_path_is_missing .git/rebase-apply &&
374 git diff --exit-code lorem
377 test_expect_success 'am can rename a file' '
378 grep "^rename from" rename.patch &&
379 rm -fr .git/rebase-apply &&
380 git reset --hard &&
381 git checkout lorem^0 &&
382 git am rename.patch &&
383 test_path_is_missing .git/rebase-apply &&
384 git update-index --refresh &&
385 git diff --exit-code rename
388 test_expect_success 'am -3 can rename a file' '
389 grep "^rename from" rename.patch &&
390 rm -fr .git/rebase-apply &&
391 git reset --hard &&
392 git checkout lorem^0 &&
393 git am -3 rename.patch &&
394 test_path_is_missing .git/rebase-apply &&
395 git update-index --refresh &&
396 git diff --exit-code rename
399 test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '
400 grep "^rename from" rename-add.patch &&
401 rm -fr .git/rebase-apply &&
402 git reset --hard &&
403 git checkout lorem^0 &&
404 git am -3 rename-add.patch &&
405 test_path_is_missing .git/rebase-apply &&
406 git update-index --refresh &&
407 git diff --exit-code rename
410 test_expect_success 'am -3 -q is quiet' '
411 rm -fr .git/rebase-apply &&
412 git checkout -f lorem2 &&
413 git reset master2 --hard &&
414 sed -n -e "3,\$p" msg >file &&
415 head -n 9 msg >>file &&
416 git add file &&
417 test_tick &&
418 git commit -m "copied stuff" &&
419 git am -3 -q lorem-move.patch >output.out 2>&1 &&
420 ! test -s output.out
423 test_expect_success 'am pauses on conflict' '
424 rm -fr .git/rebase-apply &&
425 git reset --hard &&
426 git checkout lorem2^^ &&
427 test_must_fail git am lorem-move.patch &&
428 test -d .git/rebase-apply
431 test_expect_success 'am --skip works' '
432 echo goodbye >expected &&
433 git am --skip &&
434 test_path_is_missing .git/rebase-apply &&
435 git diff --exit-code lorem2^^ -- file &&
436 test_cmp expected another
439 test_expect_success 'am --abort removes a stray directory' '
440 mkdir .git/rebase-apply &&
441 git am --abort &&
442 test_path_is_missing .git/rebase-apply
445 test_expect_success 'am --resolved works' '
446 echo goodbye >expected &&
447 rm -fr .git/rebase-apply &&
448 git reset --hard &&
449 git checkout lorem2^^ &&
450 test_must_fail git am lorem-move.patch &&
451 test -d .git/rebase-apply &&
452 echo resolved >>file &&
453 git add file &&
454 git am --resolved &&
455 test_path_is_missing .git/rebase-apply &&
456 test_cmp expected another
459 test_expect_success 'am takes patches from a Pine mailbox' '
460 rm -fr .git/rebase-apply &&
461 git reset --hard &&
462 git checkout first &&
463 cat pine patch1 | git am &&
464 test_path_is_missing .git/rebase-apply &&
465 git diff --exit-code master^..HEAD
468 test_expect_success 'am fails on mail without patch' '
469 rm -fr .git/rebase-apply &&
470 git reset --hard &&
471 test_must_fail git am <failmail &&
472 git am --abort &&
473 test_path_is_missing .git/rebase-apply
476 test_expect_success 'am fails on empty patch' '
477 rm -fr .git/rebase-apply &&
478 git reset --hard &&
479 echo "---" >>failmail &&
480 test_must_fail git am <failmail &&
481 git am --skip &&
482 test_path_is_missing .git/rebase-apply
485 test_expect_success 'am works from stdin in subdirectory' '
486 rm -fr subdir &&
487 rm -fr .git/rebase-apply &&
488 git reset --hard &&
489 git checkout first &&
491 mkdir -p subdir &&
492 cd subdir &&
493 git am <../patch1
494 ) &&
495 git diff --exit-code second
498 test_expect_success 'am works from file (relative path given) in subdirectory' '
499 rm -fr subdir &&
500 rm -fr .git/rebase-apply &&
501 git reset --hard &&
502 git checkout first &&
504 mkdir -p subdir &&
505 cd subdir &&
506 git am ../patch1
507 ) &&
508 git diff --exit-code second
511 test_expect_success 'am works from file (absolute path given) in subdirectory' '
512 rm -fr subdir &&
513 rm -fr .git/rebase-apply &&
514 git reset --hard &&
515 git checkout first &&
516 P=$(pwd) &&
518 mkdir -p subdir &&
519 cd subdir &&
520 git am "$P/patch1"
521 ) &&
522 git diff --exit-code second
525 test_expect_success 'am --committer-date-is-author-date' '
526 rm -fr .git/rebase-apply &&
527 git reset --hard &&
528 git checkout first &&
529 test_tick &&
530 git am --committer-date-is-author-date patch1 &&
531 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
532 sed -ne "/^author /s/.*> //p" head1 >at &&
533 sed -ne "/^committer /s/.*> //p" head1 >ct &&
534 test_cmp at ct
537 test_expect_success 'am without --committer-date-is-author-date' '
538 rm -fr .git/rebase-apply &&
539 git reset --hard &&
540 git checkout first &&
541 test_tick &&
542 git am patch1 &&
543 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
544 sed -ne "/^author /s/.*> //p" head1 >at &&
545 sed -ne "/^committer /s/.*> //p" head1 >ct &&
546 ! test_cmp at ct
549 # This checks for +0000 because TZ is set to UTC and that should
550 # show up when the current time is used. The date in message is set
551 # by test_tick that uses -0700 timezone; if this feature does not
552 # work, we will see that instead of +0000.
553 test_expect_success 'am --ignore-date' '
554 rm -fr .git/rebase-apply &&
555 git reset --hard &&
556 git checkout first &&
557 test_tick &&
558 git am --ignore-date patch1 &&
559 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
560 sed -ne "/^author /s/.*> //p" head1 >at &&
561 grep "+0000" at
564 test_expect_success 'am into an unborn branch' '
565 git rev-parse first^{tree} >expected &&
566 rm -fr .git/rebase-apply &&
567 git reset --hard &&
568 rm -fr subdir &&
569 mkdir subdir &&
570 git format-patch --numbered-files -o subdir -1 first &&
572 cd subdir &&
573 git init &&
574 git am 1
575 ) &&
577 cd subdir &&
578 git rev-parse HEAD^{tree} >../actual
579 ) &&
580 test_cmp expected actual
583 test_expect_success 'am newline in subject' '
584 rm -fr .git/rebase-apply &&
585 git reset --hard &&
586 git checkout first &&
587 test_tick &&
588 sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
589 git am <patchnl >output.out 2>&1 &&
590 test_i18ngrep "^Applying: second \\\n foo$" output.out
593 test_expect_success 'am -q is quiet' '
594 rm -fr .git/rebase-apply &&
595 git reset --hard &&
596 git checkout first &&
597 test_tick &&
598 git am -q <patch1 >output.out 2>&1 &&
599 ! test -s output.out
602 test_expect_success 'am empty-file does not infloop' '
603 rm -fr .git/rebase-apply &&
604 git reset --hard &&
605 touch empty-file &&
606 test_tick &&
607 test_must_fail git am empty-file 2>actual &&
608 echo Patch format detection failed. >expected &&
609 test_i18ncmp expected actual
612 test_expect_success 'am --message-id really adds the message id' '
613 rm -fr .git/rebase-apply &&
614 git reset --hard &&
615 git checkout HEAD^ &&
616 git am --message-id patch1.eml &&
617 test_path_is_missing .git/rebase-apply &&
618 git cat-file commit HEAD | tail -n1 >actual &&
619 grep Message-Id patch1.eml >expected &&
620 test_cmp expected actual
623 test_expect_success 'am --message-id -s signs off after the message id' '
624 rm -fr .git/rebase-apply &&
625 git reset --hard &&
626 git checkout HEAD^ &&
627 git am -s --message-id patch1.eml &&
628 test_path_is_missing .git/rebase-apply &&
629 git cat-file commit HEAD | tail -n2 | head -n1 >actual &&
630 grep Message-Id patch1.eml >expected &&
631 test_cmp expected actual
634 test_done