Merge branch 'wl/new-command-doc'
[git.git] / t / t3507-cherry-pick-conflict.sh
blobf32799e04633fd831293d5b64106f9c856d3d407
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 EOF
64 test_must_fail git cherry-pick picked 2>actual &&
66 test_cmp expected actual
69 test_expect_success 'advice from failed cherry-pick --no-commit' "
70 pristine_detach initial &&
72 picked=\$(git rev-parse --short picked) &&
73 cat <<-EOF >expected &&
74 error: could not apply \$picked... picked
75 hint: after resolving the conflicts, mark the corrected paths
76 hint: with 'git add <paths>' or 'git rm <paths>'
77 EOF
78 test_must_fail git cherry-pick --no-commit picked 2>actual &&
80 test_cmp expected actual
83 test_expect_success 'failed cherry-pick sets CHERRY_PICK_HEAD' '
84 pristine_detach initial &&
85 test_must_fail git cherry-pick picked &&
86 test_cmp_rev picked CHERRY_PICK_HEAD
89 test_expect_success 'successful cherry-pick does not set CHERRY_PICK_HEAD' '
90 pristine_detach initial &&
91 git cherry-pick base &&
92 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
95 test_expect_success 'cherry-pick --no-commit does not set CHERRY_PICK_HEAD' '
96 pristine_detach initial &&
97 git cherry-pick --no-commit base &&
98 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
101 test_expect_success 'cherry-pick w/dirty tree does not set CHERRY_PICK_HEAD' '
102 pristine_detach initial &&
103 echo foo >foo &&
104 test_must_fail git cherry-pick base &&
105 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
108 test_expect_success \
109 'cherry-pick --strategy=resolve w/dirty tree does not set CHERRY_PICK_HEAD' '
110 pristine_detach initial &&
111 echo foo >foo &&
112 test_must_fail git cherry-pick --strategy=resolve base &&
113 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
116 test_expect_success 'GIT_CHERRY_PICK_HELP suppresses CHERRY_PICK_HEAD' '
117 pristine_detach initial &&
119 GIT_CHERRY_PICK_HELP="and then do something else" &&
120 export GIT_CHERRY_PICK_HELP &&
121 test_must_fail git cherry-pick picked
122 ) &&
123 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
126 test_expect_success 'git reset clears CHERRY_PICK_HEAD' '
127 pristine_detach initial &&
129 test_must_fail git cherry-pick picked &&
130 git reset &&
132 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
135 test_expect_success 'failed commit does not clear CHERRY_PICK_HEAD' '
136 pristine_detach initial &&
138 test_must_fail git cherry-pick picked &&
139 test_must_fail git commit &&
141 test_cmp_rev picked CHERRY_PICK_HEAD
144 test_expect_success 'cancelled commit does not clear CHERRY_PICK_HEAD' '
145 pristine_detach initial &&
147 test_must_fail git cherry-pick picked &&
148 echo resolved >foo &&
149 git add foo &&
150 git update-index --refresh -q &&
151 test_must_fail git diff-index --exit-code HEAD &&
153 GIT_EDITOR=false &&
154 export GIT_EDITOR &&
155 test_must_fail git commit
156 ) &&
158 test_cmp_rev picked CHERRY_PICK_HEAD
161 test_expect_success 'successful commit clears CHERRY_PICK_HEAD' '
162 pristine_detach initial &&
164 test_must_fail git cherry-pick picked &&
165 echo resolved >foo &&
166 git add foo &&
167 git commit &&
169 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
172 test_expect_success 'partial commit of cherry-pick fails' '
173 pristine_detach initial &&
175 test_must_fail git cherry-pick picked &&
176 echo resolved >foo &&
177 git add foo &&
178 test_must_fail git commit foo 2>err &&
180 test_i18ngrep "cannot do a partial commit during a cherry-pick." err
183 test_expect_success 'commit --amend of cherry-pick fails' '
184 pristine_detach initial &&
186 test_must_fail git cherry-pick picked &&
187 echo resolved >foo &&
188 git add foo &&
189 test_must_fail git commit --amend 2>err &&
191 test_i18ngrep "in the middle of a cherry-pick -- cannot amend." err
194 test_expect_success 'successful final commit clears cherry-pick state' '
195 pristine_detach initial &&
197 test_must_fail git cherry-pick base picked-signed &&
198 echo resolved >foo &&
199 test_path_is_file .git/sequencer/todo &&
200 git commit -a &&
201 test_path_is_missing .git/sequencer
204 test_expect_success 'reset after final pick clears cherry-pick state' '
205 pristine_detach initial &&
207 test_must_fail git cherry-pick base picked-signed &&
208 echo resolved >foo &&
209 test_path_is_file .git/sequencer/todo &&
210 git reset &&
211 test_path_is_missing .git/sequencer
214 test_expect_success 'failed cherry-pick produces dirty index' '
215 pristine_detach initial &&
217 test_must_fail git cherry-pick picked &&
219 test_must_fail git update-index --refresh -q &&
220 test_must_fail git diff-index --exit-code HEAD
223 test_expect_success 'failed cherry-pick registers participants in index' '
224 pristine_detach initial &&
226 git checkout base -- foo &&
227 git ls-files --stage foo &&
228 git checkout initial -- foo &&
229 git ls-files --stage foo &&
230 git checkout picked -- foo &&
231 git ls-files --stage foo
232 } >stages &&
233 sed "
234 1 s/ 0 / 1 /
235 2 s/ 0 / 2 /
236 3 s/ 0 / 3 /
237 " stages >expected &&
238 git read-tree -u --reset HEAD &&
240 test_must_fail git cherry-pick picked &&
241 git ls-files --stage --unmerged >actual &&
243 test_cmp expected actual
246 test_expect_success \
247 'cherry-pick conflict, ensure commit.cleanup = scissors places scissors line properly' '
248 pristine_detach initial &&
249 git config commit.cleanup scissors &&
250 cat <<-EOF >expected &&
251 picked
253 # ------------------------ >8 ------------------------
254 # Do not modify or remove the line above.
255 # Everything below it will be ignored.
257 # Conflicts:
258 # foo
261 test_must_fail git cherry-pick picked &&
263 test_cmp expected .git/MERGE_MSG
266 test_expect_success \
267 'cherry-pick conflict, ensure cleanup=scissors places scissors line properly' '
268 pristine_detach initial &&
269 git config --unset commit.cleanup &&
270 cat <<-EOF >expected &&
271 picked
273 # ------------------------ >8 ------------------------
274 # Do not modify or remove the line above.
275 # Everything below it will be ignored.
277 # Conflicts:
278 # foo
281 test_must_fail git cherry-pick --cleanup=scissors picked &&
283 test_cmp expected .git/MERGE_MSG
286 test_expect_success 'failed cherry-pick describes conflict in work tree' '
287 pristine_detach initial &&
288 cat <<-EOF >expected &&
289 <<<<<<< HEAD
291 =======
293 >>>>>>> objid (picked)
296 test_must_fail git cherry-pick picked &&
298 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
299 test_cmp expected actual
302 test_expect_success 'diff3 -m style' '
303 pristine_detach initial &&
304 git config merge.conflictstyle diff3 &&
305 cat <<-EOF >expected &&
306 <<<<<<< HEAD
308 ||||||| parent of objid (picked)
310 =======
312 >>>>>>> objid (picked)
315 test_must_fail git cherry-pick picked &&
317 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
318 test_cmp expected actual
321 test_expect_success 'revert also handles conflicts sanely' '
322 git config --unset merge.conflictstyle &&
323 pristine_detach initial &&
324 cat <<-EOF >expected &&
325 <<<<<<< HEAD
327 =======
329 >>>>>>> parent of objid (picked)
332 git checkout picked -- foo &&
333 git ls-files --stage foo &&
334 git checkout initial -- foo &&
335 git ls-files --stage foo &&
336 git checkout base -- foo &&
337 git ls-files --stage foo
338 } >stages &&
339 sed "
340 1 s/ 0 / 1 /
341 2 s/ 0 / 2 /
342 3 s/ 0 / 3 /
343 " stages >expected-stages &&
344 git read-tree -u --reset HEAD &&
346 head=$(git rev-parse HEAD) &&
347 test_must_fail git revert picked &&
348 newhead=$(git rev-parse HEAD) &&
349 git ls-files --stage --unmerged >actual-stages &&
351 test "$head" = "$newhead" &&
352 test_must_fail git update-index --refresh -q &&
353 test_must_fail git diff-index --exit-code HEAD &&
354 test_cmp expected-stages actual-stages &&
355 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
356 test_cmp expected actual
359 test_expect_success 'failed revert sets REVERT_HEAD' '
360 pristine_detach initial &&
361 test_must_fail git revert picked &&
362 test_cmp_rev picked REVERT_HEAD
365 test_expect_success 'successful revert does not set REVERT_HEAD' '
366 pristine_detach base &&
367 git revert base &&
368 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
369 test_must_fail git rev-parse --verify REVERT_HEAD
372 test_expect_success 'revert --no-commit sets REVERT_HEAD' '
373 pristine_detach base &&
374 git revert --no-commit base &&
375 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
376 test_cmp_rev base REVERT_HEAD
379 test_expect_success 'revert w/dirty tree does not set REVERT_HEAD' '
380 pristine_detach base &&
381 echo foo >foo &&
382 test_must_fail git revert base &&
383 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
384 test_must_fail git rev-parse --verify REVERT_HEAD
387 test_expect_success 'GIT_CHERRY_PICK_HELP does not suppress REVERT_HEAD' '
388 pristine_detach initial &&
390 GIT_CHERRY_PICK_HELP="and then do something else" &&
391 GIT_REVERT_HELP="and then do something else, again" &&
392 export GIT_CHERRY_PICK_HELP GIT_REVERT_HELP &&
393 test_must_fail git revert picked
394 ) &&
395 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
396 test_cmp_rev picked REVERT_HEAD
399 test_expect_success 'git reset clears REVERT_HEAD' '
400 pristine_detach initial &&
401 test_must_fail git revert picked &&
402 git reset &&
403 test_must_fail git rev-parse --verify REVERT_HEAD
406 test_expect_success 'failed commit does not clear REVERT_HEAD' '
407 pristine_detach initial &&
408 test_must_fail git revert picked &&
409 test_must_fail git commit &&
410 test_cmp_rev picked REVERT_HEAD
413 test_expect_success 'successful final commit clears revert state' '
414 pristine_detach picked-signed &&
416 test_must_fail git revert picked-signed base &&
417 echo resolved >foo &&
418 test_path_is_file .git/sequencer/todo &&
419 git commit -a &&
420 test_path_is_missing .git/sequencer
423 test_expect_success 'reset after final pick clears revert state' '
424 pristine_detach picked-signed &&
426 test_must_fail git revert picked-signed base &&
427 echo resolved >foo &&
428 test_path_is_file .git/sequencer/todo &&
429 git reset &&
430 test_path_is_missing .git/sequencer
433 test_expect_success 'revert conflict, diff3 -m style' '
434 pristine_detach initial &&
435 git config merge.conflictstyle diff3 &&
436 cat <<-EOF >expected &&
437 <<<<<<< HEAD
439 ||||||| objid (picked)
441 =======
443 >>>>>>> parent of objid (picked)
446 test_must_fail git revert picked &&
448 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
449 test_cmp expected actual
452 test_expect_success \
453 'revert conflict, ensure commit.cleanup = scissors places scissors line properly' '
454 pristine_detach initial &&
455 git config commit.cleanup scissors &&
456 cat >expected <<-EOF &&
457 Revert "picked"
459 This reverts commit OBJID.
461 # ------------------------ >8 ------------------------
462 # Do not modify or remove the line above.
463 # Everything below it will be ignored.
465 # Conflicts:
466 # foo
469 test_must_fail git revert picked &&
471 sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
472 test_cmp expected actual
475 test_expect_success \
476 'revert conflict, ensure cleanup=scissors places scissors line properly' '
477 pristine_detach initial &&
478 git config --unset commit.cleanup &&
479 cat >expected <<-EOF &&
480 Revert "picked"
482 This reverts commit OBJID.
484 # ------------------------ >8 ------------------------
485 # Do not modify or remove the line above.
486 # Everything below it will be ignored.
488 # Conflicts:
489 # foo
492 test_must_fail git revert --cleanup=scissors picked &&
494 sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
495 test_cmp expected actual
498 test_expect_success 'failed cherry-pick does not forget -s' '
499 pristine_detach initial &&
500 test_must_fail git cherry-pick -s picked &&
501 test_i18ngrep -e "Signed-off-by" .git/MERGE_MSG
504 test_expect_success 'commit after failed cherry-pick does not add duplicated -s' '
505 pristine_detach initial &&
506 test_must_fail git cherry-pick -s picked-signed &&
507 git commit -a -s &&
508 test $(git show -s >tmp && grep -c "Signed-off-by" tmp && rm tmp) = 1
511 test_expect_success 'commit after failed cherry-pick adds -s at the right place' '
512 pristine_detach initial &&
513 test_must_fail git cherry-pick picked &&
515 git commit -a -s &&
517 # Do S-o-b and Conflicts appear in the right order?
518 cat <<-\EOF >expect &&
519 Signed-off-by: C O Mitter <committer@example.com>
520 # Conflicts:
522 grep -e "^# Conflicts:" -e "^Signed-off-by" .git/COMMIT_EDITMSG >actual &&
523 test_cmp expect actual &&
525 cat <<-\EOF >expected &&
526 picked
528 Signed-off-by: C O Mitter <committer@example.com>
531 git show -s --pretty=format:%B >actual &&
532 test_cmp expected actual
535 test_expect_success 'commit --amend -s places the sign-off at the right place' '
536 pristine_detach initial &&
537 test_must_fail git cherry-pick picked &&
539 # emulate old-style conflicts block
540 mv .git/MERGE_MSG .git/MERGE_MSG+ &&
541 sed -e "/^# Conflicts:/,\$s/^# *//" .git/MERGE_MSG+ >.git/MERGE_MSG &&
543 git commit -a &&
544 git commit --amend -s &&
546 # Do S-o-b and Conflicts appear in the right order?
547 cat <<-\EOF >expect &&
548 Signed-off-by: C O Mitter <committer@example.com>
549 Conflicts:
551 grep -e "^Conflicts:" -e "^Signed-off-by" .git/COMMIT_EDITMSG >actual &&
552 test_cmp expect actual
555 test_expect_success 'cherry-pick preserves sparse-checkout' '
556 pristine_detach initial &&
557 test_config core.sparseCheckout true &&
558 test_when_finished "
559 echo \"/*\" >.git/info/sparse-checkout
560 git read-tree --reset -u HEAD
561 rm .git/info/sparse-checkout" &&
562 mkdir .git/info &&
563 echo /unrelated >.git/info/sparse-checkout &&
564 git read-tree --reset -u HEAD &&
565 test_must_fail git cherry-pick -Xours picked>actual &&
566 test_i18ngrep ! "Changes not staged for commit:" actual
569 test_expect_success 'cherry-pick --continue remembers --keep-redundant-commits' '
570 test_when_finished "git cherry-pick --abort || :" &&
571 pristine_detach initial &&
572 test_must_fail git cherry-pick --keep-redundant-commits picked redundant &&
573 echo c >foo &&
574 git add foo &&
575 git cherry-pick --continue
578 test_expect_success 'cherry-pick --continue remembers --allow-empty and --allow-empty-message' '
579 test_when_finished "git cherry-pick --abort || :" &&
580 pristine_detach initial &&
581 test_must_fail git cherry-pick --allow-empty --allow-empty-message \
582 picked empty &&
583 echo c >foo &&
584 git add foo &&
585 git cherry-pick --continue
588 test_done