1#!/bin/sh
2
3test_description='git am running'
4
5. ./test-lib.sh
6
7cat >msg <<EOF
8second
9
10Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, sed diam nonumy
11eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
12voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita
13kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem
14ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
15tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At
16vero 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
25Lorem ipsum dolor sit amet,
26consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
27laoreet dolore magna aliquam erat volutpat.
28
29 git
30 ---
31 +++
32
33Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit
34lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure
35dolor in hendrerit in vulputate velit esse molestie consequat, vel illum
36dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
37dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te
38feugait nulla facilisi.
39EOF
40
41cat >failmail <<EOF
42From foo@example.com Fri May 23 10:43:49 2008
43From: foo@example.com
44To: bar@example.com
45Subject: Re: [RFC/PATCH] git-foo.sh
46Date: Fri, 23 May 2008 05:23:42 +0200
47
48Sometimes we have to find out that there's nothing left.
49
50EOF
51
52cat >pine <<EOF
53From MAILER-DAEMON Fri May 23 10:43:49 2008
54Date: 23 May 2008 05:23:42 +0200
55From: Mail System Internal Data <MAILER-DAEMON@example.com>
56Subject: DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA
57Message-ID: <foo-0001@example.com>
58
59This text is part of the internal format of your mail folder, and is not
60a real message. It is created automatically by the mail system software.
61If deleted, important folder data will be lost, and it will be re-created
62with the data reset to initial values.
63
64EOF
65
66echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected
67
68test_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
98unset test_tick
99test_tick
100
101test_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
111GIT_AUTHOR_NAME="Another Thor"
112GIT_AUTHOR_EMAIL="a.thor@example.com"
113GIT_COMMITTER_NAME="Co M Miter"
114GIT_COMMITTER_EMAIL="c.miter@example.com"
115export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
116
117compare () {
118 test "$(git cat-file commit "$2" | grep "^$1 ")" = \
119 "$(git cat-file commit "$3" | grep "^$1 ")"
120}
121
122test_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
136test_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
147test_expect_success 'am stays in branch' '
148 test "refs/heads/master2" = "$(git symbolic-ref HEAD)"
149'
150
151test_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
159test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
160 test "$(git rev-parse HEAD)" = "$(git rev-parse master2)"
161'
162
163test_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
171test_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
183test_expect_success 'am pauses on conflict' '
184 git checkout lorem2^^ &&
185 test_must_fail git am lorem-move.patch &&
186 test -d .git/rebase-apply
187'
188
189test_expect_success 'am --skip works' '
190 git am --skip &&
191 ! test -d .git/rebase-apply &&
192 test -z "$(git diff lorem2^^ -- file)" &&
193 test goodbye = "$(cat another)"
194'
195
196test_expect_success 'am --resolved works' '
197 git checkout lorem2^^ &&
198 test_must_fail git am lorem-move.patch &&
199 test -d .git/rebase-apply &&
200 echo resolved >>file &&
201 git add file &&
202 git am --resolved &&
203 ! test -d .git/rebase-apply &&
204 test goodbye = "$(cat another)"
205'
206
207test_expect_success 'am takes patches from a Pine mailbox' '
208 git checkout first &&
209 cat pine patch1 | git am &&
210 ! test -d .git/rebase-apply &&
211 test -z "$(git diff master^..HEAD)"
212'
213
214test_expect_success 'am fails on mail without patch' '
215 test_must_fail git am <failmail &&
216 rm -r .git/rebase-apply/
217'
218
219test_expect_success 'am fails on empty patch' '
220 echo "---" >>failmail &&
221 test_must_fail git am <failmail &&
222 git am --skip &&
223 ! test -d .git/rebase-apply
224'
225
226test_expect_success 'am works from stdin in subdirectory' '
227 rm -fr subdir &&
228 git checkout first &&
229 (
230 mkdir -p subdir &&
231 cd subdir &&
232 git am <../patch1
233 ) &&
234 test -z "$(git diff second)"
235'
236
237test_expect_success 'am works from file (relative path given) 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
248test_expect_success 'am works from file (absolute path given) in subdirectory' '
249 rm -fr subdir &&
250 git checkout first &&
251 P=$(pwd) &&
252 (
253 mkdir -p subdir &&
254 cd subdir &&
255 git am "$P/patch1"
256 ) &&
257 test -z "$(git diff second)"
258'
259
260test_expect_success 'am --committer-date-is-author-date' '
261 git checkout first &&
262 test_tick &&
263 git am --committer-date-is-author-date patch1 &&
264 git cat-file commit HEAD | sed -e "/^$/q" >head1 &&
265 at=$(sed -ne "/^author /s/.*> //p" head1) &&
266 ct=$(sed -ne "/^committer /s/.*> //p" head1) &&
267 test "$at" = "$ct"
268'
269
270test_expect_success 'am without --committer-date-is-author-date' '
271 git checkout first &&
272 test_tick &&
273 git am patch1 &&
274 git cat-file commit HEAD | sed -e "/^$/q" >head1 &&
275 at=$(sed -ne "/^author /s/.*> //p" head1) &&
276 ct=$(sed -ne "/^committer /s/.*> //p" head1) &&
277 test "$at" != "$ct"
278'
279
280# This checks for +0000 because TZ is set to UTC and that should
281# show up when the current time is used. The date in message is set
282# by test_tick that uses -0700 timezone; if this feature does not
283# work, we will see that instead of +0000.
284test_expect_success 'am --ignore-date' '
285 git checkout first &&
286 test_tick &&
287 git am --ignore-date patch1 &&
288 git cat-file commit HEAD | sed -e "/^$/q" >head1 &&
289 at=$(sed -ne "/^author /s/.*> //p" head1) &&
290 echo "$at" | grep "+0000"
291'
292
293test_done