Code

am: learn passing -b to mailinfo
[git.git] / t / t4150-am.sh
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>"
71 '
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 &&
87         {
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 &&
93         {
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         sed -n -e "3,\$p" msg >file &&
101         git add file &&
102         test_tick &&
103         git commit -m third &&
105         git format-patch --stdout first >patch2 &&
107         git checkout -b lorem &&
108         sed -n -e "11,\$p" msg >file &&
109         head -n 9 msg >>file &&
110         test_tick &&
111         git commit -a -m "moved stuff" &&
113         echo goodbye >another &&
114         git add another &&
115         test_tick &&
116         git commit -m "added another file" &&
118         git format-patch --stdout master >lorem-move.patch &&
120         git checkout -b rename &&
121         git mv file renamed &&
122         git commit -m "renamed a file" &&
124         git format-patch -M --stdout lorem >rename.patch &&
126         git reset --soft lorem^ &&
127         git commit -m "renamed a file and added another" &&
129         git format-patch -M --stdout lorem^ >rename-add.patch &&
131         # reset time
132         unset test_tick &&
133         test_tick
136 test_expect_success 'am applies patch correctly' '
137         rm -fr .git/rebase-apply &&
138         git reset --hard &&
139         git checkout first &&
140         test_tick &&
141         git am <patch1 &&
142         ! test -d .git/rebase-apply &&
143         git diff --exit-code second &&
144         test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
145         test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
148 test_expect_success 'am applies patch e-mail not in a mbox' '
149         rm -fr .git/rebase-apply &&
150         git reset --hard &&
151         git checkout first &&
152         git am patch1.eml &&
153         ! test -d .git/rebase-apply &&
154         git diff --exit-code second &&
155         test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
156         test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
159 test_expect_success 'am applies patch e-mail not in a mbox with CRLF' '
160         rm -fr .git/rebase-apply &&
161         git reset --hard &&
162         git checkout first &&
163         git am patch1-crlf.eml &&
164         ! test -d .git/rebase-apply &&
165         git diff --exit-code second &&
166         test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
167         test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
170 test_expect_success 'setup: new author and committer' '
171         GIT_AUTHOR_NAME="Another Thor" &&
172         GIT_AUTHOR_EMAIL="a.thor@example.com" &&
173         GIT_COMMITTER_NAME="Co M Miter" &&
174         GIT_COMMITTER_EMAIL="c.miter@example.com" &&
175         export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
178 compare () {
179         a=$(git cat-file commit "$2" | grep "^$1 ") &&
180         b=$(git cat-file commit "$3" | grep "^$1 ") &&
181         test "$a" = "$b"
184 test_expect_success 'am changes committer and keeps author' '
185         test_tick &&
186         rm -fr .git/rebase-apply &&
187         git reset --hard &&
188         git checkout first &&
189         git am patch2 &&
190         ! test -d .git/rebase-apply &&
191         test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" &&
192         git diff --exit-code master..HEAD &&
193         git diff --exit-code master^..HEAD^ &&
194         compare author master HEAD &&
195         compare author master^ HEAD^ &&
196         test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
197              "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
200 test_expect_success 'am --signoff adds Signed-off-by: line' '
201         rm -fr .git/rebase-apply &&
202         git reset --hard &&
203         git checkout -b master2 first &&
204         git am --signoff <patch2 &&
205         printf "%s\n" "$signoff" >expected &&
206         echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >>expected &&
207         git cat-file commit HEAD^ | grep "Signed-off-by:" >actual &&
208         test_cmp expected actual &&
209         echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected &&
210         git cat-file commit HEAD | grep "Signed-off-by:" >actual &&
211         test_cmp expected actual
214 test_expect_success 'am stays in branch' '
215         echo refs/heads/master2 >expected &&
216         git symbolic-ref HEAD >actual &&
217         test_cmp expected actual
220 test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
221         git format-patch --stdout HEAD^ >patch3 &&
222         sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," patch3 >patch4 &&
223         rm -fr .git/rebase-apply &&
224         git reset --hard &&
225         git checkout HEAD^ &&
226         git am --signoff patch4 &&
227         git cat-file commit HEAD >actual &&
228         test $(grep -c "^Signed-off-by:" actual) -eq 1
231 test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
232         git rev-parse HEAD >expected &&
233         git rev-parse master2 >actual &&
234         test_cmp expected actual
237 test_expect_success 'am --keep really keeps the subject' '
238         rm -fr .git/rebase-apply &&
239         git reset --hard &&
240         git checkout HEAD^ &&
241         git am --keep patch4 &&
242         ! test -d .git/rebase-apply &&
243         git cat-file commit HEAD >actual &&
244         grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
247 test_expect_failure 'am --keep-non-patch really keeps the non-patch part' '
248         rm -fr .git/rebase-apply &&
249         git reset --hard &&
250         git checkout HEAD^ &&
251         git am --keep-non-patch patch4 &&
252         ! test -d .git/rebase-apply &&
253         git cat-file commit HEAD >actual &&
254         grep "^\[foo\] third" actual
257 test_expect_success 'am -3 falls back to 3-way merge' '
258         rm -fr .git/rebase-apply &&
259         git reset --hard &&
260         git checkout -b lorem2 master2 &&
261         sed -n -e "3,\$p" msg >file &&
262         head -n 9 msg >>file &&
263         git add file &&
264         test_tick &&
265         git commit -m "copied stuff" &&
266         git am -3 lorem-move.patch &&
267         ! test -d .git/rebase-apply &&
268         git diff --exit-code lorem
271 test_expect_success 'am can rename a file' '
272         grep "^rename from" rename.patch &&
273         rm -fr .git/rebase-apply &&
274         git reset --hard &&
275         git checkout lorem^0 &&
276         git am rename.patch &&
277         ! test -d .git/rebase-apply &&
278         git update-index --refresh &&
279         git diff --exit-code rename
282 test_expect_success 'am -3 can rename a file' '
283         grep "^rename from" rename.patch &&
284         rm -fr .git/rebase-apply &&
285         git reset --hard &&
286         git checkout lorem^0 &&
287         git am -3 rename.patch &&
288         ! test -d .git/rebase-apply &&
289         git update-index --refresh &&
290         git diff --exit-code rename
293 test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '
294         grep "^rename from" rename-add.patch &&
295         rm -fr .git/rebase-apply &&
296         git reset --hard &&
297         git checkout lorem^0 &&
298         git am -3 rename-add.patch &&
299         ! test -d .git/rebase-apply &&
300         git update-index --refresh &&
301         git diff --exit-code rename
304 test_expect_success 'am -3 -q is quiet' '
305         rm -fr .git/rebase-apply &&
306         git checkout -f lorem2 &&
307         git reset master2 --hard &&
308         sed -n -e "3,\$p" msg >file &&
309         head -n 9 msg >>file &&
310         git add file &&
311         test_tick &&
312         git commit -m "copied stuff" &&
313         git am -3 -q lorem-move.patch >output.out 2>&1 &&
314         ! test -s output.out
317 test_expect_success 'am pauses on conflict' '
318         rm -fr .git/rebase-apply &&
319         git reset --hard &&
320         git checkout lorem2^^ &&
321         test_must_fail git am lorem-move.patch &&
322         test -d .git/rebase-apply
325 test_expect_success 'am --skip works' '
326         echo goodbye >expected &&
327         git am --skip &&
328         ! test -d .git/rebase-apply &&
329         git diff --exit-code lorem2^^ -- file &&
330         test_cmp expected another
333 test_expect_success 'am --resolved works' '
334         echo goodbye >expected &&
335         rm -fr .git/rebase-apply &&
336         git reset --hard &&
337         git checkout lorem2^^ &&
338         test_must_fail git am lorem-move.patch &&
339         test -d .git/rebase-apply &&
340         echo resolved >>file &&
341         git add file &&
342         git am --resolved &&
343         ! test -d .git/rebase-apply &&
344         test_cmp expected another
347 test_expect_success 'am takes patches from a Pine mailbox' '
348         rm -fr .git/rebase-apply &&
349         git reset --hard &&
350         git checkout first &&
351         cat pine patch1 | git am &&
352         ! test -d .git/rebase-apply &&
353         git diff --exit-code master^..HEAD
356 test_expect_success 'am fails on mail without patch' '
357         rm -fr .git/rebase-apply &&
358         git reset --hard &&
359         test_must_fail git am <failmail &&
360         git am --abort &&
361         ! test -d .git/rebase-apply
364 test_expect_success 'am fails on empty patch' '
365         rm -fr .git/rebase-apply &&
366         git reset --hard &&
367         echo "---" >>failmail &&
368         test_must_fail git am <failmail &&
369         git am --skip &&
370         ! test -d .git/rebase-apply
373 test_expect_success 'am works from stdin in subdirectory' '
374         rm -fr subdir &&
375         rm -fr .git/rebase-apply &&
376         git reset --hard &&
377         git checkout first &&
378         (
379                 mkdir -p subdir &&
380                 cd subdir &&
381                 git am <../patch1
382         ) &&
383         git diff --exit-code second
386 test_expect_success 'am works from file (relative path given) in subdirectory' '
387         rm -fr subdir &&
388         rm -fr .git/rebase-apply &&
389         git reset --hard &&
390         git checkout first &&
391         (
392                 mkdir -p subdir &&
393                 cd subdir &&
394                 git am ../patch1
395         ) &&
396         git diff --exit-code second
399 test_expect_success 'am works from file (absolute path given) in subdirectory' '
400         rm -fr subdir &&
401         rm -fr .git/rebase-apply &&
402         git reset --hard &&
403         git checkout first &&
404         P=$(pwd) &&
405         (
406                 mkdir -p subdir &&
407                 cd subdir &&
408                 git am "$P/patch1"
409         ) &&
410         git diff --exit-code second
413 test_expect_success 'am --committer-date-is-author-date' '
414         rm -fr .git/rebase-apply &&
415         git reset --hard &&
416         git checkout first &&
417         test_tick &&
418         git am --committer-date-is-author-date patch1 &&
419         git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
420         sed -ne "/^author /s/.*> //p" head1 >at &&
421         sed -ne "/^committer /s/.*> //p" head1 >ct &&
422         test_cmp at ct
425 test_expect_success 'am without --committer-date-is-author-date' '
426         rm -fr .git/rebase-apply &&
427         git reset --hard &&
428         git checkout first &&
429         test_tick &&
430         git am patch1 &&
431         git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
432         sed -ne "/^author /s/.*> //p" head1 >at &&
433         sed -ne "/^committer /s/.*> //p" head1 >ct &&
434         ! test_cmp at ct
437 # This checks for +0000 because TZ is set to UTC and that should
438 # show up when the current time is used. The date in message is set
439 # by test_tick that uses -0700 timezone; if this feature does not
440 # work, we will see that instead of +0000.
441 test_expect_success 'am --ignore-date' '
442         rm -fr .git/rebase-apply &&
443         git reset --hard &&
444         git checkout first &&
445         test_tick &&
446         git am --ignore-date patch1 &&
447         git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
448         sed -ne "/^author /s/.*> //p" head1 >at &&
449         grep "+0000" at
452 test_expect_success 'am into an unborn branch' '
453         git rev-parse first^{tree} >expected &&
454         rm -fr .git/rebase-apply &&
455         git reset --hard &&
456         rm -fr subdir &&
457         mkdir subdir &&
458         git format-patch --numbered-files -o subdir -1 first &&
459         (
460                 cd subdir &&
461                 git init &&
462                 git am 1
463         ) &&
464         (
465                 cd subdir &&
466                 git rev-parse HEAD^{tree} >../actual
467         ) &&
468         test_cmp expected actual
471 test_expect_success 'am newline in subject' '
472         rm -fr .git/rebase-apply &&
473         git reset --hard &&
474         git checkout first &&
475         test_tick &&
476         sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
477         git am <patchnl >output.out 2>&1 &&
478         grep "^Applying: second \\\n foo$" output.out
481 test_expect_success 'am -q is quiet' '
482         rm -fr .git/rebase-apply &&
483         git reset --hard &&
484         git checkout first &&
485         test_tick &&
486         git am -q <patch1 >output.out 2>&1 &&
487         ! test -s output.out
490 test_done