]>
Commit | Line | Data |
---|---|---|
35d2fffd JH |
1 | #!/bin/sh |
2 | ||
3 | test_description='test aborting in-progress merges | |
4 | ||
5 | Set up repo with conflicting and non-conflicting branches: | |
6 | ||
7 | There are three files foo/bar/baz, and the following graph illustrates the | |
8 | content of these files in each commit: | |
9 | ||
10 | # foo/bar/baz --- foo/bar/bazz <-- master | |
11 | # \ | |
12 | # --- foo/barf/bazf <-- conflict_branch | |
13 | # \ | |
14 | # --- foo/bart/baz <-- clean_branch | |
15 | ||
16 | Next, test git merge --abort with the following variables: | |
17 | - before/after successful merge (should fail when not in merge context) | |
18 | - with/without conflicts | |
19 | - clean/dirty index before merge | |
20 | - clean/dirty worktree before merge | |
21 | - dirty index before merge matches contents on remote branch | |
22 | - changed/unchanged worktree after merge | |
23 | - changed/unchanged index after merge | |
24 | ' | |
25 | . ./test-lib.sh | |
26 | ||
27 | test_expect_success 'setup' ' | |
28 | # Create the above repo | |
29 | echo foo > foo && | |
30 | echo bar > bar && | |
31 | echo baz > baz && | |
32 | git add foo bar baz && | |
33 | git commit -m initial && | |
34 | echo bazz > baz && | |
35 | git commit -a -m "second" && | |
36 | git checkout -b conflict_branch HEAD^ && | |
37 | echo barf > bar && | |
38 | echo bazf > baz && | |
39 | git commit -a -m "conflict" && | |
40 | git checkout -b clean_branch HEAD^ && | |
41 | echo bart > bar && | |
42 | git commit -a -m "clean" && | |
43 | git checkout master | |
44 | ' | |
45 | ||
46 | pre_merge_head="$(git rev-parse HEAD)" | |
47 | ||
48 | test_expect_success 'fails without MERGE_HEAD (unstarted merge)' ' | |
bacec478 ÆAB |
49 | test_must_fail git merge --abort 2>output |
50 | ' | |
51 | ||
52 | test_expect_success C_LOCALE_OUTPUT 'fails without MERGE_HEAD (unstarted merge): fatal output' ' | |
53 | grep -q MERGE_HEAD output | |
54 | ' | |
55 | ||
56 | test_expect_success 'fails without MERGE_HEAD (unstarted merge): .git/MERGE_HEAD sanity' ' | |
35d2fffd JH |
57 | test ! -f .git/MERGE_HEAD && |
58 | test "$pre_merge_head" = "$(git rev-parse HEAD)" | |
59 | ' | |
60 | ||
61 | test_expect_success 'fails without MERGE_HEAD (completed merge)' ' | |
62 | git merge clean_branch && | |
63 | test ! -f .git/MERGE_HEAD && | |
64 | # Merge successfully completed | |
65 | post_merge_head="$(git rev-parse HEAD)" && | |
bacec478 ÆAB |
66 | test_must_fail git merge --abort 2>output |
67 | ' | |
68 | ||
69 | test_expect_success C_LOCALE_OUTPUT 'fails without MERGE_HEAD (completed merge): output' ' | |
70 | grep -q MERGE_HEAD output | |
71 | ' | |
72 | ||
73 | test_expect_success 'fails without MERGE_HEAD (completed merge): .git/MERGE_HEAD sanity' ' | |
35d2fffd JH |
74 | test ! -f .git/MERGE_HEAD && |
75 | test "$post_merge_head" = "$(git rev-parse HEAD)" | |
76 | ' | |
77 | ||
78 | test_expect_success 'Forget previous merge' ' | |
79 | git reset --hard "$pre_merge_head" | |
80 | ' | |
81 | ||
82 | test_expect_success 'Abort after --no-commit' ' | |
83 | # Redo merge, but stop before creating merge commit | |
84 | git merge --no-commit clean_branch && | |
85 | test -f .git/MERGE_HEAD && | |
86 | # Abort non-conflicting merge | |
87 | git merge --abort && | |
88 | test ! -f .git/MERGE_HEAD && | |
89 | test "$pre_merge_head" = "$(git rev-parse HEAD)" && | |
90 | test -z "$(git diff)" && | |
91 | test -z "$(git diff --staged)" | |
92 | ' | |
93 | ||
94 | test_expect_success 'Abort after conflicts' ' | |
95 | # Create conflicting merge | |
96 | test_must_fail git merge conflict_branch && | |
97 | test -f .git/MERGE_HEAD && | |
98 | # Abort conflicting merge | |
99 | git merge --abort && | |
100 | test ! -f .git/MERGE_HEAD && | |
101 | test "$pre_merge_head" = "$(git rev-parse HEAD)" && | |
102 | test -z "$(git diff)" && | |
103 | test -z "$(git diff --staged)" | |
104 | ' | |
105 | ||
106 | test_expect_success 'Clean merge with dirty index fails' ' | |
107 | echo xyzzy >> foo && | |
108 | git add foo && | |
109 | git diff --staged > expect && | |
110 | test_must_fail git merge clean_branch && | |
111 | test ! -f .git/MERGE_HEAD && | |
112 | test "$pre_merge_head" = "$(git rev-parse HEAD)" && | |
113 | test -z "$(git diff)" && | |
114 | git diff --staged > actual && | |
115 | test_cmp expect actual | |
116 | ' | |
117 | ||
118 | test_expect_success 'Conflicting merge with dirty index fails' ' | |
119 | test_must_fail git merge conflict_branch && | |
120 | test ! -f .git/MERGE_HEAD && | |
121 | test "$pre_merge_head" = "$(git rev-parse HEAD)" && | |
122 | test -z "$(git diff)" && | |
123 | git diff --staged > actual && | |
124 | test_cmp expect actual | |
125 | ' | |
126 | ||
127 | test_expect_success 'Reset index (but preserve worktree changes)' ' | |
128 | git reset "$pre_merge_head" && | |
129 | git diff > actual && | |
130 | test_cmp expect actual | |
131 | ' | |
132 | ||
133 | test_expect_success 'Abort clean merge with non-conflicting dirty worktree' ' | |
134 | git merge --no-commit clean_branch && | |
135 | test -f .git/MERGE_HEAD && | |
136 | # Abort merge | |
137 | git merge --abort && | |
138 | test ! -f .git/MERGE_HEAD && | |
139 | test "$pre_merge_head" = "$(git rev-parse HEAD)" && | |
140 | test -z "$(git diff --staged)" && | |
141 | git diff > actual && | |
142 | test_cmp expect actual | |
143 | ' | |
144 | ||
145 | test_expect_success 'Abort conflicting merge with non-conflicting dirty worktree' ' | |
146 | test_must_fail git merge conflict_branch && | |
147 | test -f .git/MERGE_HEAD && | |
148 | # Abort merge | |
149 | git merge --abort && | |
150 | test ! -f .git/MERGE_HEAD && | |
151 | test "$pre_merge_head" = "$(git rev-parse HEAD)" && | |
152 | test -z "$(git diff --staged)" && | |
153 | git diff > actual && | |
154 | test_cmp expect actual | |
155 | ' | |
156 | ||
157 | test_expect_success 'Reset worktree changes' ' | |
158 | git reset --hard "$pre_merge_head" | |
159 | ' | |
160 | ||
161 | test_expect_success 'Fail clean merge with conflicting dirty worktree' ' | |
162 | echo xyzzy >> bar && | |
163 | git diff > expect && | |
164 | test_must_fail git merge --no-commit clean_branch && | |
165 | test ! -f .git/MERGE_HEAD && | |
166 | test "$pre_merge_head" = "$(git rev-parse HEAD)" && | |
167 | test -z "$(git diff --staged)" && | |
168 | git diff > actual && | |
169 | test_cmp expect actual | |
170 | ' | |
171 | ||
172 | test_expect_success 'Fail conflicting merge with conflicting dirty worktree' ' | |
173 | test_must_fail git merge conflict_branch && | |
174 | test ! -f .git/MERGE_HEAD && | |
175 | test "$pre_merge_head" = "$(git rev-parse HEAD)" && | |
176 | test -z "$(git diff --staged)" && | |
177 | git diff > actual && | |
178 | test_cmp expect actual | |
179 | ' | |
180 | ||
181 | test_expect_success 'Reset worktree changes' ' | |
182 | git reset --hard "$pre_merge_head" | |
183 | ' | |
184 | ||
185 | test_expect_success 'Fail clean merge with matching dirty worktree' ' | |
186 | echo bart > bar && | |
187 | git diff > expect && | |
188 | test_must_fail git merge --no-commit clean_branch && | |
189 | test ! -f .git/MERGE_HEAD && | |
190 | test "$pre_merge_head" = "$(git rev-parse HEAD)" && | |
191 | test -z "$(git diff --staged)" && | |
192 | git diff > actual && | |
193 | test_cmp expect actual | |
194 | ' | |
195 | ||
196 | test_expect_success 'Abort clean merge with matching dirty index' ' | |
197 | git add bar && | |
198 | git diff --staged > expect && | |
199 | git merge --no-commit clean_branch && | |
200 | test -f .git/MERGE_HEAD && | |
201 | ### When aborting the merge, git will discard all staged changes, | |
202 | ### including those that were staged pre-merge. In other words, | |
203 | ### --abort will LOSE any staged changes (the staged changes that | |
204 | ### are lost must match the merge result, or the merge would not | |
205 | ### have been allowed to start). Change expectations accordingly: | |
206 | rm expect && | |
207 | touch expect && | |
208 | # Abort merge | |
209 | git merge --abort && | |
210 | test ! -f .git/MERGE_HEAD && | |
211 | test "$pre_merge_head" = "$(git rev-parse HEAD)" && | |
212 | git diff --staged > actual && | |
213 | test_cmp expect actual && | |
214 | test -z "$(git diff)" | |
215 | ' | |
216 | ||
217 | test_expect_success 'Reset worktree changes' ' | |
218 | git reset --hard "$pre_merge_head" | |
219 | ' | |
220 | ||
221 | test_expect_success 'Fail conflicting merge with matching dirty worktree' ' | |
222 | echo barf > bar && | |
223 | git diff > expect && | |
224 | test_must_fail git merge conflict_branch && | |
225 | test ! -f .git/MERGE_HEAD && | |
226 | test "$pre_merge_head" = "$(git rev-parse HEAD)" && | |
227 | test -z "$(git diff --staged)" && | |
228 | git diff > actual && | |
229 | test_cmp expect actual | |
230 | ' | |
231 | ||
232 | test_expect_success 'Abort conflicting merge with matching dirty index' ' | |
233 | git add bar && | |
234 | git diff --staged > expect && | |
235 | test_must_fail git merge conflict_branch && | |
236 | test -f .git/MERGE_HEAD && | |
237 | ### When aborting the merge, git will discard all staged changes, | |
238 | ### including those that were staged pre-merge. In other words, | |
239 | ### --abort will LOSE any staged changes (the staged changes that | |
240 | ### are lost must match the merge result, or the merge would not | |
241 | ### have been allowed to start). Change expectations accordingly: | |
242 | rm expect && | |
243 | touch expect && | |
244 | # Abort merge | |
245 | git merge --abort && | |
246 | test ! -f .git/MERGE_HEAD && | |
247 | test "$pre_merge_head" = "$(git rev-parse HEAD)" && | |
248 | git diff --staged > actual && | |
249 | test_cmp expect actual && | |
250 | test -z "$(git diff)" | |
251 | ' | |
252 | ||
253 | test_expect_success 'Reset worktree changes' ' | |
254 | git reset --hard "$pre_merge_head" | |
255 | ' | |
256 | ||
257 | test_expect_success 'Abort merge with pre- and post-merge worktree changes' ' | |
258 | # Pre-merge worktree changes | |
259 | echo xyzzy > foo && | |
260 | echo barf > bar && | |
261 | git add bar && | |
262 | git diff > expect && | |
263 | git diff --staged > expect-staged && | |
264 | # Perform merge | |
265 | test_must_fail git merge conflict_branch && | |
266 | test -f .git/MERGE_HEAD && | |
267 | # Post-merge worktree changes | |
268 | echo yzxxz > foo && | |
269 | echo blech > baz && | |
270 | ### When aborting the merge, git will discard staged changes (bar) | |
271 | ### and unmerged changes (baz). Other changes that are neither | |
272 | ### staged nor marked as unmerged (foo), will be preserved. For | |
273 | ### these changed, git cannot tell pre-merge changes apart from | |
274 | ### post-merge changes, so the post-merge changes will be | |
275 | ### preserved. Change expectations accordingly: | |
276 | git diff -- foo > expect && | |
277 | rm expect-staged && | |
278 | touch expect-staged && | |
279 | # Abort merge | |
280 | git merge --abort && | |
281 | test ! -f .git/MERGE_HEAD && | |
282 | test "$pre_merge_head" = "$(git rev-parse HEAD)" && | |
283 | git diff > actual && | |
284 | test_cmp expect actual && | |
285 | git diff --staged > actual-staged && | |
286 | test_cmp expect-staged actual-staged | |
287 | ' | |
288 | ||
289 | test_expect_success 'Reset worktree changes' ' | |
290 | git reset --hard "$pre_merge_head" | |
291 | ' | |
292 | ||
293 | test_expect_success 'Abort merge with pre- and post-merge index changes' ' | |
294 | # Pre-merge worktree changes | |
295 | echo xyzzy > foo && | |
296 | echo barf > bar && | |
297 | git add bar && | |
298 | git diff > expect && | |
299 | git diff --staged > expect-staged && | |
300 | # Perform merge | |
301 | test_must_fail git merge conflict_branch && | |
302 | test -f .git/MERGE_HEAD && | |
303 | # Post-merge worktree changes | |
304 | echo yzxxz > foo && | |
305 | echo blech > baz && | |
306 | git add foo bar && | |
307 | ### When aborting the merge, git will discard all staged changes | |
308 | ### (foo, bar and baz), and no changes will be preserved. Whether | |
309 | ### the changes were staged pre- or post-merge does not matter | |
310 | ### (except for not preventing starting the merge). | |
311 | ### Change expectations accordingly: | |
312 | rm expect expect-staged && | |
313 | touch expect && | |
314 | touch expect-staged && | |
315 | # Abort merge | |
316 | git merge --abort && | |
317 | test ! -f .git/MERGE_HEAD && | |
318 | test "$pre_merge_head" = "$(git rev-parse HEAD)" && | |
319 | git diff > actual && | |
320 | test_cmp expect actual && | |
321 | git diff --staged > actual-staged && | |
322 | test_cmp expect-staged actual-staged | |
323 | ' | |
324 | ||
325 | test_done |