Code

Merge branch 'jk/parse-object-cached'
[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 &&
99         {
100                 printf "%255s\\n" ""
101                 echo "X-Fake-Field: Line One" &&
102                 echo "X-Fake-Field: Line Two" &&
103                 echo "X-Fake-Field: Line Three" &&
104                 git format-patch --stdout first | sed -e "1d"
105         } > patch1-ws.eml &&
107         sed -n -e "3,\$p" msg >file &&
108         git add file &&
109         test_tick &&
110         git commit -m third &&
112         git format-patch --stdout first >patch2 &&
114         git checkout -b lorem &&
115         sed -n -e "11,\$p" msg >file &&
116         head -n 9 msg >>file &&
117         test_tick &&
118         git commit -a -m "moved stuff" &&
120         echo goodbye >another &&
121         git add another &&
122         test_tick &&
123         git commit -m "added another file" &&
125         git format-patch --stdout master >lorem-move.patch &&
127         git checkout -b rename &&
128         git mv file renamed &&
129         git commit -m "renamed a file" &&
131         git format-patch -M --stdout lorem >rename.patch &&
133         git reset --soft lorem^ &&
134         git commit -m "renamed a file and added another" &&
136         git format-patch -M --stdout lorem^ >rename-add.patch &&
138         # reset time
139         unset test_tick &&
140         test_tick
143 test_expect_success 'am applies patch correctly' '
144         rm -fr .git/rebase-apply &&
145         git reset --hard &&
146         git checkout first &&
147         test_tick &&
148         git am <patch1 &&
149         ! test -d .git/rebase-apply &&
150         git diff --exit-code second &&
151         test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
152         test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
155 test_expect_success 'am applies patch e-mail not in a mbox' '
156         rm -fr .git/rebase-apply &&
157         git reset --hard &&
158         git checkout first &&
159         git am patch1.eml &&
160         ! test -d .git/rebase-apply &&
161         git diff --exit-code second &&
162         test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
163         test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
166 test_expect_success 'am applies patch e-mail not in a mbox with CRLF' '
167         rm -fr .git/rebase-apply &&
168         git reset --hard &&
169         git checkout first &&
170         git am patch1-crlf.eml &&
171         ! test -d .git/rebase-apply &&
172         git diff --exit-code second &&
173         test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
174         test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
177 test_expect_success 'am applies patch e-mail with preceding whitespace' '
178         rm -fr .git/rebase-apply &&
179         git reset --hard &&
180         git checkout first &&
181         git am patch1-ws.eml &&
182         ! test -d .git/rebase-apply &&
183         git diff --exit-code second &&
184         test "$(git rev-parse second)" = "$(git rev-parse HEAD)" &&
185         test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)"
188 test_expect_success 'setup: new author and committer' '
189         GIT_AUTHOR_NAME="Another Thor" &&
190         GIT_AUTHOR_EMAIL="a.thor@example.com" &&
191         GIT_COMMITTER_NAME="Co M Miter" &&
192         GIT_COMMITTER_EMAIL="c.miter@example.com" &&
193         export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
196 compare () {
197         a=$(git cat-file commit "$2" | grep "^$1 ") &&
198         b=$(git cat-file commit "$3" | grep "^$1 ") &&
199         test "$a" = "$b"
202 test_expect_success 'am changes committer and keeps author' '
203         test_tick &&
204         rm -fr .git/rebase-apply &&
205         git reset --hard &&
206         git checkout first &&
207         git am patch2 &&
208         ! test -d .git/rebase-apply &&
209         test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" &&
210         git diff --exit-code master..HEAD &&
211         git diff --exit-code master^..HEAD^ &&
212         compare author master HEAD &&
213         compare author master^ HEAD^ &&
214         test "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" = \
215              "$(git log -1 --pretty=format:"%cn <%ce>" HEAD)"
218 test_expect_success 'am --signoff adds Signed-off-by: line' '
219         rm -fr .git/rebase-apply &&
220         git reset --hard &&
221         git checkout -b master2 first &&
222         git am --signoff <patch2 &&
223         printf "%s\n" "$signoff" >expected &&
224         echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >>expected &&
225         git cat-file commit HEAD^ | grep "Signed-off-by:" >actual &&
226         test_cmp expected actual &&
227         echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" >expected &&
228         git cat-file commit HEAD | grep "Signed-off-by:" >actual &&
229         test_cmp expected actual
232 test_expect_success 'am stays in branch' '
233         echo refs/heads/master2 >expected &&
234         git symbolic-ref HEAD >actual &&
235         test_cmp expected actual
238 test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
239         git format-patch --stdout HEAD^ >patch3 &&
240         sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," patch3 >patch4 &&
241         rm -fr .git/rebase-apply &&
242         git reset --hard &&
243         git checkout HEAD^ &&
244         git am --signoff patch4 &&
245         git cat-file commit HEAD >actual &&
246         test $(grep -c "^Signed-off-by:" actual) -eq 1
249 test_expect_success 'am without --keep removes Re: and [PATCH] stuff' '
250         git rev-parse HEAD >expected &&
251         git rev-parse master2 >actual &&
252         test_cmp expected actual
255 test_expect_success 'am --keep really keeps the subject' '
256         rm -fr .git/rebase-apply &&
257         git reset --hard &&
258         git checkout HEAD^ &&
259         git am --keep patch4 &&
260         ! test -d .git/rebase-apply &&
261         git cat-file commit HEAD >actual &&
262         grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
265 test_expect_success 'am --keep-non-patch really keeps the non-patch part' '
266         rm -fr .git/rebase-apply &&
267         git reset --hard &&
268         git checkout HEAD^ &&
269         git am --keep-non-patch patch4 &&
270         ! test -d .git/rebase-apply &&
271         git cat-file commit HEAD >actual &&
272         grep "^\[foo\] third" actual
275 test_expect_success 'am -3 falls back to 3-way merge' '
276         rm -fr .git/rebase-apply &&
277         git reset --hard &&
278         git checkout -b lorem2 master2 &&
279         sed -n -e "3,\$p" msg >file &&
280         head -n 9 msg >>file &&
281         git add file &&
282         test_tick &&
283         git commit -m "copied stuff" &&
284         git am -3 lorem-move.patch &&
285         ! test -d .git/rebase-apply &&
286         git diff --exit-code lorem
289 test_expect_success 'am can rename a file' '
290         grep "^rename from" rename.patch &&
291         rm -fr .git/rebase-apply &&
292         git reset --hard &&
293         git checkout lorem^0 &&
294         git am rename.patch &&
295         ! test -d .git/rebase-apply &&
296         git update-index --refresh &&
297         git diff --exit-code rename
300 test_expect_success 'am -3 can rename a file' '
301         grep "^rename from" rename.patch &&
302         rm -fr .git/rebase-apply &&
303         git reset --hard &&
304         git checkout lorem^0 &&
305         git am -3 rename.patch &&
306         ! test -d .git/rebase-apply &&
307         git update-index --refresh &&
308         git diff --exit-code rename
311 test_expect_success 'am -3 can rename a file after falling back to 3-way merge' '
312         grep "^rename from" rename-add.patch &&
313         rm -fr .git/rebase-apply &&
314         git reset --hard &&
315         git checkout lorem^0 &&
316         git am -3 rename-add.patch &&
317         ! test -d .git/rebase-apply &&
318         git update-index --refresh &&
319         git diff --exit-code rename
322 test_expect_success 'am -3 -q is quiet' '
323         rm -fr .git/rebase-apply &&
324         git checkout -f lorem2 &&
325         git reset master2 --hard &&
326         sed -n -e "3,\$p" msg >file &&
327         head -n 9 msg >>file &&
328         git add file &&
329         test_tick &&
330         git commit -m "copied stuff" &&
331         git am -3 -q lorem-move.patch >output.out 2>&1 &&
332         ! test -s output.out
335 test_expect_success 'am pauses on conflict' '
336         rm -fr .git/rebase-apply &&
337         git reset --hard &&
338         git checkout lorem2^^ &&
339         test_must_fail git am lorem-move.patch &&
340         test -d .git/rebase-apply
343 test_expect_success 'am --skip works' '
344         echo goodbye >expected &&
345         git am --skip &&
346         ! test -d .git/rebase-apply &&
347         git diff --exit-code lorem2^^ -- file &&
348         test_cmp expected another
351 test_expect_success 'am --resolved works' '
352         echo goodbye >expected &&
353         rm -fr .git/rebase-apply &&
354         git reset --hard &&
355         git checkout lorem2^^ &&
356         test_must_fail git am lorem-move.patch &&
357         test -d .git/rebase-apply &&
358         echo resolved >>file &&
359         git add file &&
360         git am --resolved &&
361         ! test -d .git/rebase-apply &&
362         test_cmp expected another
365 test_expect_success 'am takes patches from a Pine mailbox' '
366         rm -fr .git/rebase-apply &&
367         git reset --hard &&
368         git checkout first &&
369         cat pine patch1 | git am &&
370         ! test -d .git/rebase-apply &&
371         git diff --exit-code master^..HEAD
374 test_expect_success 'am fails on mail without patch' '
375         rm -fr .git/rebase-apply &&
376         git reset --hard &&
377         test_must_fail git am <failmail &&
378         git am --abort &&
379         ! test -d .git/rebase-apply
382 test_expect_success 'am fails on empty patch' '
383         rm -fr .git/rebase-apply &&
384         git reset --hard &&
385         echo "---" >>failmail &&
386         test_must_fail git am <failmail &&
387         git am --skip &&
388         ! test -d .git/rebase-apply
391 test_expect_success 'am works from stdin in subdirectory' '
392         rm -fr subdir &&
393         rm -fr .git/rebase-apply &&
394         git reset --hard &&
395         git checkout first &&
396         (
397                 mkdir -p subdir &&
398                 cd subdir &&
399                 git am <../patch1
400         ) &&
401         git diff --exit-code second
404 test_expect_success 'am works from file (relative path given) in subdirectory' '
405         rm -fr subdir &&
406         rm -fr .git/rebase-apply &&
407         git reset --hard &&
408         git checkout first &&
409         (
410                 mkdir -p subdir &&
411                 cd subdir &&
412                 git am ../patch1
413         ) &&
414         git diff --exit-code second
417 test_expect_success 'am works from file (absolute path given) in subdirectory' '
418         rm -fr subdir &&
419         rm -fr .git/rebase-apply &&
420         git reset --hard &&
421         git checkout first &&
422         P=$(pwd) &&
423         (
424                 mkdir -p subdir &&
425                 cd subdir &&
426                 git am "$P/patch1"
427         ) &&
428         git diff --exit-code second
431 test_expect_success 'am --committer-date-is-author-date' '
432         rm -fr .git/rebase-apply &&
433         git reset --hard &&
434         git checkout first &&
435         test_tick &&
436         git am --committer-date-is-author-date patch1 &&
437         git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
438         sed -ne "/^author /s/.*> //p" head1 >at &&
439         sed -ne "/^committer /s/.*> //p" head1 >ct &&
440         test_cmp at ct
443 test_expect_success 'am without --committer-date-is-author-date' '
444         rm -fr .git/rebase-apply &&
445         git reset --hard &&
446         git checkout first &&
447         test_tick &&
448         git am patch1 &&
449         git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
450         sed -ne "/^author /s/.*> //p" head1 >at &&
451         sed -ne "/^committer /s/.*> //p" head1 >ct &&
452         ! test_cmp at ct
455 # This checks for +0000 because TZ is set to UTC and that should
456 # show up when the current time is used. The date in message is set
457 # by test_tick that uses -0700 timezone; if this feature does not
458 # work, we will see that instead of +0000.
459 test_expect_success 'am --ignore-date' '
460         rm -fr .git/rebase-apply &&
461         git reset --hard &&
462         git checkout first &&
463         test_tick &&
464         git am --ignore-date patch1 &&
465         git cat-file commit HEAD | sed -e "/^\$/q" >head1 &&
466         sed -ne "/^author /s/.*> //p" head1 >at &&
467         grep "+0000" at
470 test_expect_success 'am into an unborn branch' '
471         git rev-parse first^{tree} >expected &&
472         rm -fr .git/rebase-apply &&
473         git reset --hard &&
474         rm -fr subdir &&
475         mkdir subdir &&
476         git format-patch --numbered-files -o subdir -1 first &&
477         (
478                 cd subdir &&
479                 git init &&
480                 git am 1
481         ) &&
482         (
483                 cd subdir &&
484                 git rev-parse HEAD^{tree} >../actual
485         ) &&
486         test_cmp expected actual
489 test_expect_success 'am newline in subject' '
490         rm -fr .git/rebase-apply &&
491         git reset --hard &&
492         git checkout first &&
493         test_tick &&
494         sed -e "s/second/second \\\n foo/" patch1 >patchnl &&
495         git am <patchnl >output.out 2>&1 &&
496         test_i18ngrep "^Applying: second \\\n foo$" output.out
499 test_expect_success 'am -q is quiet' '
500         rm -fr .git/rebase-apply &&
501         git reset --hard &&
502         git checkout first &&
503         test_tick &&
504         git am -q <patch1 >output.out 2>&1 &&
505         ! test -s output.out
508 test_done