51962e481ea69e476776a15d7a651ed25ade5f01
1#!/bin/sh
2
3test_description='git am running'
4
5. ./test-lib.sh
6
7test_expect_success 'setup: messages' '
8 cat >msg <<-\EOF &&
9 second
10
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.
18
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 &&
28
29 Lorem ipsum dolor sit amet,
30 consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
31 laoreet dolore magna aliquam erat volutpat.
32
33 git
34 ---
35 +++
36
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
44
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
51
52 Sometimes we have to find out that there'\''s nothing left.
53
54 EOF
55
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>
62
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.
67
68 EOF
69
70 signoff="Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
71'
72
73test_expect_success setup '
74 echo hello >file &&
75 git add file &&
76 test_tick &&
77 git commit -m first &&
78 git tag first &&
79
80 echo world >>file &&
81 git add file &&
82 test_tick &&
83 git commit -s -F msg &&
84 git tag second &&
85
86 git format-patch --stdout first >patch1 &&
87 {
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 &&
94 {
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 &&
100 {
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 &&
107 {
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
120 sed -n -e "3,\$p" msg >file &&
121 git add file &&
122 test_tick &&
123 git commit -m third &&
124
125 git format-patch --stdout first >patch2 &&
126
127 git checkout -b lorem &&
128 sed -n -e "11,\$p" msg >file &&
129 head -n 9 msg >>file &&
130 test_tick &&
131 git commit -a -m "moved stuff" &&
132
133 echo goodbye >another &&
134 git add another &&
135 test_tick &&
136 git commit -m "added another file" &&
137
138 git format-patch --stdout master >lorem-move.patch &&
139 git format-patch --no-prefix --stdout master >lorem-zero.patch &&
140
141 git checkout -b rename &&
142 git mv file renamed &&
143 git commit -m "renamed a file" &&
144
145 git format-patch -M --stdout lorem >rename.patch &&
146
147 git reset --soft lorem^ &&
148 git commit -m "renamed a file and added another" &&
149
150 git format-patch -M --stdout lorem^ >rename-add.patch &&
151
152 # reset time
153 sane_unset test_tick &&
154 test_tick
155'
156
157test_expect_success 'am applies patch correctly' '
158 rm -fr .git/rebase-apply &&
159 git reset --hard &&
160 git checkout first &&
161 test_tick &&
162 git am <patch1 &&
163 test_path_is_missing .git/rebase-apply &&
164 git diff --exit-code second &&
165 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
166 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
167'
168
169test_expect_success 'am applies patch e-mail not in a mbox' '
170 rm -fr .git/rebase-apply &&
171 git reset --hard &&
172 git checkout first &&
173 git am patch1.eml &&
174 test_path_is_missing .git/rebase-apply &&
175 git diff --exit-code second &&
176 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
177 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
178'
179
180test_expect_success 'am applies patch e-mail not in a mbox with CRLF' '
181 rm -fr .git/rebase-apply &&
182 git reset --hard &&
183 git checkout first &&
184 git am patch1-crlf.eml &&
185 test_path_is_missing .git/rebase-apply &&
186 git diff --exit-code second &&
187 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
188 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
189'
190
191test_expect_success 'am applies patch e-mail with preceding whitespace' '
192 rm -fr .git/rebase-apply &&
193 git reset --hard &&
194 git checkout first &&
195 git am patch1-ws.eml &&
196 test_path_is_missing .git/rebase-apply &&
197 git diff --exit-code second &&
198 test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
199 test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
200'
201
202test_expect_success 'am applies stgit patch' '
203 rm -fr .git/rebase-apply &&
204 git checkout -f first &&
205 git am patch1-stgit.eml &&
206 test_path_is_missing .git/rebase-apply &&
207 git diff --exit-code second &&
208 test_cmp_rev second HEAD &&
209 test_cmp_rev second^ HEAD^
210'
211
212test_expect_success 'am --patch-format=stgit applies stgit patch' '
213 rm -fr .git/rebase-apply &&
214 git checkout -f first &&
215 git am --patch-format=stgit <patch1-stgit.eml &&
216 test_path_is_missing .git/rebase-apply &&
217 git diff --exit-code second &&
218 test_cmp_rev second HEAD &&
219 test_cmp_rev second^ HEAD^
220'
221
222test_expect_success 'setup: new author and committer' '
223 GIT_AUTHOR_NAME="Another Thor" &&
224 GIT_AUTHOR_EMAIL="a.thor@example.com" &&
225 GIT_COMMITTER_NAME="Co M Miter" &&
226 GIT_COMMITTER_EMAIL="c.miter@example.com" &&
227 export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
228'
229
230compare () {
231 a=$(git cat-file commit "$2" | grep "^$1 ") &&
232 b=$(git cat-file commit "$3" | grep "^$1 ") &&
233 test "$a" = "$b"
234}
235
236test_expect_success 'am changes committer and keeps author' '
237 test_tick &&
238 rm -fr .git/rebase-apply &&
239 git reset --hard &&
240 git checkout first &&
241 git am patch2 &&
242 test_path_is_missing .git/rebase-apply &&
243 test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" &&
244 git diff --exit-code master..HEAD &&
245 git diff --exit-code master^..HEAD^ &&
246 compare author master HEAD &&
247 compare author master^ HEAD^ &&
248 test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
249 "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
250'
251
252test_expect_success 'am --signoff adds Signed-off-by: line' '
253 rm -fr .git/rebase-apply &&
254 git reset --hard &&
255 git checkout -b master2 first &&
256 git am --signoff <patch2 &&
257 printf "%s\n" "$signoff" >expected &&
258 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >>expected &&
259 git cat-file commit HEAD^ | grep "Signed-off-by:" >actual &&
260 test_cmp expected actual &&
261 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected &&
262 git cat-file commit HEAD | grep "Signed-off-by:" >actual &&
263 test_cmp expected actual
264'
265
266test_expect_success 'am stays in branch' '
267 echo refs/heads/master2 >expected &&
268 git symbolic-ref HEAD >actual &&
269 test_cmp expected actual
270'
271
272test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
273 git format-patch --stdout HEAD^ >patch3 &&
274 sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," patch3 >patch4 &&
275 rm -fr .git/rebase-apply &&
276 git reset --hard &&
277 git checkout HEAD^ &&
278 git am --signoff patch4 &&
279 git cat-file commit HEAD >actual &&
280 test $(grep -c "^Signed-off-by:" actual) -eq 1
281'
282
283test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
284 git rev-parse HEAD >expected &&
285 git rev-parse master2 >actual &&
286 test_cmp expected actual
287'
288
289test_expect_success 'am --keep really keeps the subject' '
290 rm -fr .git/rebase-apply &&
291 git reset --hard &&
292 git checkout HEAD^ &&
293 git am --keep patch4 &&
294 test_path_is_missing .git/rebase-apply &&
295 git cat-file commit HEAD >actual &&
296 grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
297'
298
299test_expect_success 'am --keep-non-patch really keeps the non-patch part' '
300 rm -fr .git/rebase-apply &&
301 git reset --hard &&
302 git checkout HEAD^ &&
303 git am --keep-non-patch patch4 &&
304 test_path_is_missing .git/rebase-apply &&
305 git cat-file commit HEAD >actual &&
306 grep "^\[foo\] third" actual
307'
308
309test_expect_success 'am -3 falls back to 3-way merge' '
310 rm -fr .git/rebase-apply &&
311 git reset --hard &&
312 git checkout -b lorem2 master2 &&
313 sed -n -e "3,\$p" msg >file &&
314 head -n 9 msg >>file &&
315 git add file &&
316 test_tick &&
317 git commit -m "copied stuff" &&
318 git am -3 lorem-move.patch &&
319 test_path_is_missing .git/rebase-apply &&
320 git diff --exit-code lorem
321'
322
323test_expect_success 'am -3 -p0 can read --no-prefix patch' '
324 rm -fr .git/rebase-apply &&
325 git reset --hard &&
326 git checkout -b lorem3 master2 &&
327 sed -n -e "3,\$p" msg >file &&
328 head -n 9 msg >>file &&
329 git add file &&
330 test_tick &&
331 git commit -m "copied stuff" &&
332 git am -3 -p0 lorem-zero.patch &&
333 test_path_is_missing .git/rebase-apply &&
334 git diff --exit-code lorem
335'
336
337test_expect_success 'am can rename a file' '
338 grep "^rename from" rename.patch &&
339 rm -fr .git/rebase-apply &&
340 git reset --hard &&
341 git checkout lorem^0 &&
342 git am rename.patch &&
343 test_path_is_missing .git/rebase-apply &&
344 git update-index --refresh &&
345 git diff --exit-code rename
346'
347
348test_expect_success 'am -3 can rename a file' '
349 grep "^rename from" rename.patch &&
350 rm -fr .git/rebase-apply &&
351 git reset --hard &&
352 git checkout lorem^0 &&
353 git am -3 rename.patch &&
354 test_path_is_missing .git/rebase-apply &&
355 git update-index --refresh &&
356 git diff --exit-code rename
357'
358
359test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '
360 grep "^rename from" rename-add.patch &&
361 rm -fr .git/rebase-apply &&
362 git reset --hard &&
363 git checkout lorem^0 &&
364 git am -3 rename-add.patch &&
365 test_path_is_missing .git/rebase-apply &&
366 git update-index --refresh &&
367 git diff --exit-code rename
368'
369
370test_expect_success 'am -3 -q is quiet' '
371 rm -fr .git/rebase-apply &&
372 git checkout -f lorem2 &&
373 git reset master2 --hard &&
374 sed -n -e "3,\$p" msg >file &&
375 head -n 9 msg >>file &&
376 git add file &&
377 test_tick &&
378 git commit -m "copied stuff" &&
379 git am -3 -q lorem-move.patch >output.out 2>&1 &&
380 ! test -s output.out
381'
382
383test_expect_success 'am pauses on conflict' '
384 rm -fr .git/rebase-apply &&
385 git reset --hard &&
386 git checkout lorem2^^ &&
387 test_must_fail git am lorem-move.patch &&
388 test -d .git/rebase-apply
389'
390
391test_expect_success 'am --skip works' '
392 echo goodbye >expected &&
393 git am --skip &&
394 test_path_is_missing .git/rebase-apply &&
395 git diff --exit-code lorem2^^ -- file &&
396 test_cmp expected another
397'
398
399test_expect_success 'am --abort removes a stray directory' '
400 mkdir .git/rebase-apply &&
401 git am --abort &&
402 test_path_is_missing .git/rebase-apply
403'
404
405test_expect_success 'am --resolved works' '
406 echo goodbye >expected &&
407 rm -fr .git/rebase-apply &&
408 git reset --hard &&
409 git checkout lorem2^^ &&
410 test_must_fail git am lorem-move.patch &&
411 test -d .git/rebase-apply &&
412 echo resolved >>file &&
413 git add file &&
414 git am --resolved &&
415 test_path_is_missing .git/rebase-apply &&
416 test_cmp expected another
417'
418
419test_expect_success 'am takes patches from a Pine mailbox' '
420 rm -fr .git/rebase-apply &&
421 git reset --hard &&
422 git checkout first &&
423 cat pine patch1 | git am &&
424 test_path_is_missing .git/rebase-apply &&
425 git diff --exit-code master^..HEAD
426'
427
428test_expect_success 'am fails on mail without patch' '
429 rm -fr .git/rebase-apply &&
430 git reset --hard &&
431 test_must_fail git am <failmail &&
432 git am --abort &&
433 test_path_is_missing .git/rebase-apply
434'
435
436test_expect_success 'am fails on empty patch' '
437 rm -fr .git/rebase-apply &&
438 git reset --hard &&
439 echo "---" >>failmail &&
440 test_must_fail git am <failmail &&
441 git am --skip &&
442 test_path_is_missing .git/rebase-apply
443'
444
445test_expect_success 'am works from stdin in subdirectory' '
446 rm -fr subdir &&
447 rm -fr .git/rebase-apply &&
448 git reset --hard &&
449 git checkout first &&
450 (
451 mkdir -p subdir &&
452 cd subdir &&
453 git am <../patch1
454 ) &&
455 git diff --exit-code second
456'
457
458test_expect_success 'am works from file (relative path given) in subdirectory' '
459 rm -fr subdir &&
460 rm -fr .git/rebase-apply &&
461 git reset --hard &&
462 git checkout first &&
463 (
464 mkdir -p subdir &&
465 cd subdir &&
466 git am ../patch1
467 ) &&
468 git diff --exit-code second
469'
470
471test_expect_success 'am works from file (absolute path given) in subdirectory' '
472 rm -fr subdir &&
473 rm -fr .git/rebase-apply &&
474 git reset --hard &&
475 git checkout first &&
476 P=$(pwd) &&
477 (
478 mkdir -p subdir &&
479 cd subdir &&
480 git am "$P/patch1"
481 ) &&
482 git diff --exit-code second
483'
484
485test_expect_success 'am --committer-date-is-author-date' '
486 rm -fr .git/rebase-apply &&
487 git reset --hard &&
488 git checkout first &&
489 test_tick &&
490 git am --committer-date-is-author-date patch1 &&
491 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
492 sed -ne "/^author /s/.*> //p" head1 >at &&
493 sed -ne "/^committer /s/.*> //p" head1 >ct &&
494 test_cmp at ct
495'
496
497test_expect_success 'am without --committer-date-is-author-date' '
498 rm -fr .git/rebase-apply &&
499 git reset --hard &&
500 git checkout first &&
501 test_tick &&
502 git am patch1 &&
503 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
504 sed -ne "/^author /s/.*> //p" head1 >at &&
505 sed -ne "/^committer /s/.*> //p" head1 >ct &&
506 ! test_cmp at ct
507'
508
509# This checks for +0000 because TZ is set to UTC and that should
510# show up when the current time is used. The date in message is set
511# by test_tick that uses -0700 timezone; if this feature does not
512# work, we will see that instead of +0000.
513test_expect_success 'am --ignore-date' '
514 rm -fr .git/rebase-apply &&
515 git reset --hard &&
516 git checkout first &&
517 test_tick &&
518 git am --ignore-date patch1 &&
519 git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
520 sed -ne "/^author /s/.*> //p" head1 >at &&
521 grep "+0000" at
522'
523
524test_expect_success 'am into an unborn branch' '
525 git rev-parse first^{tree} >expected &&
526 rm -fr .git/rebase-apply &&
527 git reset --hard &&
528 rm -fr subdir &&
529 mkdir subdir &&
530 git format-patch --numbered-files -o subdir -1 first &&
531 (
532 cd subdir &&
533 git init &&
534 git am 1
535 ) &&
536 (
537 cd subdir &&
538 git rev-parse HEAD^{tree} >../actual
539 ) &&
540 test_cmp expected actual
541'
542
543test_expect_success 'am newline in subject' '
544 rm -fr .git/rebase-apply &&
545 git reset --hard &&
546 git checkout first &&
547 test_tick &&
548 sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
549 git am <patchnl >output.out 2>&1 &&
550 test_i18ngrep "^Applying: second \\\n foo$" output.out
551'
552
553test_expect_success 'am -q is quiet' '
554 rm -fr .git/rebase-apply &&
555 git reset --hard &&
556 git checkout first &&
557 test_tick &&
558 git am -q <patch1 >output.out 2>&1 &&
559 ! test -s output.out
560'
561
562test_expect_success 'am empty-file does not infloop' '
563 rm -fr .git/rebase-apply &&
564 git reset --hard &&
565 touch empty-file &&
566 test_tick &&
567 test_must_fail git am empty-file 2>actual &&
568 echo Patch format detection failed. >expected &&
569 test_i18ncmp expected actual
570'
571
572test_expect_success 'am --message-id really adds the message id' '
573 rm -fr .git/rebase-apply &&
574 git reset --hard &&
575 git checkout HEAD^ &&
576 git am --message-id patch1.eml &&
577 test_path_is_missing .git/rebase-apply &&
578 git cat-file commit HEAD | tail -n1 >actual &&
579 grep Message-Id patch1.eml >expected &&
580 test_cmp expected actual
581'
582
583test_expect_success 'am --message-id -s signs off after the message id' '
584 rm -fr .git/rebase-apply &&
585 git reset --hard &&
586 git checkout HEAD^ &&
587 git am -s --message-id patch1.eml &&
588 test_path_is_missing .git/rebase-apply &&
589 git cat-file commit HEAD | tail -n2 | head -n1 >actual &&
590 grep Message-Id patch1.eml >expected &&
591 test_cmp expected actual
592'
593
594test_done