Revert "compat: add strtok_r()"
[git/mjg.git] / t / t4150-am.sh
blobcdafd7e7c1e6c73a97c36a60f77810badff603f2
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 q_to_tab <<-\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 -d .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 -d .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 -d .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 -d .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 -d .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 -d .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 -d .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 -d .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 -d .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 -d .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 -d .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 -d .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 -d .git/rebase-apply &&
362 git diff --exit-code lorem2^^ -- file &&
363 test_cmp expected another
366 test_expect_success 'am --resolved works' '
367 echo goodbye >expected &&
368 rm -fr .git/rebase-apply &&
369 git reset --hard &&
370 git checkout lorem2^^ &&
371 test_must_fail git am lorem-move.patch &&
372 test -d .git/rebase-apply &&
373 echo resolved >>file &&
374 git add file &&
375 git am --resolved &&
376 ! test -d .git/rebase-apply &&
377 test_cmp expected another
380 test_expect_success 'am takes patches from a Pine mailbox' '
381 rm -fr .git/rebase-apply &&
382 git reset --hard &&
383 git checkout first &&
384 cat pine patch1 | git am &&
385 ! test -d .git/rebase-apply &&
386 git diff --exit-code master^..HEAD
389 test_expect_success 'am fails on mail without patch' '
390 rm -fr .git/rebase-apply &&
391 git reset --hard &&
392 test_must_fail git am <failmail &&
393 git am --abort &&
394 ! test -d .git/rebase-apply
397 test_expect_success 'am fails on empty patch' '
398 rm -fr .git/rebase-apply &&
399 git reset --hard &&
400 echo "---" >>failmail &&
401 test_must_fail git am <failmail &&
402 git am --skip &&
403 ! test -d .git/rebase-apply
406 test_expect_success 'am works from stdin in subdirectory' '
407 rm -fr subdir &&
408 rm -fr .git/rebase-apply &&
409 git reset --hard &&
410 git checkout first &&
412 mkdir -p subdir &&
413 cd subdir &&
414 git am <../patch1
415 ) &&
416 git diff --exit-code second
419 test_expect_success 'am works from file (relative path given) in subdirectory' '
420 rm -fr subdir &&
421 rm -fr .git/rebase-apply &&
422 git reset --hard &&
423 git checkout first &&
425 mkdir -p subdir &&
426 cd subdir &&
427 git am ../patch1
428 ) &&
429 git diff --exit-code second
432 test_expect_success 'am works from file (absolute path given) in subdirectory' '
433 rm -fr subdir &&
434 rm -fr .git/rebase-apply &&
435 git reset --hard &&
436 git checkout first &&
437 P=$(pwd) &&
439 mkdir -p subdir &&
440 cd subdir &&
441 git am "$P/patch1"
442 ) &&
443 git diff --exit-code second
446 test_expect_success 'am --committer-date-is-author-date' '
447 rm -fr .git/rebase-apply &&
448 git reset --hard &&
449 git checkout first &&
450 test_tick &&
451 git am --committer-date-is-author-date patch1 &&
452 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
453 sed -ne "/^author /s/.*> //p" head1 >at &&
454 sed -ne "/^committer /s/.*> //p" head1 >ct &&
455 test_cmp at ct
458 test_expect_success 'am without --committer-date-is-author-date' '
459 rm -fr .git/rebase-apply &&
460 git reset --hard &&
461 git checkout first &&
462 test_tick &&
463 git am patch1 &&
464 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
465 sed -ne "/^author /s/.*> //p" head1 >at &&
466 sed -ne "/^committer /s/.*> //p" head1 >ct &&
467 ! test_cmp at ct
470 # This checks for +0000 because TZ is set to UTC and that should
471 # show up when the current time is used. The date in message is set
472 # by test_tick that uses -0700 timezone; if this feature does not
473 # work, we will see that instead of +0000.
474 test_expect_success 'am --ignore-date' '
475 rm -fr .git/rebase-apply &&
476 git reset --hard &&
477 git checkout first &&
478 test_tick &&
479 git am --ignore-date patch1 &&
480 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
481 sed -ne "/^author /s/.*> //p" head1 >at &&
482 grep "+0000" at
485 test_expect_success 'am into an unborn branch' '
486 git rev-parse first^{tree} >expected &&
487 rm -fr .git/rebase-apply &&
488 git reset --hard &&
489 rm -fr subdir &&
490 mkdir subdir &&
491 git format-patch --numbered-files -o subdir -1 first &&
493 cd subdir &&
494 git init &&
495 git am 1
496 ) &&
498 cd subdir &&
499 git rev-parse HEAD^{tree} >../actual
500 ) &&
501 test_cmp expected actual
504 test_expect_success 'am newline in subject' '
505 rm -fr .git/rebase-apply &&
506 git reset --hard &&
507 git checkout first &&
508 test_tick &&
509 sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
510 git am <patchnl >output.out 2>&1 &&
511 test_i18ngrep "^Applying: second \\\n foo$" output.out
514 test_expect_success 'am -q is quiet' '
515 rm -fr .git/rebase-apply &&
516 git reset --hard &&
517 git checkout first &&
518 test_tick &&
519 git am -q <patch1 >output.out 2>&1 &&
520 ! test -s output.out
523 test_expect_success 'am empty-file does not infloop' '
524 rm -fr .git/rebase-apply &&
525 git reset --hard &&
526 touch empty-file &&
527 test_tick &&
528 test_must_fail git am empty-file 2>actual &&
529 echo Patch format detection failed. >expected &&
530 test_i18ncmp expected actual
533 test_done