Merge branch 'maint'
[git.git] / t / t4150-am.sh
blob5edb79a058f407f47353041afb8e7851b066a517
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 "X-Fake-Field: Line One" &&
89 echo "X-Fake-Field: Line Two" &&
90 echo "X-Fake-Field: Line Three" &&
91 git format-patch --stdout first | sed -e "1d"
92 } > patch1.eml &&
94 echo "X-Fake-Field: Line One" &&
95 echo "X-Fake-Field: Line Two" &&
96 echo "X-Fake-Field: Line Three" &&
97 git format-patch --stdout first | sed -e "1d"
98 } | append_cr >patch1-crlf.eml &&
100 printf "%255s\\n" ""
101 echo "X-Fake-Field: Line One" &&
102 echo "X-Fake-Field: Line Two" &&
103 echo "X-Fake-Field: Line Three" &&
104 git format-patch --stdout first | sed -e "1d"
105 } > patch1-ws.eml &&
107 sed -n -e "3,\$p" msg >file &&
108 git add file &&
109 test_tick &&
110 git commit -m third &&
112 git format-patch --stdout first >patch2 &&
114 git checkout -b lorem &&
115 sed -n -e "11,\$p" msg >file &&
116 head -n 9 msg >>file &&
117 test_tick &&
118 git commit -a -m "moved stuff" &&
120 echo goodbye >another &&
121 git add another &&
122 test_tick &&
123 git commit -m "added another file" &&
125 git format-patch --stdout master >lorem-move.patch &&
126 git format-patch --no-prefix --stdout master >lorem-zero.patch &&
128 git checkout -b rename &&
129 git mv file renamed &&
130 git commit -m "renamed a file" &&
132 git format-patch -M --stdout lorem >rename.patch &&
134 git reset --soft lorem^ &&
135 git commit -m "renamed a file and added another" &&
137 git format-patch -M --stdout lorem^ >rename-add.patch &&
139 # reset time
140 sane_unset test_tick &&
141 test_tick
144 test_expect_success 'am applies patch correctly' '
145 rm -fr .git/rebase-apply &&
146 git reset --hard &&
147 git checkout first &&
148 test_tick &&
149 git am <patch1 &&
150 test_path_is_missing .git/rebase-apply &&
151 git diff --exit-code second &&
152 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
153 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
156 test_expect_success 'am applies patch e-mail not in a mbox' '
157 rm -fr .git/rebase-apply &&
158 git reset --hard &&
159 git checkout first &&
160 git am patch1.eml &&
161 test_path_is_missing .git/rebase-apply &&
162 git diff --exit-code second &&
163 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
164 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
167 test_expect_success 'am applies patch e-mail not in a mbox with CRLF' '
168 rm -fr .git/rebase-apply &&
169 git reset --hard &&
170 git checkout first &&
171 git am patch1-crlf.eml &&
172 test_path_is_missing .git/rebase-apply &&
173 git diff --exit-code second &&
174 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
175 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
178 test_expect_success 'am applies patch e-mail with preceding whitespace' '
179 rm -fr .git/rebase-apply &&
180 git reset --hard &&
181 git checkout first &&
182 git am patch1-ws.eml &&
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 'setup: new author and committer' '
190 GIT_AUTHOR_NAME="Another Thor" &&
191 GIT_AUTHOR_EMAIL="a.thor@example.com" &&
192 GIT_COMMITTER_NAME="Co M Miter" &&
193 GIT_COMMITTER_EMAIL="c.miter@example.com" &&
194 export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
197 compare () {
198 a=$(git cat-file commit "$2" | grep "^$1 ") &&
199 b=$(git cat-file commit "$3" | grep "^$1 ") &&
200 test "$a" = "$b"
203 test_expect_success 'am changes committer and keeps author' '
204 test_tick &&
205 rm -fr .git/rebase-apply &&
206 git reset --hard &&
207 git checkout first &&
208 git am patch2 &&
209 test_path_is_missing .git/rebase-apply &&
210 test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" &&
211 git diff --exit-code master..HEAD &&
212 git diff --exit-code master^..HEAD^ &&
213 compare author master HEAD &&
214 compare author master^ HEAD^ &&
215 test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
216 "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
219 test_expect_success 'am --signoff adds Signed-off-by: line' '
220 rm -fr .git/rebase-apply &&
221 git reset --hard &&
222 git checkout -b master2 first &&
223 git am --signoff <patch2 &&
224 printf "%s\n" "$signoff" >expected &&
225 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >>expected &&
226 git cat-file commit HEAD^ | grep "Signed-off-by:" >actual &&
227 test_cmp expected actual &&
228 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected &&
229 git cat-file commit HEAD | grep "Signed-off-by:" >actual &&
230 test_cmp expected actual
233 test_expect_success 'am stays in branch' '
234 echo refs/heads/master2 >expected &&
235 git symbolic-ref HEAD >actual &&
236 test_cmp expected actual
239 test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
240 git format-patch --stdout HEAD^ >patch3 &&
241 sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," patch3 >patch4 &&
242 rm -fr .git/rebase-apply &&
243 git reset --hard &&
244 git checkout HEAD^ &&
245 git am --signoff patch4 &&
246 git cat-file commit HEAD >actual &&
247 test $(grep -c "^Signed-off-by:" actual) -eq 1
250 test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
251 git rev-parse HEAD >expected &&
252 git rev-parse master2 >actual &&
253 test_cmp expected actual
256 test_expect_success 'am --keep really keeps the subject' '
257 rm -fr .git/rebase-apply &&
258 git reset --hard &&
259 git checkout HEAD^ &&
260 git am --keep patch4 &&
261 test_path_is_missing .git/rebase-apply &&
262 git cat-file commit HEAD >actual &&
263 grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
266 test_expect_success 'am --keep-non-patch really keeps the non-patch part' '
267 rm -fr .git/rebase-apply &&
268 git reset --hard &&
269 git checkout HEAD^ &&
270 git am --keep-non-patch patch4 &&
271 test_path_is_missing .git/rebase-apply &&
272 git cat-file commit HEAD >actual &&
273 grep "^\[foo\] third" actual
276 test_expect_success 'am -3 falls back to 3-way merge' '
277 rm -fr .git/rebase-apply &&
278 git reset --hard &&
279 git checkout -b lorem2 master2 &&
280 sed -n -e "3,\$p" msg >file &&
281 head -n 9 msg >>file &&
282 git add file &&
283 test_tick &&
284 git commit -m "copied stuff" &&
285 git am -3 lorem-move.patch &&
286 test_path_is_missing .git/rebase-apply &&
287 git diff --exit-code lorem
290 test_expect_success 'am -3 -p0 can read --no-prefix patch' '
291 rm -fr .git/rebase-apply &&
292 git reset --hard &&
293 git checkout -b lorem3 master2 &&
294 sed -n -e "3,\$p" msg >file &&
295 head -n 9 msg >>file &&
296 git add file &&
297 test_tick &&
298 git commit -m "copied stuff" &&
299 git am -3 -p0 lorem-zero.patch &&
300 test_path_is_missing .git/rebase-apply &&
301 git diff --exit-code lorem
304 test_expect_success 'am can rename a file' '
305 grep "^rename from" rename.patch &&
306 rm -fr .git/rebase-apply &&
307 git reset --hard &&
308 git checkout lorem^0 &&
309 git am rename.patch &&
310 test_path_is_missing .git/rebase-apply &&
311 git update-index --refresh &&
312 git diff --exit-code rename
315 test_expect_success 'am -3 can rename a file' '
316 grep "^rename from" rename.patch &&
317 rm -fr .git/rebase-apply &&
318 git reset --hard &&
319 git checkout lorem^0 &&
320 git am -3 rename.patch &&
321 test_path_is_missing .git/rebase-apply &&
322 git update-index --refresh &&
323 git diff --exit-code rename
326 test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '
327 grep "^rename from" rename-add.patch &&
328 rm -fr .git/rebase-apply &&
329 git reset --hard &&
330 git checkout lorem^0 &&
331 git am -3 rename-add.patch &&
332 test_path_is_missing .git/rebase-apply &&
333 git update-index --refresh &&
334 git diff --exit-code rename
337 test_expect_success 'am -3 -q is quiet' '
338 rm -fr .git/rebase-apply &&
339 git checkout -f lorem2 &&
340 git reset master2 --hard &&
341 sed -n -e "3,\$p" msg >file &&
342 head -n 9 msg >>file &&
343 git add file &&
344 test_tick &&
345 git commit -m "copied stuff" &&
346 git am -3 -q lorem-move.patch >output.out 2>&1 &&
347 ! test -s output.out
350 test_expect_success 'am pauses on conflict' '
351 rm -fr .git/rebase-apply &&
352 git reset --hard &&
353 git checkout lorem2^^ &&
354 test_must_fail git am lorem-move.patch &&
355 test -d .git/rebase-apply
358 test_expect_success 'am --skip works' '
359 echo goodbye >expected &&
360 git am --skip &&
361 test_path_is_missing .git/rebase-apply &&
362 git diff --exit-code lorem2^^ -- file &&
363 test_cmp expected another
366 test_expect_success 'am --abort removes a stray directory' '
367 mkdir .git/rebase-apply &&
368 git am --abort &&
369 test_path_is_missing .git/rebase-apply
372 test_expect_success 'am --resolved works' '
373 echo goodbye >expected &&
374 rm -fr .git/rebase-apply &&
375 git reset --hard &&
376 git checkout lorem2^^ &&
377 test_must_fail git am lorem-move.patch &&
378 test -d .git/rebase-apply &&
379 echo resolved >>file &&
380 git add file &&
381 git am --resolved &&
382 test_path_is_missing .git/rebase-apply &&
383 test_cmp expected another
386 test_expect_success 'am takes patches from a Pine mailbox' '
387 rm -fr .git/rebase-apply &&
388 git reset --hard &&
389 git checkout first &&
390 cat pine patch1 | git am &&
391 test_path_is_missing .git/rebase-apply &&
392 git diff --exit-code master^..HEAD
395 test_expect_success 'am fails on mail without patch' '
396 rm -fr .git/rebase-apply &&
397 git reset --hard &&
398 test_must_fail git am <failmail &&
399 git am --abort &&
400 test_path_is_missing .git/rebase-apply
403 test_expect_success 'am fails on empty patch' '
404 rm -fr .git/rebase-apply &&
405 git reset --hard &&
406 echo "---" >>failmail &&
407 test_must_fail git am <failmail &&
408 git am --skip &&
409 test_path_is_missing .git/rebase-apply
412 test_expect_success 'am works from stdin in subdirectory' '
413 rm -fr subdir &&
414 rm -fr .git/rebase-apply &&
415 git reset --hard &&
416 git checkout first &&
418 mkdir -p subdir &&
419 cd subdir &&
420 git am <../patch1
421 ) &&
422 git diff --exit-code second
425 test_expect_success 'am works from file (relative path given) in subdirectory' '
426 rm -fr subdir &&
427 rm -fr .git/rebase-apply &&
428 git reset --hard &&
429 git checkout first &&
431 mkdir -p subdir &&
432 cd subdir &&
433 git am ../patch1
434 ) &&
435 git diff --exit-code second
438 test_expect_success 'am works from file (absolute path given) in subdirectory' '
439 rm -fr subdir &&
440 rm -fr .git/rebase-apply &&
441 git reset --hard &&
442 git checkout first &&
443 P=$(pwd) &&
445 mkdir -p subdir &&
446 cd subdir &&
447 git am "$P/patch1"
448 ) &&
449 git diff --exit-code second
452 test_expect_success 'am --committer-date-is-author-date' '
453 rm -fr .git/rebase-apply &&
454 git reset --hard &&
455 git checkout first &&
456 test_tick &&
457 git am --committer-date-is-author-date patch1 &&
458 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
459 sed -ne "/^author /s/.*> //p" head1 >at &&
460 sed -ne "/^committer /s/.*> //p" head1 >ct &&
461 test_cmp at ct
464 test_expect_success 'am without --committer-date-is-author-date' '
465 rm -fr .git/rebase-apply &&
466 git reset --hard &&
467 git checkout first &&
468 test_tick &&
469 git am patch1 &&
470 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
471 sed -ne "/^author /s/.*> //p" head1 >at &&
472 sed -ne "/^committer /s/.*> //p" head1 >ct &&
473 ! test_cmp at ct
476 # This checks for +0000 because TZ is set to UTC and that should
477 # show up when the current time is used. The date in message is set
478 # by test_tick that uses -0700 timezone; if this feature does not
479 # work, we will see that instead of +0000.
480 test_expect_success 'am --ignore-date' '
481 rm -fr .git/rebase-apply &&
482 git reset --hard &&
483 git checkout first &&
484 test_tick &&
485 git am --ignore-date patch1 &&
486 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
487 sed -ne "/^author /s/.*> //p" head1 >at &&
488 grep "+0000" at
491 test_expect_success 'am into an unborn branch' '
492 git rev-parse first^{tree} >expected &&
493 rm -fr .git/rebase-apply &&
494 git reset --hard &&
495 rm -fr subdir &&
496 mkdir subdir &&
497 git format-patch --numbered-files -o subdir -1 first &&
499 cd subdir &&
500 git init &&
501 git am 1
502 ) &&
504 cd subdir &&
505 git rev-parse HEAD^{tree} >../actual
506 ) &&
507 test_cmp expected actual
510 test_expect_success 'am newline in subject' '
511 rm -fr .git/rebase-apply &&
512 git reset --hard &&
513 git checkout first &&
514 test_tick &&
515 sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
516 git am <patchnl >output.out 2>&1 &&
517 test_i18ngrep "^Applying: second \\\n foo$" output.out
520 test_expect_success 'am -q is quiet' '
521 rm -fr .git/rebase-apply &&
522 git reset --hard &&
523 git checkout first &&
524 test_tick &&
525 git am -q <patch1 >output.out 2>&1 &&
526 ! test -s output.out
529 test_expect_success 'am empty-file does not infloop' '
530 rm -fr .git/rebase-apply &&
531 git reset --hard &&
532 touch empty-file &&
533 test_tick &&
534 test_must_fail git am empty-file 2>actual &&
535 echo Patch format detection failed. >expected &&
536 test_i18ncmp expected actual
539 test_done