diff -c/--cc: do not mistake "resolved as deletion" as "use working tree"
[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         {
81                 echo "X-Fake-Field: Line One" &&
82                 echo "X-Fake-Field: Line Two" &&
83                 echo "X-Fake-Field: Line Three" &&
84                 git format-patch --stdout first | sed -e "1d"
85         } > patch1.eml &&
86         {
87                 echo "X-Fake-Field: Line One" &&
88                 echo "X-Fake-Field: Line Two" &&
89                 echo "X-Fake-Field: Line Three" &&
90                 git format-patch --stdout first | sed -e "1d"
91         } | append_cr >patch1-crlf.eml &&
92         sed -n -e "3,\$p" msg >file &&
93         git add file &&
94         test_tick &&
95         git commit -m third &&
96         git format-patch --stdout first >patch2 &&
97         git checkout -b lorem &&
98         sed -n -e "11,\$p" msg >file &&
99         head -n 9 msg >>file &&
100         test_tick &&
101         git commit -a -m "moved stuff" &&
102         echo goodbye >another &&
103         git add another &&
104         test_tick &&
105         git commit -m "added another file" &&
106         git format-patch --stdout master >lorem-move.patch
107 '
108
109 # reset time
110 unset test_tick
111 test_tick
112
113 test_expect_success 'am applies patch correctly' '
114         git checkout first &&
115         test_tick &&
116         git am <patch1 &&
117         ! test -d .git/rebase-apply &&
118         test -z "$(git diff second)" &&
119         test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
120         test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
121 '
122
123 test_expect_success 'am applies patch e-mail not in a mbox' '
124         git checkout first &&
125         git am patch1.eml &&
126         ! test -d .git/rebase-apply &&
127         test -z "$(git diff second)" &&
128         test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
129         test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
130 '
131
132 test_expect_success 'am applies patch e-mail not in a mbox with CRLF' '
133         git checkout first &&
134         git am patch1-crlf.eml &&
135         ! test -d .git/rebase-apply &&
136         test -z "$(git diff second)" &&
137         test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
138         test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
139 '
140
141 GIT_AUTHOR_NAME="Another Thor"
142 GIT_AUTHOR_EMAIL="a.thor@example.com"
143 GIT_COMMITTER_NAME="Co M Miter"
144 GIT_COMMITTER_EMAIL="c.miter@example.com"
145 export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
146
147 compare () {
148         test "$(git cat-file commit "$2" | grep "^$1 ")" = \
149              "$(git cat-file commit "$3" | grep "^$1 ")"
150 }
151
152 test_expect_success 'am changes committer and keeps author' '
153         test_tick &&
154         git checkout first &&
155         git am patch2 &&
156         ! test -d .git/rebase-apply &&
157         test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" &&
158         test -z "$(git diff master..HEAD)" &&
159         test -z "$(git diff master^..HEAD^)" &&
160         compare author master HEAD &&
161         compare author master^ HEAD^ &&
162         test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
163              "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
164 '
165
166 test_expect_success 'am --signoff adds Signed-off-by: line' '
167         git checkout -b master2 first &&
168         git am --signoff <patch2 &&
169         echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >>expected &&
170         git cat-file commit HEAD^ | grep "Signed-off-by:" >actual &&
171         test_cmp actual expected &&
172         echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected &&
173         git cat-file commit HEAD | grep "Signed-off-by:" >actual &&
174         test_cmp actual expected
175 '
176
177 test_expect_success 'am stays in branch' '
178         test "refs/heads/master2" = "$(git symbolic-ref HEAD)"
179 '
180
181 test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
182         git format-patch --stdout HEAD^ >patch3 &&
183         sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2," patch3 >patch4
184         git checkout HEAD^ &&
185         git am --signoff patch4 &&
186         test "$(git cat-file commit HEAD | grep -c "^Signed-off-by:")" -eq 1
187 '
188
189 test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
190         test "$(git rev-parse HEAD)" = "$(git rev-parse master2)"
191 '
192
193 test_expect_success 'am --keep really keeps the subject' '
194         git checkout HEAD^ &&
195         git am --keep patch4 &&
196         ! test -d .git/rebase-apply &&
197         git cat-file commit HEAD |
198                 fgrep "Re: Re: Re: [PATCH 1/5 v2] third"
199 '
200
201 test_expect_success 'am -3 falls back to 3-way merge' '
202         git checkout -b lorem2 master2 &&
203         sed -n -e "3,\$p" msg >file &&
204         head -n 9 msg >>file &&
205         git add file &&
206         test_tick &&
207         git commit -m "copied stuff" &&
208         git am -3 lorem-move.patch &&
209         ! test -d .git/rebase-apply &&
210         test -z "$(git diff lorem)"
211 '
212
213 test_expect_success 'am -3 -q is quiet' '
214         git reset master2 --hard &&
215         sed -n -e "3,\$p" msg >file &&
216         head -n 9 msg >>file &&
217         git add file &&
218         test_tick &&
219         git commit -m "copied stuff" &&
220         git am -3 -q lorem-move.patch > output.out 2>&1 &&
221         ! test -s output.out
222 '
223
224 test_expect_success 'am pauses on conflict' '
225         git checkout lorem2^^ &&
226         test_must_fail git am lorem-move.patch &&
227         test -d .git/rebase-apply
228 '
229
230 test_expect_success 'am --skip works' '
231         git am --skip &&
232         ! test -d .git/rebase-apply &&
233         test -z "$(git diff lorem2^^ -- file)" &&
234         test goodbye = "$(cat another)"
235 '
236
237 test_expect_success 'am --resolved works' '
238         git checkout lorem2^^ &&
239         test_must_fail git am lorem-move.patch &&
240         test -d .git/rebase-apply &&
241         echo resolved >>file &&
242         git add file &&
243         git am --resolved &&
244         ! test -d .git/rebase-apply &&
245         test goodbye = "$(cat another)"
246 '
247
248 test_expect_success 'am takes patches from a Pine mailbox' '
249         git checkout first &&
250         cat pine patch1 | git am &&
251         ! test -d .git/rebase-apply &&
252         test -z "$(git diff master^..HEAD)"
253 '
254
255 test_expect_success 'am fails on mail without patch' '
256         test_must_fail git am <failmail &&
257         rm -r .git/rebase-apply/
258 '
259
260 test_expect_success 'am fails on empty patch' '
261         echo "---" >>failmail &&
262         test_must_fail git am <failmail &&
263         git am --skip &&
264         ! test -d .git/rebase-apply
265 '
266
267 test_expect_success 'am works from stdin in subdirectory' '
268         rm -fr subdir &&
269         git checkout first &&
270         (
271                 mkdir -p subdir &&
272                 cd subdir &&
273                 git am <../patch1
274         ) &&
275         test -z "$(git diff second)"
276 '
277
278 test_expect_success 'am works from file (relative path given) in subdirectory' '
279         rm -fr subdir &&
280         git checkout first &&
281         (
282                 mkdir -p subdir &&
283                 cd subdir &&
284                 git am ../patch1
285         ) &&
286         test -z "$(git diff second)"
287 '
288
289 test_expect_success 'am works from file (absolute path given) in subdirectory' '
290         rm -fr subdir &&
291         git checkout first &&
292         P=$(pwd) &&
293         (
294                 mkdir -p subdir &&
295                 cd subdir &&
296                 git am "$P/patch1"
297         ) &&
298         test -z "$(git diff second)"
299 '
300
301 test_expect_success 'am --committer-date-is-author-date' '
302         git checkout first &&
303         test_tick &&
304         git am --committer-date-is-author-date patch1 &&
305         git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
306         at=$(sed -ne "/^author /s/.*> //p" head1) &&
307         ct=$(sed -ne "/^committer /s/.*> //p" head1) &&
308         test "$at" = "$ct"
309 '
310
311 test_expect_success 'am without --committer-date-is-author-date' '
312         git checkout first &&
313         test_tick &&
314         git am patch1 &&
315         git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
316         at=$(sed -ne "/^author /s/.*> //p" head1) &&
317         ct=$(sed -ne "/^committer /s/.*> //p" head1) &&
318         test "$at" != "$ct"
319 '
320
321 # This checks for +0000 because TZ is set to UTC and that should
322 # show up when the current time is used. The date in message is set
323 # by test_tick that uses -0700 timezone; if this feature does not
324 # work, we will see that instead of +0000.
325 test_expect_success 'am --ignore-date' '
326         git checkout first &&
327         test_tick &&
328         git am --ignore-date patch1 &&
329         git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
330         at=$(sed -ne "/^author /s/.*> //p" head1) &&
331         echo "$at" | grep "+0000"
332 '
333
334 test_expect_success 'am into an unborn branch' '
335         rm -fr subdir &&
336         mkdir -p subdir &&
337         git format-patch --numbered-files -o subdir -1 first &&
338         (
339                 cd subdir &&
340                 git init &&
341                 git am 1
342         ) &&
343         result=$(
344                 cd subdir && git rev-parse HEAD^{tree}
345         ) &&
346         test "z$result" = "z$(git rev-parse first^{tree})"
347 '
348
349 test_expect_success 'am newline in subject' '
350         git checkout first &&
351         test_tick &&
352         sed -e "s/second/second \\\n foo/" patch1 > patchnl &&
353         git am < patchnl > output.out 2>&1 &&
354         grep "^Applying: second \\\n foo$" output.out
355 '
356
357 test_expect_success 'am -q is quiet' '
358         git checkout first &&
359         test_tick &&
360         git am -q < patch1 > output.out 2>&1 &&
361         ! test -s output.out
362 '
363
364 test_done