Documentation: explain optional arguments better
[git.git] / t / t4150-am.sh
blob6ced98cfb4a71553d66a828118a585e0f7fc84c7
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 -n -e "3,\$p" msg >file &&
109 git add file &&
110 test_tick &&
111 git commit -m third &&
113 git format-patch --stdout first >patch2 &&
115 git checkout -b lorem &&
116 sed -n -e "11,\$p" msg >file &&
117 head -n 9 msg >>file &&
118 test_tick &&
119 git commit -a -m "moved stuff" &&
121 echo goodbye >another &&
122 git add another &&
123 test_tick &&
124 git commit -m "added another file" &&
126 git format-patch --stdout master >lorem-move.patch &&
127 git format-patch --no-prefix --stdout master >lorem-zero.patch &&
129 git checkout -b rename &&
130 git mv file renamed &&
131 git commit -m "renamed a file" &&
133 git format-patch -M --stdout lorem >rename.patch &&
135 git reset --soft lorem^ &&
136 git commit -m "renamed a file and added another" &&
138 git format-patch -M --stdout lorem^ >rename-add.patch &&
140 # reset time
141 sane_unset test_tick &&
142 test_tick
145 test_expect_success 'am applies patch correctly' '
146 rm -fr .git/rebase-apply &&
147 git reset --hard &&
148 git checkout first &&
149 test_tick &&
150 git am <patch1 &&
151 test_path_is_missing .git/rebase-apply &&
152 git diff --exit-code second &&
153 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
154 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
157 test_expect_success 'am applies patch e-mail not in a mbox' '
158 rm -fr .git/rebase-apply &&
159 git reset --hard &&
160 git checkout first &&
161 git am patch1.eml &&
162 test_path_is_missing .git/rebase-apply &&
163 git diff --exit-code second &&
164 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
165 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
168 test_expect_success 'am applies patch e-mail not in a mbox with CRLF' '
169 rm -fr .git/rebase-apply &&
170 git reset --hard &&
171 git checkout first &&
172 git am patch1-crlf.eml &&
173 test_path_is_missing .git/rebase-apply &&
174 git diff --exit-code second &&
175 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
176 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
179 test_expect_success 'am applies patch e-mail with preceding whitespace' '
180 rm -fr .git/rebase-apply &&
181 git reset --hard &&
182 git checkout first &&
183 git am patch1-ws.eml &&
184 test_path_is_missing .git/rebase-apply &&
185 git diff --exit-code second &&
186 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
187 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
190 test_expect_success 'setup: new author and committer' '
191 GIT_AUTHOR_NAME="Another Thor" &&
192 GIT_AUTHOR_EMAIL="a.thor@example.com" &&
193 GIT_COMMITTER_NAME="Co M Miter" &&
194 GIT_COMMITTER_EMAIL="c.miter@example.com" &&
195 export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
198 compare () {
199 a=$(git cat-file commit "$2" | grep "^$1 ") &&
200 b=$(git cat-file commit "$3" | grep "^$1 ") &&
201 test "$a" = "$b"
204 test_expect_success 'am changes committer and keeps author' '
205 test_tick &&
206 rm -fr .git/rebase-apply &&
207 git reset --hard &&
208 git checkout first &&
209 git am patch2 &&
210 test_path_is_missing .git/rebase-apply &&
211 test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" &&
212 git diff --exit-code master..HEAD &&
213 git diff --exit-code master^..HEAD^ &&
214 compare author master HEAD &&
215 compare author master^ HEAD^ &&
216 test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
217 "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
220 test_expect_success 'am --signoff adds Signed-off-by: line' '
221 rm -fr .git/rebase-apply &&
222 git reset --hard &&
223 git checkout -b master2 first &&
224 git am --signoff <patch2 &&
225 printf "%s\n" "$signoff" >expected &&
226 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >>expected &&
227 git cat-file commit HEAD^ | grep "Signed-off-by:" >actual &&
228 test_cmp expected actual &&
229 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected &&
230 git cat-file commit HEAD | grep "Signed-off-by:" >actual &&
231 test_cmp expected actual
234 test_expect_success 'am stays in branch' '
235 echo refs/heads/master2 >expected &&
236 git symbolic-ref HEAD >actual &&
237 test_cmp expected actual
240 test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
241 git format-patch --stdout HEAD^ >patch3 &&
242 sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," patch3 >patch4 &&
243 rm -fr .git/rebase-apply &&
244 git reset --hard &&
245 git checkout HEAD^ &&
246 git am --signoff patch4 &&
247 git cat-file commit HEAD >actual &&
248 test $(grep -c "^Signed-off-by:" actual) -eq 1
251 test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
252 git rev-parse HEAD >expected &&
253 git rev-parse master2 >actual &&
254 test_cmp expected actual
257 test_expect_success 'am --keep really keeps the subject' '
258 rm -fr .git/rebase-apply &&
259 git reset --hard &&
260 git checkout HEAD^ &&
261 git am --keep patch4 &&
262 test_path_is_missing .git/rebase-apply &&
263 git cat-file commit HEAD >actual &&
264 grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
267 test_expect_success 'am --keep-non-patch really keeps the non-patch part' '
268 rm -fr .git/rebase-apply &&
269 git reset --hard &&
270 git checkout HEAD^ &&
271 git am --keep-non-patch patch4 &&
272 test_path_is_missing .git/rebase-apply &&
273 git cat-file commit HEAD >actual &&
274 grep "^\[foo\] third" actual
277 test_expect_success 'setup am -3' '
278 rm -fr .git/rebase-apply &&
279 git reset --hard &&
280 git checkout -b base3way master2 &&
281 sed -n -e "3,\$p" msg >file &&
282 head -n 9 msg >>file &&
283 git add file &&
284 test_tick &&
285 git commit -m "copied stuff"
288 test_expect_success 'am -3 falls back to 3-way merge' '
289 rm -fr .git/rebase-apply &&
290 git reset --hard &&
291 git checkout -b lorem2 base3way &&
292 git am -3 lorem-move.patch &&
293 test_path_is_missing .git/rebase-apply &&
294 git diff --exit-code lorem
297 test_expect_success 'am -3 -p0 can read --no-prefix patch' '
298 rm -fr .git/rebase-apply &&
299 git reset --hard &&
300 git checkout -b lorem3 base3way &&
301 git am -3 -p0 lorem-zero.patch &&
302 test_path_is_missing .git/rebase-apply &&
303 git diff --exit-code lorem
306 test_expect_success 'am can rename a file' '
307 grep "^rename from" rename.patch &&
308 rm -fr .git/rebase-apply &&
309 git reset --hard &&
310 git checkout lorem^0 &&
311 git am rename.patch &&
312 test_path_is_missing .git/rebase-apply &&
313 git update-index --refresh &&
314 git diff --exit-code rename
317 test_expect_success 'am -3 can rename a file' '
318 grep "^rename from" rename.patch &&
319 rm -fr .git/rebase-apply &&
320 git reset --hard &&
321 git checkout lorem^0 &&
322 git am -3 rename.patch &&
323 test_path_is_missing .git/rebase-apply &&
324 git update-index --refresh &&
325 git diff --exit-code rename
328 test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '
329 grep "^rename from" rename-add.patch &&
330 rm -fr .git/rebase-apply &&
331 git reset --hard &&
332 git checkout lorem^0 &&
333 git am -3 rename-add.patch &&
334 test_path_is_missing .git/rebase-apply &&
335 git update-index --refresh &&
336 git diff --exit-code rename
339 test_expect_success 'am -3 -q is quiet' '
340 rm -fr .git/rebase-apply &&
341 git checkout -f lorem2 &&
342 git reset base3way --hard &&
343 git am -3 -q lorem-move.patch >output.out 2>&1 &&
344 ! test -s output.out
347 test_expect_success 'am pauses on conflict' '
348 rm -fr .git/rebase-apply &&
349 git reset --hard &&
350 git checkout lorem2^^ &&
351 test_must_fail git am lorem-move.patch &&
352 test -d .git/rebase-apply
355 test_expect_success 'am --skip works' '
356 echo goodbye >expected &&
357 git am --skip &&
358 test_path_is_missing .git/rebase-apply &&
359 git diff --exit-code lorem2^^ -- file &&
360 test_cmp expected another
363 test_expect_success 'am --abort removes a stray directory' '
364 mkdir .git/rebase-apply &&
365 git am --abort &&
366 test_path_is_missing .git/rebase-apply
369 test_expect_success 'am --resolved works' '
370 echo goodbye >expected &&
371 rm -fr .git/rebase-apply &&
372 git reset --hard &&
373 git checkout lorem2^^ &&
374 test_must_fail git am lorem-move.patch &&
375 test -d .git/rebase-apply &&
376 echo resolved >>file &&
377 git add file &&
378 git am --resolved &&
379 test_path_is_missing .git/rebase-apply &&
380 test_cmp expected another
383 test_expect_success 'am takes patches from a Pine mailbox' '
384 rm -fr .git/rebase-apply &&
385 git reset --hard &&
386 git checkout first &&
387 cat pine patch1 | git am &&
388 test_path_is_missing .git/rebase-apply &&
389 git diff --exit-code master^..HEAD
392 test_expect_success 'am fails on mail without patch' '
393 rm -fr .git/rebase-apply &&
394 git reset --hard &&
395 test_must_fail git am <failmail &&
396 git am --abort &&
397 test_path_is_missing .git/rebase-apply
400 test_expect_success 'am fails on empty patch' '
401 rm -fr .git/rebase-apply &&
402 git reset --hard &&
403 echo "---" >>failmail &&
404 test_must_fail git am <failmail &&
405 git am --skip &&
406 test_path_is_missing .git/rebase-apply
409 test_expect_success 'am works from stdin in subdirectory' '
410 rm -fr subdir &&
411 rm -fr .git/rebase-apply &&
412 git reset --hard &&
413 git checkout first &&
415 mkdir -p subdir &&
416 cd subdir &&
417 git am <../patch1
418 ) &&
419 git diff --exit-code second
422 test_expect_success 'am works from file (relative path given) in subdirectory' '
423 rm -fr subdir &&
424 rm -fr .git/rebase-apply &&
425 git reset --hard &&
426 git checkout first &&
428 mkdir -p subdir &&
429 cd subdir &&
430 git am ../patch1
431 ) &&
432 git diff --exit-code second
435 test_expect_success 'am works from file (absolute path given) in subdirectory' '
436 rm -fr subdir &&
437 rm -fr .git/rebase-apply &&
438 git reset --hard &&
439 git checkout first &&
440 P=$(pwd) &&
442 mkdir -p subdir &&
443 cd subdir &&
444 git am "$P/patch1"
445 ) &&
446 git diff --exit-code second
449 test_expect_success 'am --committer-date-is-author-date' '
450 rm -fr .git/rebase-apply &&
451 git reset --hard &&
452 git checkout first &&
453 test_tick &&
454 git am --committer-date-is-author-date patch1 &&
455 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
456 sed -ne "/^author /s/.*> //p" head1 >at &&
457 sed -ne "/^committer /s/.*> //p" head1 >ct &&
458 test_cmp at ct
461 test_expect_success 'am without --committer-date-is-author-date' '
462 rm -fr .git/rebase-apply &&
463 git reset --hard &&
464 git checkout first &&
465 test_tick &&
466 git am patch1 &&
467 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
468 sed -ne "/^author /s/.*> //p" head1 >at &&
469 sed -ne "/^committer /s/.*> //p" head1 >ct &&
470 ! test_cmp at ct
473 # This checks for +0000 because TZ is set to UTC and that should
474 # show up when the current time is used. The date in message is set
475 # by test_tick that uses -0700 timezone; if this feature does not
476 # work, we will see that instead of +0000.
477 test_expect_success 'am --ignore-date' '
478 rm -fr .git/rebase-apply &&
479 git reset --hard &&
480 git checkout first &&
481 test_tick &&
482 git am --ignore-date patch1 &&
483 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
484 sed -ne "/^author /s/.*> //p" head1 >at &&
485 grep "+0000" at
488 test_expect_success 'am into an unborn branch' '
489 git rev-parse first^{tree} >expected &&
490 rm -fr .git/rebase-apply &&
491 git reset --hard &&
492 rm -fr subdir &&
493 mkdir subdir &&
494 git format-patch --numbered-files -o subdir -1 first &&
496 cd subdir &&
497 git init &&
498 git am 1
499 ) &&
501 cd subdir &&
502 git rev-parse HEAD^{tree} >../actual
503 ) &&
504 test_cmp expected actual
507 test_expect_success 'am newline in subject' '
508 rm -fr .git/rebase-apply &&
509 git reset --hard &&
510 git checkout first &&
511 test_tick &&
512 sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
513 git am <patchnl >output.out 2>&1 &&
514 test_i18ngrep "^Applying: second \\\n foo$" output.out
517 test_expect_success 'am -q is quiet' '
518 rm -fr .git/rebase-apply &&
519 git reset --hard &&
520 git checkout first &&
521 test_tick &&
522 git am -q <patch1 >output.out 2>&1 &&
523 ! test -s output.out
526 test_expect_success 'am empty-file does not infloop' '
527 rm -fr .git/rebase-apply &&
528 git reset --hard &&
529 touch empty-file &&
530 test_tick &&
531 test_must_fail git am empty-file 2>actual &&
532 echo Patch format detection failed. >expected &&
533 test_i18ncmp expected actual
536 test_expect_success 'am --message-id really adds the message id' '
537 rm -fr .git/rebase-apply &&
538 git reset --hard &&
539 git checkout HEAD^ &&
540 git am --message-id patch1.eml &&
541 test_path_is_missing .git/rebase-apply &&
542 git cat-file commit HEAD | tail -n1 >actual &&
543 grep Message-Id patch1.eml >expected &&
544 test_cmp expected actual
547 test_expect_success 'am --message-id -s signs off after the message id' '
548 rm -fr .git/rebase-apply &&
549 git reset --hard &&
550 git checkout HEAD^ &&
551 git am -s --message-id patch1.eml &&
552 test_path_is_missing .git/rebase-apply &&
553 git cat-file commit HEAD | tail -n2 | head -n1 >actual &&
554 grep Message-Id patch1.eml >expected &&
555 test_cmp expected actual
558 test_done