]> git.ipfire.org Git - thirdparty/git.git/blob - t/t3507-cherry-pick-conflict.sh
Merge branch 'jk/fetch-reachability-error-fix'
[thirdparty/git.git] / t / t3507-cherry-pick-conflict.sh
1 #!/bin/sh
2
3 test_description='test cherry-pick and revert with conflicts
4
5 -
6 + picked: rewrites foo to c
7 + base: rewrites foo to b
8 + initial: writes foo as a, unrelated as unrelated
9
10 '
11
12 . ./test-lib.sh
13
14 pristine_detach () {
15 git checkout -f "$1^0" &&
16 git read-tree -u --reset HEAD &&
17 git clean -d -f -f -q -x
18 }
19
20 test_expect_success setup '
21
22 echo unrelated >unrelated &&
23 git add unrelated &&
24 test_commit initial foo a &&
25 test_commit base foo b &&
26 test_commit picked foo c &&
27 test_commit --signoff picked-signed foo d &&
28 git checkout -b topic initial &&
29 test_commit redundant-pick foo c redundant &&
30 git commit --allow-empty --allow-empty-message &&
31 git tag empty &&
32 git checkout master &&
33 git config advice.detachedhead false
34
35 '
36
37 test_expect_success 'failed cherry-pick does not advance HEAD' '
38 pristine_detach initial &&
39
40 head=$(git rev-parse HEAD) &&
41 test_must_fail git cherry-pick picked &&
42 newhead=$(git rev-parse HEAD) &&
43
44 test "$head" = "$newhead"
45 '
46
47 test_expect_success 'advice from failed cherry-pick' "
48 pristine_detach initial &&
49
50 picked=\$(git rev-parse --short picked) &&
51 cat <<-EOF >expected &&
52 error: could not apply \$picked... picked
53 hint: after resolving the conflicts, mark the corrected paths
54 hint: with 'git add <paths>' or 'git rm <paths>'
55 hint: and commit the result with 'git commit'
56 EOF
57 test_must_fail git cherry-pick picked 2>actual &&
58
59 test_i18ncmp expected actual
60 "
61
62 test_expect_success 'advice from failed cherry-pick --no-commit' "
63 pristine_detach initial &&
64
65 picked=\$(git rev-parse --short picked) &&
66 cat <<-EOF >expected &&
67 error: could not apply \$picked... picked
68 hint: after resolving the conflicts, mark the corrected paths
69 hint: with 'git add <paths>' or 'git rm <paths>'
70 EOF
71 test_must_fail git cherry-pick --no-commit picked 2>actual &&
72
73 test_i18ncmp expected actual
74 "
75
76 test_expect_success 'failed cherry-pick sets CHERRY_PICK_HEAD' '
77 pristine_detach initial &&
78 test_must_fail git cherry-pick picked &&
79 test_cmp_rev picked CHERRY_PICK_HEAD
80 '
81
82 test_expect_success 'successful cherry-pick does not set CHERRY_PICK_HEAD' '
83 pristine_detach initial &&
84 git cherry-pick base &&
85 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
86 '
87
88 test_expect_success 'cherry-pick --no-commit does not set CHERRY_PICK_HEAD' '
89 pristine_detach initial &&
90 git cherry-pick --no-commit base &&
91 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
92 '
93
94 test_expect_success 'cherry-pick w/dirty tree does not set CHERRY_PICK_HEAD' '
95 pristine_detach initial &&
96 echo foo > foo &&
97 test_must_fail git cherry-pick base &&
98 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
99 '
100
101 test_expect_success \
102 'cherry-pick --strategy=resolve w/dirty tree does not set CHERRY_PICK_HEAD' '
103 pristine_detach initial &&
104 echo foo > foo &&
105 test_must_fail git cherry-pick --strategy=resolve base &&
106 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
107 '
108
109 test_expect_success 'GIT_CHERRY_PICK_HELP suppresses CHERRY_PICK_HEAD' '
110 pristine_detach initial &&
111 (
112 GIT_CHERRY_PICK_HELP="and then do something else" &&
113 export GIT_CHERRY_PICK_HELP &&
114 test_must_fail git cherry-pick picked
115 ) &&
116 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
117 '
118
119 test_expect_success 'git reset clears CHERRY_PICK_HEAD' '
120 pristine_detach initial &&
121
122 test_must_fail git cherry-pick picked &&
123 git reset &&
124
125 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
126 '
127
128 test_expect_success 'failed commit does not clear CHERRY_PICK_HEAD' '
129 pristine_detach initial &&
130
131 test_must_fail git cherry-pick picked &&
132 test_must_fail git commit &&
133
134 test_cmp_rev picked CHERRY_PICK_HEAD
135 '
136
137 test_expect_success 'cancelled commit does not clear CHERRY_PICK_HEAD' '
138 pristine_detach initial &&
139
140 test_must_fail git cherry-pick picked &&
141 echo resolved >foo &&
142 git add foo &&
143 git update-index --refresh -q &&
144 test_must_fail git diff-index --exit-code HEAD &&
145 (
146 GIT_EDITOR=false &&
147 export GIT_EDITOR &&
148 test_must_fail git commit
149 ) &&
150
151 test_cmp_rev picked CHERRY_PICK_HEAD
152 '
153
154 test_expect_success 'successful commit clears CHERRY_PICK_HEAD' '
155 pristine_detach initial &&
156
157 test_must_fail git cherry-pick picked &&
158 echo resolved >foo &&
159 git add foo &&
160 git commit &&
161
162 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
163 '
164
165 test_expect_success 'failed cherry-pick produces dirty index' '
166 pristine_detach initial &&
167
168 test_must_fail git cherry-pick picked &&
169
170 test_must_fail git update-index --refresh -q &&
171 test_must_fail git diff-index --exit-code HEAD
172 '
173
174 test_expect_success 'failed cherry-pick registers participants in index' '
175 pristine_detach initial &&
176 {
177 git checkout base -- foo &&
178 git ls-files --stage foo &&
179 git checkout initial -- foo &&
180 git ls-files --stage foo &&
181 git checkout picked -- foo &&
182 git ls-files --stage foo
183 } > stages &&
184 sed "
185 1 s/ 0 / 1 /
186 2 s/ 0 / 2 /
187 3 s/ 0 / 3 /
188 " < stages > expected &&
189 git read-tree -u --reset HEAD &&
190
191 test_must_fail git cherry-pick picked &&
192 git ls-files --stage --unmerged > actual &&
193
194 test_cmp expected actual
195 '
196
197 test_expect_success 'failed cherry-pick describes conflict in work tree' '
198 pristine_detach initial &&
199 cat <<-EOF > expected &&
200 <<<<<<< HEAD
201 a
202 =======
203 c
204 >>>>>>> objid picked
205 EOF
206
207 test_must_fail git cherry-pick picked &&
208
209 sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
210 test_cmp expected actual
211 '
212
213 test_expect_success 'diff3 -m style' '
214 pristine_detach initial &&
215 git config merge.conflictstyle diff3 &&
216 cat <<-EOF > expected &&
217 <<<<<<< HEAD
218 a
219 ||||||| parent of objid picked
220 b
221 =======
222 c
223 >>>>>>> objid picked
224 EOF
225
226 test_must_fail git cherry-pick picked &&
227
228 sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
229 test_cmp expected actual
230 '
231
232 test_expect_success 'revert also handles conflicts sanely' '
233 git config --unset merge.conflictstyle &&
234 pristine_detach initial &&
235 cat <<-EOF > expected &&
236 <<<<<<< HEAD
237 a
238 =======
239 b
240 >>>>>>> parent of objid picked
241 EOF
242 {
243 git checkout picked -- foo &&
244 git ls-files --stage foo &&
245 git checkout initial -- foo &&
246 git ls-files --stage foo &&
247 git checkout base -- foo &&
248 git ls-files --stage foo
249 } > stages &&
250 sed "
251 1 s/ 0 / 1 /
252 2 s/ 0 / 2 /
253 3 s/ 0 / 3 /
254 " < stages > expected-stages &&
255 git read-tree -u --reset HEAD &&
256
257 head=$(git rev-parse HEAD) &&
258 test_must_fail git revert picked &&
259 newhead=$(git rev-parse HEAD) &&
260 git ls-files --stage --unmerged > actual-stages &&
261
262 test "$head" = "$newhead" &&
263 test_must_fail git update-index --refresh -q &&
264 test_must_fail git diff-index --exit-code HEAD &&
265 test_cmp expected-stages actual-stages &&
266 sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
267 test_cmp expected actual
268 '
269
270 test_expect_success 'failed revert sets REVERT_HEAD' '
271 pristine_detach initial &&
272 test_must_fail git revert picked &&
273 test_cmp_rev picked REVERT_HEAD
274 '
275
276 test_expect_success 'successful revert does not set REVERT_HEAD' '
277 pristine_detach base &&
278 git revert base &&
279 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
280 test_must_fail git rev-parse --verify REVERT_HEAD
281 '
282
283 test_expect_success 'revert --no-commit sets REVERT_HEAD' '
284 pristine_detach base &&
285 git revert --no-commit base &&
286 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
287 test_cmp_rev base REVERT_HEAD
288 '
289
290 test_expect_success 'revert w/dirty tree does not set REVERT_HEAD' '
291 pristine_detach base &&
292 echo foo > foo &&
293 test_must_fail git revert base &&
294 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
295 test_must_fail git rev-parse --verify REVERT_HEAD
296 '
297
298 test_expect_success 'GIT_CHERRY_PICK_HELP does not suppress REVERT_HEAD' '
299 pristine_detach initial &&
300 (
301 GIT_CHERRY_PICK_HELP="and then do something else" &&
302 GIT_REVERT_HELP="and then do something else, again" &&
303 export GIT_CHERRY_PICK_HELP GIT_REVERT_HELP &&
304 test_must_fail git revert picked
305 ) &&
306 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
307 test_cmp_rev picked REVERT_HEAD
308 '
309
310 test_expect_success 'git reset clears REVERT_HEAD' '
311 pristine_detach initial &&
312 test_must_fail git revert picked &&
313 git reset &&
314 test_must_fail git rev-parse --verify REVERT_HEAD
315 '
316
317 test_expect_success 'failed commit does not clear REVERT_HEAD' '
318 pristine_detach initial &&
319 test_must_fail git revert picked &&
320 test_must_fail git commit &&
321 test_cmp_rev picked REVERT_HEAD
322 '
323
324 test_expect_success 'revert conflict, diff3 -m style' '
325 pristine_detach initial &&
326 git config merge.conflictstyle diff3 &&
327 cat <<-EOF > expected &&
328 <<<<<<< HEAD
329 a
330 ||||||| objid picked
331 c
332 =======
333 b
334 >>>>>>> parent of objid picked
335 EOF
336
337 test_must_fail git revert picked &&
338
339 sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
340 test_cmp expected actual
341 '
342
343 test_expect_success 'failed cherry-pick does not forget -s' '
344 pristine_detach initial &&
345 test_must_fail git cherry-pick -s picked &&
346 test_i18ngrep -e "Signed-off-by" .git/MERGE_MSG
347 '
348
349 test_expect_success 'commit after failed cherry-pick does not add duplicated -s' '
350 pristine_detach initial &&
351 test_must_fail git cherry-pick -s picked-signed &&
352 git commit -a -s &&
353 test $(git show -s |grep -c "Signed-off-by") = 1
354 '
355
356 test_expect_success 'commit after failed cherry-pick adds -s at the right place' '
357 pristine_detach initial &&
358 test_must_fail git cherry-pick picked &&
359
360 git commit -a -s &&
361
362 # Do S-o-b and Conflicts appear in the right order?
363 cat <<-\EOF >expect &&
364 Signed-off-by: C O Mitter <committer@example.com>
365 # Conflicts:
366 EOF
367 grep -e "^# Conflicts:" -e '^Signed-off-by' <.git/COMMIT_EDITMSG >actual &&
368 test_cmp expect actual &&
369
370 cat <<-\EOF >expected &&
371 picked
372
373 Signed-off-by: C O Mitter <committer@example.com>
374 EOF
375
376 git show -s --pretty=format:%B >actual &&
377 test_cmp expected actual
378 '
379
380 test_expect_success 'commit --amend -s places the sign-off at the right place' '
381 pristine_detach initial &&
382 test_must_fail git cherry-pick picked &&
383
384 # emulate old-style conflicts block
385 mv .git/MERGE_MSG .git/MERGE_MSG+ &&
386 sed -e "/^# Conflicts:/,\$s/^# *//" <.git/MERGE_MSG+ >.git/MERGE_MSG &&
387
388 git commit -a &&
389 git commit --amend -s &&
390
391 # Do S-o-b and Conflicts appear in the right order?
392 cat <<-\EOF >expect &&
393 Signed-off-by: C O Mitter <committer@example.com>
394 Conflicts:
395 EOF
396 grep -e "^Conflicts:" -e '^Signed-off-by' <.git/COMMIT_EDITMSG >actual &&
397 test_cmp expect actual
398 '
399
400 test_expect_success 'cherry-pick preserves sparse-checkout' '
401 pristine_detach initial &&
402 test_config core.sparseCheckout true &&
403 test_when_finished "
404 echo \"/*\" >.git/info/sparse-checkout
405 git read-tree --reset -u HEAD
406 rm .git/info/sparse-checkout" &&
407 echo /unrelated >.git/info/sparse-checkout &&
408 git read-tree --reset -u HEAD &&
409 test_must_fail git cherry-pick -Xours picked>actual &&
410 test_i18ngrep ! "Changes not staged for commit:" actual
411 '
412
413 test_expect_success 'cherry-pick --continue remembers --keep-redundant-commits' '
414 test_when_finished "git cherry-pick --abort || :" &&
415 pristine_detach initial &&
416 test_must_fail git cherry-pick --keep-redundant-commits picked redundant &&
417 echo c >foo &&
418 git add foo &&
419 git cherry-pick --continue
420 '
421
422 test_expect_success 'cherry-pick --continue remembers --allow-empty and --allow-empty-message' '
423 test_when_finished "git cherry-pick --abort || :" &&
424 pristine_detach initial &&
425 test_must_fail git cherry-pick --allow-empty --allow-empty-message \
426 picked empty &&
427 echo c >foo &&
428 git add foo &&
429 git cherry-pick --continue
430 '
431
432 test_done