in_merge_bases(): omit unnecessary redundant common ancestor reduction
[git.git] / t / t4150-am.sh
blob658354a6ce8ab13fd6b229bb2adecd8e29de9697
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," 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\] third" actual
266 test_expect_success 'am -3 falls back to 3-way merge' '
267 rm -fr .git/rebase-apply &&
268 git reset --hard &&
269 git checkout -b lorem2 master2 &&
270 sed -n -e "3,\$p" msg >file &&
271 head -n 9 msg >>file &&
272 git add file &&
273 test_tick &&
274 git commit -m "copied stuff" &&
275 git am -3 lorem-move.patch &&
276 ! test -d .git/rebase-apply &&
277 git diff --exit-code lorem
280 test_expect_success 'am -3 -p0 can read --no-prefix patch' '
281 rm -fr .git/rebase-apply &&
282 git reset --hard &&
283 git checkout -b lorem3 master2 &&
284 sed -n -e "3,\$p" msg >file &&
285 head -n 9 msg >>file &&
286 git add file &&
287 test_tick &&
288 git commit -m "copied stuff" &&
289 git am -3 -p0 lorem-zero.patch &&
290 ! test -d .git/rebase-apply &&
291 git diff --exit-code lorem
294 test_expect_success 'am can rename a file' '
295 grep "^rename from" rename.patch &&
296 rm -fr .git/rebase-apply &&
297 git reset --hard &&
298 git checkout lorem^0 &&
299 git am rename.patch &&
300 ! test -d .git/rebase-apply &&
301 git update-index --refresh &&
302 git diff --exit-code rename
305 test_expect_success 'am -3 can rename a file' '
306 grep "^rename from" rename.patch &&
307 rm -fr .git/rebase-apply &&
308 git reset --hard &&
309 git checkout lorem^0 &&
310 git am -3 rename.patch &&
311 ! test -d .git/rebase-apply &&
312 git update-index --refresh &&
313 git diff --exit-code rename
316 test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '
317 grep "^rename from" rename-add.patch &&
318 rm -fr .git/rebase-apply &&
319 git reset --hard &&
320 git checkout lorem^0 &&
321 git am -3 rename-add.patch &&
322 ! test -d .git/rebase-apply &&
323 git update-index --refresh &&
324 git diff --exit-code rename
327 test_expect_success 'am -3 -q is quiet' '
328 rm -fr .git/rebase-apply &&
329 git checkout -f lorem2 &&
330 git reset master2 --hard &&
331 sed -n -e "3,\$p" msg >file &&
332 head -n 9 msg >>file &&
333 git add file &&
334 test_tick &&
335 git commit -m "copied stuff" &&
336 git am -3 -q lorem-move.patch >output.out 2>&1 &&
337 ! test -s output.out
340 test_expect_success 'am pauses on conflict' '
341 rm -fr .git/rebase-apply &&
342 git reset --hard &&
343 git checkout lorem2^^ &&
344 test_must_fail git am lorem-move.patch &&
345 test -d .git/rebase-apply
348 test_expect_success 'am --skip works' '
349 echo goodbye >expected &&
350 git am --skip &&
351 ! test -d .git/rebase-apply &&
352 git diff --exit-code lorem2^^ -- file &&
353 test_cmp expected another
356 test_expect_success 'am --resolved works' '
357 echo goodbye >expected &&
358 rm -fr .git/rebase-apply &&
359 git reset --hard &&
360 git checkout lorem2^^ &&
361 test_must_fail git am lorem-move.patch &&
362 test -d .git/rebase-apply &&
363 echo resolved >>file &&
364 git add file &&
365 git am --resolved &&
366 ! test -d .git/rebase-apply &&
367 test_cmp expected another
370 test_expect_success 'am takes patches from a Pine mailbox' '
371 rm -fr .git/rebase-apply &&
372 git reset --hard &&
373 git checkout first &&
374 cat pine patch1 | git am &&
375 ! test -d .git/rebase-apply &&
376 git diff --exit-code master^..HEAD
379 test_expect_success 'am fails on mail without patch' '
380 rm -fr .git/rebase-apply &&
381 git reset --hard &&
382 test_must_fail git am <failmail &&
383 git am --abort &&
384 ! test -d .git/rebase-apply
387 test_expect_success 'am fails on empty patch' '
388 rm -fr .git/rebase-apply &&
389 git reset --hard &&
390 echo "---" >>failmail &&
391 test_must_fail git am <failmail &&
392 git am --skip &&
393 ! test -d .git/rebase-apply
396 test_expect_success 'am works from stdin in subdirectory' '
397 rm -fr subdir &&
398 rm -fr .git/rebase-apply &&
399 git reset --hard &&
400 git checkout first &&
402 mkdir -p subdir &&
403 cd subdir &&
404 git am <../patch1
405 ) &&
406 git diff --exit-code second
409 test_expect_success 'am works from file (relative path given) 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 (absolute path given) in subdirectory' '
423 rm -fr subdir &&
424 rm -fr .git/rebase-apply &&
425 git reset --hard &&
426 git checkout first &&
427 P=$(pwd) &&
429 mkdir -p subdir &&
430 cd subdir &&
431 git am "$P/patch1"
432 ) &&
433 git diff --exit-code second
436 test_expect_success 'am --committer-date-is-author-date' '
437 rm -fr .git/rebase-apply &&
438 git reset --hard &&
439 git checkout first &&
440 test_tick &&
441 git am --committer-date-is-author-date patch1 &&
442 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
443 sed -ne "/^author /s/.*> //p" head1 >at &&
444 sed -ne "/^committer /s/.*> //p" head1 >ct &&
445 test_cmp at ct
448 test_expect_success 'am without --committer-date-is-author-date' '
449 rm -fr .git/rebase-apply &&
450 git reset --hard &&
451 git checkout first &&
452 test_tick &&
453 git am patch1 &&
454 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
455 sed -ne "/^author /s/.*> //p" head1 >at &&
456 sed -ne "/^committer /s/.*> //p" head1 >ct &&
457 ! test_cmp at ct
460 # This checks for +0000 because TZ is set to UTC and that should
461 # show up when the current time is used. The date in message is set
462 # by test_tick that uses -0700 timezone; if this feature does not
463 # work, we will see that instead of +0000.
464 test_expect_success 'am --ignore-date' '
465 rm -fr .git/rebase-apply &&
466 git reset --hard &&
467 git checkout first &&
468 test_tick &&
469 git am --ignore-date patch1 &&
470 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
471 sed -ne "/^author /s/.*> //p" head1 >at &&
472 grep "+0000" at
475 test_expect_success 'am into an unborn branch' '
476 git rev-parse first^{tree} >expected &&
477 rm -fr .git/rebase-apply &&
478 git reset --hard &&
479 rm -fr subdir &&
480 mkdir subdir &&
481 git format-patch --numbered-files -o subdir -1 first &&
483 cd subdir &&
484 git init &&
485 git am 1
486 ) &&
488 cd subdir &&
489 git rev-parse HEAD^{tree} >../actual
490 ) &&
491 test_cmp expected actual
494 test_expect_success 'am newline in subject' '
495 rm -fr .git/rebase-apply &&
496 git reset --hard &&
497 git checkout first &&
498 test_tick &&
499 sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
500 git am <patchnl >output.out 2>&1 &&
501 test_i18ngrep "^Applying: second \\\n foo$" output.out
504 test_expect_success 'am -q is quiet' '
505 rm -fr .git/rebase-apply &&
506 git reset --hard &&
507 git checkout first &&
508 test_tick &&
509 git am -q <patch1 >output.out 2>&1 &&
510 ! test -s output.out
513 test_expect_success 'am empty-file does not infloop' '
514 rm -fr .git/rebase-apply &&
515 git reset --hard &&
516 touch empty-file &&
517 test_tick &&
518 { git am empty-file > actual 2>&1 && false || :; } &&
519 echo Patch format detection failed. >expected &&
520 test_cmp expected actual
523 test_done