Start the 2.46 cycle
[git/gitster.git] / t / t3507-cherry-pick-conflict.sh
blobf3947b400a3a89970e400d3c3f5dc5d690292d83
1 #!/bin/sh
3 test_description='test cherry-pick and revert with conflicts
6 + picked: rewrites foo to c
7 + base: rewrites foo to b
8 + initial: writes foo as a, unrelated as unrelated
12 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
13 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
15 TEST_CREATE_REPO_NO_TEMPLATE=1
16 . ./test-lib.sh
18 pristine_detach () {
19 git checkout -f "$1^0" &&
20 git read-tree -u --reset HEAD &&
21 git clean -d -f -f -q -x
24 test_expect_success setup '
26 echo unrelated >unrelated &&
27 git add unrelated &&
28 test_commit initial foo a &&
29 test_commit base foo b &&
30 test_commit picked foo c &&
31 test_commit --signoff picked-signed foo d &&
32 git checkout -b topic initial &&
33 test_commit redundant-pick foo c redundant &&
34 git commit --allow-empty --allow-empty-message &&
35 git tag empty &&
36 git checkout main &&
37 git config advice.detachedhead false
41 test_expect_success 'failed cherry-pick does not advance HEAD' '
42 pristine_detach initial &&
44 head=$(git rev-parse HEAD) &&
45 test_must_fail git cherry-pick picked &&
46 newhead=$(git rev-parse HEAD) &&
48 test "$head" = "$newhead"
51 test_expect_success 'advice from failed cherry-pick' '
52 pristine_detach initial &&
54 picked=$(git rev-parse --short picked) &&
55 cat <<-EOF >expected &&
56 error: could not apply $picked... picked
57 hint: After resolving the conflicts, mark them with
58 hint: "git add/rm <pathspec>", then run
59 hint: "git cherry-pick --continue".
60 hint: You can instead skip this commit with "git cherry-pick --skip".
61 hint: To abort and get back to the state before "git cherry-pick",
62 hint: run "git cherry-pick --abort".
63 hint: Disable this message with "git config advice.mergeConflict false"
64 EOF
65 test_must_fail git cherry-pick picked 2>actual &&
67 test_cmp expected actual
70 test_expect_success 'advice from failed cherry-pick --no-commit' "
71 pristine_detach initial &&
73 picked=\$(git rev-parse --short picked) &&
74 cat <<-EOF >expected &&
75 error: could not apply \$picked... picked
76 hint: after resolving the conflicts, mark the corrected paths
77 hint: with 'git add <paths>' or 'git rm <paths>'
78 hint: Disable this message with \"git config advice.mergeConflict false\"
79 EOF
80 test_must_fail git cherry-pick --no-commit picked 2>actual &&
82 test_cmp expected actual
85 test_expect_success 'failed cherry-pick sets CHERRY_PICK_HEAD' '
86 pristine_detach initial &&
87 test_must_fail git cherry-pick picked &&
88 test_cmp_rev picked CHERRY_PICK_HEAD
91 test_expect_success 'successful cherry-pick does not set CHERRY_PICK_HEAD' '
92 pristine_detach initial &&
93 git cherry-pick base &&
94 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
97 test_expect_success 'cherry-pick --no-commit does not set CHERRY_PICK_HEAD' '
98 pristine_detach initial &&
99 git cherry-pick --no-commit base &&
100 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
103 test_expect_success 'cherry-pick w/dirty tree does not set CHERRY_PICK_HEAD' '
104 pristine_detach initial &&
105 echo foo >foo &&
106 test_must_fail git cherry-pick base &&
107 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
110 test_expect_success \
111 'cherry-pick --strategy=resolve w/dirty tree does not set CHERRY_PICK_HEAD' '
112 pristine_detach initial &&
113 echo foo >foo &&
114 test_must_fail git cherry-pick --strategy=resolve base &&
115 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
118 test_expect_success 'GIT_CHERRY_PICK_HELP suppresses CHERRY_PICK_HEAD' '
119 pristine_detach initial &&
121 GIT_CHERRY_PICK_HELP="and then do something else" &&
122 export GIT_CHERRY_PICK_HELP &&
123 test_must_fail git cherry-pick picked
124 ) &&
125 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
128 test_expect_success 'git reset clears CHERRY_PICK_HEAD' '
129 pristine_detach initial &&
131 test_must_fail git cherry-pick picked &&
132 git reset &&
134 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
137 test_expect_success 'failed commit does not clear CHERRY_PICK_HEAD' '
138 pristine_detach initial &&
140 test_must_fail git cherry-pick picked &&
141 test_must_fail git commit &&
143 test_cmp_rev picked CHERRY_PICK_HEAD
146 test_expect_success 'cancelled commit does not clear CHERRY_PICK_HEAD' '
147 pristine_detach initial &&
149 test_must_fail git cherry-pick picked &&
150 echo resolved >foo &&
151 git add foo &&
152 git update-index --refresh -q &&
153 test_must_fail git diff-index --exit-code HEAD &&
155 GIT_EDITOR=false &&
156 export GIT_EDITOR &&
157 test_must_fail git commit
158 ) &&
160 test_cmp_rev picked CHERRY_PICK_HEAD
163 test_expect_success 'successful commit clears CHERRY_PICK_HEAD' '
164 pristine_detach initial &&
166 test_must_fail git cherry-pick picked &&
167 echo resolved >foo &&
168 git add foo &&
169 git commit &&
171 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
174 test_expect_success 'partial commit of cherry-pick fails' '
175 pristine_detach initial &&
177 test_must_fail git cherry-pick picked &&
178 echo resolved >foo &&
179 git add foo &&
180 test_must_fail git commit foo 2>err &&
182 test_grep "cannot do a partial commit during a cherry-pick." err
185 test_expect_success 'commit --amend of cherry-pick fails' '
186 pristine_detach initial &&
188 test_must_fail git cherry-pick picked &&
189 echo resolved >foo &&
190 git add foo &&
191 test_must_fail git commit --amend 2>err &&
193 test_grep "in the middle of a cherry-pick -- cannot amend." err
196 test_expect_success 'successful final commit clears cherry-pick state' '
197 pristine_detach initial &&
199 test_must_fail git cherry-pick base picked-signed &&
200 echo resolved >foo &&
201 test_path_is_file .git/sequencer/todo &&
202 git commit -a &&
203 test_path_is_missing .git/sequencer
206 test_expect_success 'reset after final pick clears cherry-pick state' '
207 pristine_detach initial &&
209 test_must_fail git cherry-pick base picked-signed &&
210 echo resolved >foo &&
211 test_path_is_file .git/sequencer/todo &&
212 git reset &&
213 test_path_is_missing .git/sequencer
216 test_expect_success 'failed cherry-pick produces dirty index' '
217 pristine_detach initial &&
219 test_must_fail git cherry-pick picked &&
221 test_must_fail git update-index --refresh -q &&
222 test_must_fail git diff-index --exit-code HEAD
225 test_expect_success 'failed cherry-pick registers participants in index' '
226 pristine_detach initial &&
228 git checkout base -- foo &&
229 git ls-files --stage foo &&
230 git checkout initial -- foo &&
231 git ls-files --stage foo &&
232 git checkout picked -- foo &&
233 git ls-files --stage foo
234 } >stages &&
235 sed "
236 1 s/ 0 / 1 /
237 2 s/ 0 / 2 /
238 3 s/ 0 / 3 /
239 " stages >expected &&
240 git read-tree -u --reset HEAD &&
242 test_must_fail git cherry-pick picked &&
243 git ls-files --stage --unmerged >actual &&
245 test_cmp expected actual
248 test_expect_success \
249 'cherry-pick conflict, ensure commit.cleanup = scissors places scissors line properly' '
250 pristine_detach initial &&
251 git config commit.cleanup scissors &&
252 cat <<-EOF >expected &&
253 picked
255 # ------------------------ >8 ------------------------
256 # Do not modify or remove the line above.
257 # Everything below it will be ignored.
259 # Conflicts:
260 # foo
263 test_must_fail git cherry-pick picked &&
265 test_cmp expected .git/MERGE_MSG
268 test_expect_success \
269 'cherry-pick conflict, ensure cleanup=scissors places scissors line properly' '
270 pristine_detach initial &&
271 git config --unset commit.cleanup &&
272 cat <<-EOF >expected &&
273 picked
275 # ------------------------ >8 ------------------------
276 # Do not modify or remove the line above.
277 # Everything below it will be ignored.
279 # Conflicts:
280 # foo
283 test_must_fail git cherry-pick --cleanup=scissors picked &&
285 test_cmp expected .git/MERGE_MSG
288 test_expect_success 'failed cherry-pick describes conflict in work tree' '
289 pristine_detach initial &&
290 cat <<-EOF >expected &&
291 <<<<<<< HEAD
293 =======
295 >>>>>>> objid (picked)
298 test_must_fail git cherry-pick picked &&
300 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
301 test_cmp expected actual
304 test_expect_success 'diff3 -m style' '
305 pristine_detach initial &&
306 git config merge.conflictstyle diff3 &&
307 cat <<-EOF >expected &&
308 <<<<<<< HEAD
310 ||||||| parent of objid (picked)
312 =======
314 >>>>>>> objid (picked)
317 test_must_fail git cherry-pick picked &&
319 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
320 test_cmp expected actual
323 test_expect_success 'revert also handles conflicts sanely' '
324 git config --unset merge.conflictstyle &&
325 pristine_detach initial &&
326 cat <<-EOF >expected &&
327 <<<<<<< HEAD
329 =======
331 >>>>>>> parent of objid (picked)
334 git checkout picked -- foo &&
335 git ls-files --stage foo &&
336 git checkout initial -- foo &&
337 git ls-files --stage foo &&
338 git checkout base -- foo &&
339 git ls-files --stage foo
340 } >stages &&
341 sed "
342 1 s/ 0 / 1 /
343 2 s/ 0 / 2 /
344 3 s/ 0 / 3 /
345 " stages >expected-stages &&
346 git read-tree -u --reset HEAD &&
348 head=$(git rev-parse HEAD) &&
349 test_must_fail git revert picked &&
350 newhead=$(git rev-parse HEAD) &&
351 git ls-files --stage --unmerged >actual-stages &&
353 test "$head" = "$newhead" &&
354 test_must_fail git update-index --refresh -q &&
355 test_must_fail git diff-index --exit-code HEAD &&
356 test_cmp expected-stages actual-stages &&
357 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
358 test_cmp expected actual
361 test_expect_success 'failed revert sets REVERT_HEAD' '
362 pristine_detach initial &&
363 test_must_fail git revert picked &&
364 test_cmp_rev picked REVERT_HEAD
367 test_expect_success 'successful revert does not set REVERT_HEAD' '
368 pristine_detach base &&
369 git revert base &&
370 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
371 test_must_fail git rev-parse --verify REVERT_HEAD
374 test_expect_success 'revert --no-commit sets REVERT_HEAD' '
375 pristine_detach base &&
376 git revert --no-commit base &&
377 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
378 test_cmp_rev base REVERT_HEAD
381 test_expect_success 'revert w/dirty tree does not set REVERT_HEAD' '
382 pristine_detach base &&
383 echo foo >foo &&
384 test_must_fail git revert base &&
385 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
386 test_must_fail git rev-parse --verify REVERT_HEAD
389 test_expect_success 'GIT_CHERRY_PICK_HELP does not suppress REVERT_HEAD' '
390 pristine_detach initial &&
392 GIT_CHERRY_PICK_HELP="and then do something else" &&
393 GIT_REVERT_HELP="and then do something else, again" &&
394 export GIT_CHERRY_PICK_HELP GIT_REVERT_HELP &&
395 test_must_fail git revert picked
396 ) &&
397 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
398 test_cmp_rev picked REVERT_HEAD
401 test_expect_success 'git reset clears REVERT_HEAD' '
402 pristine_detach initial &&
403 test_must_fail git revert picked &&
404 git reset &&
405 test_must_fail git rev-parse --verify REVERT_HEAD
408 test_expect_success 'failed commit does not clear REVERT_HEAD' '
409 pristine_detach initial &&
410 test_must_fail git revert picked &&
411 test_must_fail git commit &&
412 test_cmp_rev picked REVERT_HEAD
415 test_expect_success 'successful final commit clears revert state' '
416 pristine_detach picked-signed &&
418 test_must_fail git revert picked-signed base &&
419 echo resolved >foo &&
420 test_path_is_file .git/sequencer/todo &&
421 git commit -a &&
422 test_path_is_missing .git/sequencer
425 test_expect_success 'reset after final pick clears revert state' '
426 pristine_detach picked-signed &&
428 test_must_fail git revert picked-signed base &&
429 echo resolved >foo &&
430 test_path_is_file .git/sequencer/todo &&
431 git reset &&
432 test_path_is_missing .git/sequencer
435 test_expect_success 'revert conflict, diff3 -m style' '
436 pristine_detach initial &&
437 git config merge.conflictstyle diff3 &&
438 cat <<-EOF >expected &&
439 <<<<<<< HEAD
441 ||||||| objid (picked)
443 =======
445 >>>>>>> parent of objid (picked)
448 test_must_fail git revert picked &&
450 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
451 test_cmp expected actual
454 test_expect_success \
455 'revert conflict, ensure commit.cleanup = scissors places scissors line properly' '
456 pristine_detach initial &&
457 git config commit.cleanup scissors &&
458 cat >expected <<-EOF &&
459 Revert "picked"
461 This reverts commit OBJID.
463 # ------------------------ >8 ------------------------
464 # Do not modify or remove the line above.
465 # Everything below it will be ignored.
467 # Conflicts:
468 # foo
471 test_must_fail git revert picked &&
473 sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
474 test_cmp expected actual
477 test_expect_success \
478 'revert conflict, ensure cleanup=scissors places scissors line properly' '
479 pristine_detach initial &&
480 git config --unset commit.cleanup &&
481 cat >expected <<-EOF &&
482 Revert "picked"
484 This reverts commit OBJID.
486 # ------------------------ >8 ------------------------
487 # Do not modify or remove the line above.
488 # Everything below it will be ignored.
490 # Conflicts:
491 # foo
494 test_must_fail git revert --cleanup=scissors picked &&
496 sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
497 test_cmp expected actual
500 test_expect_success 'failed cherry-pick does not forget -s' '
501 pristine_detach initial &&
502 test_must_fail git cherry-pick -s picked &&
503 test_grep -e "Signed-off-by" .git/MERGE_MSG
506 test_expect_success 'commit after failed cherry-pick does not add duplicated -s' '
507 pristine_detach initial &&
508 test_must_fail git cherry-pick -s picked-signed &&
509 git commit -a -s &&
510 test $(git show -s >tmp && grep -c "Signed-off-by" tmp && rm tmp) = 1
513 test_expect_success 'commit after failed cherry-pick adds -s at the right place' '
514 pristine_detach initial &&
515 test_must_fail git cherry-pick picked &&
517 git commit -a -s &&
519 # Do S-o-b and Conflicts appear in the right order?
520 cat <<-\EOF >expect &&
521 Signed-off-by: C O Mitter <committer@example.com>
522 # Conflicts:
524 grep -e "^# Conflicts:" -e "^Signed-off-by" .git/COMMIT_EDITMSG >actual &&
525 test_cmp expect actual &&
527 cat <<-\EOF >expected &&
528 picked
530 Signed-off-by: C O Mitter <committer@example.com>
533 git show -s --pretty=format:%B >actual &&
534 test_cmp expected actual
537 test_expect_success 'commit --amend -s places the sign-off at the right place' '
538 pristine_detach initial &&
539 test_must_fail git cherry-pick picked &&
541 # emulate old-style conflicts block
542 mv .git/MERGE_MSG .git/MERGE_MSG+ &&
543 sed -e "/^# Conflicts:/,\$s/^# *//" .git/MERGE_MSG+ >.git/MERGE_MSG &&
545 git commit -a &&
546 git commit --amend -s &&
548 # Do S-o-b and Conflicts appear in the right order?
549 cat <<-\EOF >expect &&
550 Signed-off-by: C O Mitter <committer@example.com>
551 Conflicts:
553 grep -e "^Conflicts:" -e "^Signed-off-by" .git/COMMIT_EDITMSG >actual &&
554 test_cmp expect actual
557 test_expect_success 'cherry-pick preserves sparse-checkout' '
558 pristine_detach initial &&
559 test_config core.sparseCheckout true &&
560 test_when_finished "
561 echo \"/*\" >.git/info/sparse-checkout
562 git read-tree --reset -u HEAD
563 rm .git/info/sparse-checkout" &&
564 mkdir .git/info &&
565 echo /unrelated >.git/info/sparse-checkout &&
566 git read-tree --reset -u HEAD &&
567 test_must_fail git cherry-pick -Xours picked>actual &&
568 test_grep ! "Changes not staged for commit:" actual
571 test_expect_success 'cherry-pick --continue remembers --keep-redundant-commits' '
572 test_when_finished "git cherry-pick --abort || :" &&
573 pristine_detach initial &&
574 test_must_fail git cherry-pick --keep-redundant-commits picked redundant &&
575 echo c >foo &&
576 git add foo &&
577 git cherry-pick --continue
580 test_expect_success 'cherry-pick --continue remembers --allow-empty and --allow-empty-message' '
581 test_when_finished "git cherry-pick --abort || :" &&
582 pristine_detach initial &&
583 test_must_fail git cherry-pick --allow-empty --allow-empty-message \
584 picked empty &&
585 echo c >foo &&
586 git add foo &&
587 git cherry-pick --continue
590 test_done