Merge branch 'jk/use-our-regexp'
[git] / t / t4150-am.sh
1 #!/bin/sh
2
3 test_description='git am running'
4
5 . ./test-lib.sh
6
7 cat >msg <<EOF
8 second
9
10 Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, sed diam nonumy
11 eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
12 voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita
13 kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem
14 ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
15 tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At
16 vero eos et accusam et justo duo dolores et ea rebum.
17
18         Duis autem vel eum iriure dolor in hendrerit in vulputate velit
19         esse molestie consequat, vel illum dolore eu feugiat nulla facilisis
20         at vero eros et accumsan et iusto odio dignissim qui blandit
21         praesent luptatum zzril delenit augue duis dolore te feugait nulla
22         facilisi.
23
24
25 Lorem ipsum dolor sit amet,
26 consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
27 laoreet dolore magna aliquam erat volutpat.
28
29   git
30   ---
31   +++
32
33 Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit
34 lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure
35 dolor in hendrerit in vulputate velit esse molestie consequat, vel illum
36 dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
37 dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te
38 feugait nulla facilisi.
39 EOF
40
41 cat >failmail <<EOF
42 From foo@example.com Fri May 23 10:43:49 2008
43 From:   foo@example.com
44 To:     bar@example.com
45 Subject: Re: [RFC/PATCH] git-foo.sh
46 Date:   Fri, 23 May 2008 05:23:42 +0200
47
48 Sometimes we have to find out that there's nothing left.
49
50 EOF
51
52 cat >pine <<EOF
53 From MAILER-DAEMON Fri May 23 10:43:49 2008
54 Date: 23 May 2008 05:23:42 +0200
55 From: Mail System Internal Data <MAILER-DAEMON@example.com>
56 Subject: DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA
57 Message-ID: <foo-0001@example.com>
58
59 This text is part of the internal format of your mail folder, and is not
60 a real message.  It is created automatically by the mail system software.
61 If deleted, important folder data will be lost, and it will be re-created
62 with the data reset to initial values.
63
64 EOF
65
66 echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected
67
68 test_expect_success setup '
69         echo hello >file &&
70         git add file &&
71         test_tick &&
72         git commit -m first &&
73         git tag first &&
74         echo world >>file &&
75         git add file &&
76         test_tick &&
77         git commit -s -F msg &&
78         git tag second &&
79         git format-patch --stdout first >patch1 &&
80         sed -n -e "3,\$p" msg >file &&
81         git add file &&
82         test_tick &&
83         git commit -m third &&
84         git format-patch --stdout first >patch2 &&
85         git checkout -b lorem &&
86         sed -n -e "11,\$p" msg >file &&
87         head -n 9 msg >>file &&
88         test_tick &&
89         git commit -a -m "moved stuff" &&
90         echo goodbye >another &&
91         git add another &&
92         test_tick &&
93         git commit -m "added another file" &&
94         git format-patch --stdout master >lorem-move.patch
95 '
96
97 # reset time
98 unset test_tick
99 test_tick
100
101 test_expect_success 'am applies patch correctly' '
102         git checkout first &&
103         test_tick &&
104         git am <patch1 &&
105         ! test -d .git/rebase-apply &&
106         test -z "$(git diff second)" &&
107         test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
108         test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
109 '
110
111 GIT_AUTHOR_NAME="Another Thor"
112 GIT_AUTHOR_EMAIL="a.thor@example.com"
113 GIT_COMMITTER_NAME="Co M Miter"
114 GIT_COMMITTER_EMAIL="c.miter@example.com"
115 export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
116
117 compare () {
118         test "$(git cat-file commit "$2" | grep "^$1 ")" = \
119              "$(git cat-file commit "$3" | grep "^$1 ")"
120 }
121
122 test_expect_success 'am changes committer and keeps author' '
123         test_tick &&
124         git checkout first &&
125         git am patch2 &&
126         ! test -d .git/rebase-apply &&
127         test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" &&
128         test -z "$(git diff master..HEAD)" &&
129         test -z "$(git diff master^..HEAD^)" &&
130         compare author master HEAD &&
131         compare author master^ HEAD^ &&
132         test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
133              "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
134 '
135
136 test_expect_success 'am --signoff adds Signed-off-by: line' '
137         git checkout -b master2 first &&
138         git am --signoff <patch2 &&
139         echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >>expected &&
140         git cat-file commit HEAD^ | grep "Signed-off-by:" >actual &&
141         test_cmp actual expected &&
142         echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected &&
143         git cat-file commit HEAD | grep "Signed-off-by:" >actual &&
144         test_cmp actual expected
145 '
146
147 test_expect_success 'am stays in branch' '
148         test "refs/heads/master2" = "$(git symbolic-ref HEAD)"
149 '
150
151 test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
152         git format-patch --stdout HEAD^ >patch3 &&
153         sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2," patch3 >patch4
154         git checkout HEAD^ &&
155         git am --signoff patch4 &&
156         test "$(git cat-file commit HEAD | grep -c "^Signed-off-by:")" -eq 1
157 '
158
159 test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
160         test "$(git rev-parse HEAD)" = "$(git rev-parse master2)"
161 '
162
163 test_expect_success 'am --keep really keeps the subject' '
164         git checkout HEAD^ &&
165         git am --keep patch4 &&
166         ! test -d .git/rebase-apply &&
167         git cat-file commit HEAD |
168                 fgrep "Re: Re: Re: [PATCH 1/5 v2] third"
169 '
170
171 test_expect_success 'am -3 falls back to 3-way merge' '
172         git checkout -b lorem2 master2 &&
173         sed -n -e "3,\$p" msg >file &&
174         head -n 9 msg >>file &&
175         git add file &&
176         test_tick &&
177         git commit -m "copied stuff" &&
178         git am -3 lorem-move.patch &&
179         ! test -d .git/rebase-apply &&
180         test -z "$(git diff lorem)"
181 '
182
183 test_expect_success 'am -3 -q is quiet' '
184         git reset master2 --hard &&
185         sed -n -e "3,\$p" msg >file &&
186         head -n 9 msg >>file &&
187         git add file &&
188         test_tick &&
189         git commit -m "copied stuff" &&
190         git am -3 -q lorem-move.patch > output.out 2>&1 &&
191         ! test -s output.out
192 '
193
194 test_expect_success 'am pauses on conflict' '
195         git checkout lorem2^^ &&
196         test_must_fail git am lorem-move.patch &&
197         test -d .git/rebase-apply
198 '
199
200 test_expect_success 'am --skip works' '
201         git am --skip &&
202         ! test -d .git/rebase-apply &&
203         test -z "$(git diff lorem2^^ -- file)" &&
204         test goodbye = "$(cat another)"
205 '
206
207 test_expect_success 'am --resolved works' '
208         git checkout lorem2^^ &&
209         test_must_fail git am lorem-move.patch &&
210         test -d .git/rebase-apply &&
211         echo resolved >>file &&
212         git add file &&
213         git am --resolved &&
214         ! test -d .git/rebase-apply &&
215         test goodbye = "$(cat another)"
216 '
217
218 test_expect_success 'am takes patches from a Pine mailbox' '
219         git checkout first &&
220         cat pine patch1 | git am &&
221         ! test -d .git/rebase-apply &&
222         test -z "$(git diff master^..HEAD)"
223 '
224
225 test_expect_success 'am fails on mail without patch' '
226         test_must_fail git am <failmail &&
227         rm -r .git/rebase-apply/
228 '
229
230 test_expect_success 'am fails on empty patch' '
231         echo "---" >>failmail &&
232         test_must_fail git am <failmail &&
233         git am --skip &&
234         ! test -d .git/rebase-apply
235 '
236
237 test_expect_success 'am works from stdin in subdirectory' '
238         rm -fr subdir &&
239         git checkout first &&
240         (
241                 mkdir -p subdir &&
242                 cd subdir &&
243                 git am <../patch1
244         ) &&
245         test -z "$(git diff second)"
246 '
247
248 test_expect_success 'am works from file (relative path given) in subdirectory' '
249         rm -fr subdir &&
250         git checkout first &&
251         (
252                 mkdir -p subdir &&
253                 cd subdir &&
254                 git am ../patch1
255         ) &&
256         test -z "$(git diff second)"
257 '
258
259 test_expect_success 'am works from file (absolute path given) in subdirectory' '
260         rm -fr subdir &&
261         git checkout first &&
262         P=$(pwd) &&
263         (
264                 mkdir -p subdir &&
265                 cd subdir &&
266                 git am "$P/patch1"
267         ) &&
268         test -z "$(git diff second)"
269 '
270
271 test_expect_success 'am --committer-date-is-author-date' '
272         git checkout first &&
273         test_tick &&
274         git am --committer-date-is-author-date patch1 &&
275         git cat-file commit HEAD | sed -e "/^$/q" >head1 &&
276         at=$(sed -ne "/^author /s/.*> //p" head1) &&
277         ct=$(sed -ne "/^committer /s/.*> //p" head1) &&
278         test "$at" = "$ct"
279 '
280
281 test_expect_success 'am without --committer-date-is-author-date' '
282         git checkout first &&
283         test_tick &&
284         git am patch1 &&
285         git cat-file commit HEAD | sed -e "/^$/q" >head1 &&
286         at=$(sed -ne "/^author /s/.*> //p" head1) &&
287         ct=$(sed -ne "/^committer /s/.*> //p" head1) &&
288         test "$at" != "$ct"
289 '
290
291 # This checks for +0000 because TZ is set to UTC and that should
292 # show up when the current time is used. The date in message is set
293 # by test_tick that uses -0700 timezone; if this feature does not
294 # work, we will see that instead of +0000.
295 test_expect_success 'am --ignore-date' '
296         git checkout first &&
297         test_tick &&
298         git am --ignore-date patch1 &&
299         git cat-file commit HEAD | sed -e "/^$/q" >head1 &&
300         at=$(sed -ne "/^author /s/.*> //p" head1) &&
301         echo "$at" | grep "+0000"
302 '
303
304 test_expect_success 'am into an unborn branch' '
305         rm -fr subdir &&
306         mkdir -p subdir &&
307         git format-patch --numbered-files -o subdir -1 first &&
308         (
309                 cd subdir &&
310                 git init &&
311                 git am 1
312         ) &&
313         result=$(
314                 cd subdir && git rev-parse HEAD^{tree}
315         ) &&
316         test "z$result" = "z$(git rev-parse first^{tree})"
317 '
318
319 test_expect_success 'am newline in subject' '
320         git checkout first &&
321         test_tick &&
322         sed -e "s/second/second \\\n foo/" patch1 > patchnl &&
323         git am < patchnl > output.out 2>&1 &&
324         grep "^Applying: second \\\n foo$" output.out
325 '
326
327 test_expect_success 'am -q is quiet' '
328         git checkout first &&
329         test_tick &&
330         git am -q < patch1 > output.out 2>&1 &&
331         ! test -s output.out
332 '
333
334 test_done