1#!/bin/sh
2
3test_description='am --abort'
4
5. ./test-lib.sh
6
7test_expect_success setup '
8	for i in a b c d e f g
9	do
10		echo $i
11	done >file-1 &&
12	cp file-1 file-2 &&
13	test_tick &&
14	git add file-1 file-2 &&
15	git commit -m initial &&
16	git tag initial &&
17	git format-patch --stdout --root initial >initial.patch &&
18	for i in 2 3 4 5 6
19	do
20		echo $i >>file-1 &&
21		echo $i >otherfile-$i &&
22		git add otherfile-$i &&
23		test_tick &&
24		git commit -a -m $i || return 1
25	done &&
26	git branch changes &&
27	git format-patch --no-numbered initial &&
28	git checkout -b conflicting initial &&
29	echo different >>file-1 &&
30	echo whatever >new-file &&
31	git add file-1 new-file &&
32	git commit -m different &&
33	git checkout -b side initial &&
34	echo local change >file-2-expect
35'
36
37for with3 in '' ' -3'
38do
39	test_expect_success "am$with3 stops at a patch that does not apply" '
40
41		git reset --hard initial &&
42		cp file-2-expect file-2 &&
43
44		test_must_fail git am$with3 000[1245]-*.patch &&
45		git log --pretty=tformat:%s >actual &&
46		for i in 3 2 initial
47		do
48			echo $i
49		done >expect &&
50		test_cmp expect actual
51	'
52
53	test_expect_success "am$with3 --skip continue after failed am$with3" '
54		test_must_fail git am$with3 --skip >output &&
55		test_i18ngrep "^Applying: 6$" output &&
56		test_cmp file-2-expect file-2 &&
57		test ! -f .git/MERGE_RR
58	'
59
60	test_expect_success "am --abort goes back after failed am$with3" '
61		git am --abort &&
62		git rev-parse HEAD >actual &&
63		git rev-parse initial >expect &&
64		test_cmp expect actual &&
65		test_cmp file-2-expect file-2 &&
66		git diff-index --exit-code --cached HEAD &&
67		test ! -f .git/MERGE_RR
68	'
69
70done
71
72test_expect_success 'am -3 --skip removes otherfile-4' '
73	git reset --hard initial &&
74	test_must_fail git am -3 0003-*.patch &&
75	test 3 -eq $(git ls-files -u | wc -l) &&
76	test 4 = "$(cat otherfile-4)" &&
77	git am --skip &&
78	test_cmp_rev initial HEAD &&
79	test -z "$(git ls-files -u)" &&
80	test_path_is_missing otherfile-4
81'
82
83test_expect_success 'am -3 --abort removes otherfile-4' '
84	git reset --hard initial &&
85	test_must_fail git am -3 0003-*.patch &&
86	test 3 -eq $(git ls-files -u | wc -l) &&
87	test 4 = "$(cat otherfile-4)" &&
88	git am --abort &&
89	test_cmp_rev initial HEAD &&
90	test -z "$(git ls-files -u)" &&
91	test_path_is_missing otherfile-4
92'
93
94test_expect_success 'am --abort will keep the local commits intact' '
95	test_must_fail git am 0004-*.patch &&
96	test_commit unrelated &&
97	git rev-parse HEAD >expect &&
98	git am --abort &&
99	git rev-parse HEAD >actual &&
100	test_cmp expect actual
101'
102
103test_expect_success 'am --abort will keep dirty index intact' '
104	git reset --hard initial &&
105	echo dirtyfile >dirtyfile &&
106	cp dirtyfile dirtyfile.expected &&
107	git add dirtyfile &&
108	test_must_fail git am 0001-*.patch &&
109	test_cmp_rev initial HEAD &&
110	test_path_is_file dirtyfile &&
111	test_cmp dirtyfile.expected dirtyfile &&
112	git am --abort &&
113	test_cmp_rev initial HEAD &&
114	test_path_is_file dirtyfile &&
115	test_cmp dirtyfile.expected dirtyfile
116'
117
118test_expect_success 'am -3 stops on conflict on unborn branch' '
119	git checkout -f --orphan orphan &&
120	git reset &&
121	rm -f otherfile-4 &&
122	test_must_fail git am -3 0003-*.patch &&
123	test 2 -eq $(git ls-files -u | wc -l) &&
124	test 4 = "$(cat otherfile-4)"
125'
126
127test_expect_success 'am -3 --skip clears index on unborn branch' '
128	test_path_is_dir .git/rebase-apply &&
129	echo tmpfile >tmpfile &&
130	git add tmpfile &&
131	git am --skip &&
132	test -z "$(git ls-files)" &&
133	test_path_is_missing otherfile-4 &&
134	test_path_is_missing tmpfile
135'
136
137test_expect_success 'am -3 --abort removes otherfile-4 on unborn branch' '
138	git checkout -f --orphan orphan &&
139	git reset &&
140	rm -f otherfile-4 file-1 &&
141	test_must_fail git am -3 0003-*.patch &&
142	test 2 -eq $(git ls-files -u | wc -l) &&
143	test 4 = "$(cat otherfile-4)" &&
144	git am --abort &&
145	test -z "$(git ls-files -u)" &&
146	test_path_is_missing otherfile-4
147'
148
149test_expect_success 'am -3 --abort on unborn branch removes applied commits' '
150	git checkout -f --orphan orphan &&
151	git reset &&
152	rm -f otherfile-4 otherfile-2 file-1 file-2 &&
153	test_must_fail git am -3 initial.patch 0003-*.patch &&
154	test 3 -eq $(git ls-files -u | wc -l) &&
155	test 4 = "$(cat otherfile-4)" &&
156	git am --abort &&
157	test -z "$(git ls-files -u)" &&
158	test_path_is_missing otherfile-4 &&
159	test_path_is_missing file-1 &&
160	test_path_is_missing file-2 &&
161	test 0 -eq $(git log --oneline 2>/dev/null | wc -l) &&
162	test refs/heads/orphan = "$(git symbolic-ref HEAD)"
163'
164
165test_expect_success 'am --abort on unborn branch will keep local commits intact' '
166	git checkout -f --orphan orphan &&
167	git reset &&
168	test_must_fail git am 0004-*.patch &&
169	test_commit unrelated2 &&
170	git rev-parse HEAD >expect &&
171	git am --abort &&
172	git rev-parse HEAD >actual &&
173	test_cmp expect actual
174'
175
176test_expect_success 'am --skip leaves index stat info alone' '
177	git checkout -f --orphan skip-stat-info &&
178	git reset &&
179	test_commit skip-should-be-untouched &&
180	test-tool chmtime =0 skip-should-be-untouched.t &&
181	git update-index --refresh &&
182	git diff-files --exit-code --quiet &&
183	test_must_fail git am 0001-*.patch &&
184	git am --skip &&
185	git diff-files --exit-code --quiet
186'
187
188test_expect_success 'am --abort leaves index stat info alone' '
189	git checkout -f --orphan abort-stat-info &&
190	git reset &&
191	test_commit abort-should-be-untouched &&
192	test-tool chmtime =0 abort-should-be-untouched.t &&
193	git update-index --refresh &&
194	git diff-files --exit-code --quiet &&
195	test_must_fail git am 0001-*.patch &&
196	git am --abort &&
197	git diff-files --exit-code --quiet
198'
199
200test_expect_success 'git am --abort return failed exit status when it fails' '
201	test_when_finished "rm -rf file-2/ && git reset --hard && git am --abort" &&
202	git checkout changes &&
203	git format-patch -1 --stdout conflicting >changes.mbox &&
204	test_must_fail git am --3way changes.mbox &&
205
206	git rm file-2 &&
207	mkdir file-2 &&
208	echo precious >file-2/somefile &&
209	test_must_fail git am --abort &&
210	test_path_is_dir file-2/
211'
212
213test_expect_success 'git am --abort cleans relevant files' '
214	git checkout changes &&
215	git format-patch -1 --stdout conflicting >changes.mbox &&
216	test_must_fail git am --3way changes.mbox &&
217
218	test_path_is_file new-file &&
219	echo further changes >>file-1 &&
220	echo change other file >>file-2 &&
221
222	# Abort, and expect the files touched by am to be reverted
223	git am --abort &&
224
225	test_path_is_missing new-file &&
226
227	# Files not involved in am operation are left modified
228	git diff --name-only changes >actual &&
229	test_write_lines file-2 >expect &&
230	test_cmp expect actual
231'
232
233test_done
234