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
18 git checkout -f "$1^0" &&
19 git read-tree -u --reset HEAD &&
20 git clean -d -f -f -q -x
23 test_expect_success setup '
25 echo unrelated >unrelated &&
27 test_commit initial foo a &&
28 test_commit base foo b &&
29 test_commit picked foo c &&
30 test_commit --signoff picked-signed foo d &&
31 git checkout -b topic initial &&
32 test_commit redundant-pick foo c redundant &&
33 git commit --allow-empty --allow-empty-message &&
36 git config advice.detachedhead false
40 test_expect_success 'failed cherry-pick does not advance HEAD' '
41 pristine_detach initial &&
43 head=$(git rev-parse HEAD) &&
44 test_must_fail git cherry-pick picked &&
45 newhead=$(git rev-parse HEAD) &&
47 test "$head" = "$newhead"
50 test_expect_success 'advice from failed cherry-pick' "
51 pristine_detach initial &&
53 picked=\$(git rev-parse --short picked) &&
54 cat <<-EOF >expected &&
55 error: could not apply \$picked... picked
56 hint: after resolving the conflicts, mark the corrected paths
57 hint: with 'git add <paths>' or 'git rm <paths>'
58 hint: and commit the result with 'git commit'
60 test_must_fail git cherry-pick picked 2>actual &&
62 test_cmp expected actual
65 test_expect_success 'advice from failed cherry-pick --no-commit' "
66 pristine_detach initial &&
68 picked=\$(git rev-parse --short picked) &&
69 cat <<-EOF >expected &&
70 error: could not apply \$picked... picked
71 hint: after resolving the conflicts, mark the corrected paths
72 hint: with 'git add <paths>' or 'git rm <paths>'
74 test_must_fail git cherry-pick --no-commit picked 2>actual &&
76 test_cmp expected actual
79 test_expect_success 'failed cherry-pick sets CHERRY_PICK_HEAD' '
80 pristine_detach initial &&
81 test_must_fail git cherry-pick picked &&
82 test_cmp_rev picked CHERRY_PICK_HEAD
85 test_expect_success 'successful cherry-pick does not set CHERRY_PICK_HEAD' '
86 pristine_detach initial &&
87 git cherry-pick base &&
88 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
91 test_expect_success 'cherry-pick --no-commit does not set CHERRY_PICK_HEAD' '
92 pristine_detach initial &&
93 git cherry-pick --no-commit base &&
94 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
97 test_expect_success 'cherry-pick w/dirty tree does not set CHERRY_PICK_HEAD' '
98 pristine_detach initial &&
100 test_must_fail git cherry-pick base &&
101 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
104 test_expect_success \
105 'cherry-pick --strategy=resolve w/dirty tree does not set CHERRY_PICK_HEAD' '
106 pristine_detach initial &&
108 test_must_fail git cherry-pick --strategy=resolve base &&
109 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
112 test_expect_success 'GIT_CHERRY_PICK_HELP suppresses CHERRY_PICK_HEAD' '
113 pristine_detach initial &&
115 GIT_CHERRY_PICK_HELP="and then do something else" &&
116 export GIT_CHERRY_PICK_HELP &&
117 test_must_fail git cherry-pick picked
119 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
122 test_expect_success 'git reset clears CHERRY_PICK_HEAD' '
123 pristine_detach initial &&
125 test_must_fail git cherry-pick picked &&
128 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
131 test_expect_success 'failed commit does not clear CHERRY_PICK_HEAD' '
132 pristine_detach initial &&
134 test_must_fail git cherry-pick picked &&
135 test_must_fail git commit &&
137 test_cmp_rev picked CHERRY_PICK_HEAD
140 test_expect_success 'cancelled commit does not clear CHERRY_PICK_HEAD' '
141 pristine_detach initial &&
143 test_must_fail git cherry-pick picked &&
144 echo resolved >foo &&
146 git update-index --refresh -q &&
147 test_must_fail git diff-index --exit-code HEAD &&
151 test_must_fail git commit
154 test_cmp_rev picked CHERRY_PICK_HEAD
157 test_expect_success 'successful commit clears CHERRY_PICK_HEAD' '
158 pristine_detach initial &&
160 test_must_fail git cherry-pick picked &&
161 echo resolved >foo &&
165 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
168 test_expect_success 'partial commit of cherry-pick fails' '
169 pristine_detach initial &&
171 test_must_fail git cherry-pick picked &&
172 echo resolved >foo &&
174 test_must_fail git commit foo 2>err &&
176 test_i18ngrep "cannot do a partial commit during a cherry-pick." err
179 test_expect_success 'commit --amend of cherry-pick fails' '
180 pristine_detach initial &&
182 test_must_fail git cherry-pick picked &&
183 echo resolved >foo &&
185 test_must_fail git commit --amend 2>err &&
187 test_i18ngrep "in the middle of a cherry-pick -- cannot amend." err
190 test_expect_success 'successful final commit clears cherry-pick state' '
191 pristine_detach initial &&
193 test_must_fail git cherry-pick base picked-signed &&
194 echo resolved >foo &&
195 test_path_is_file .git/sequencer/todo &&
197 test_path_is_missing .git/sequencer
200 test_expect_success 'reset after final pick clears cherry-pick state' '
201 pristine_detach initial &&
203 test_must_fail git cherry-pick base picked-signed &&
204 echo resolved >foo &&
205 test_path_is_file .git/sequencer/todo &&
207 test_path_is_missing .git/sequencer
210 test_expect_success 'failed cherry-pick produces dirty index' '
211 pristine_detach initial &&
213 test_must_fail git cherry-pick picked &&
215 test_must_fail git update-index --refresh -q &&
216 test_must_fail git diff-index --exit-code HEAD
219 test_expect_success 'failed cherry-pick registers participants in index' '
220 pristine_detach initial &&
222 git checkout base -- foo &&
223 git ls-files --stage foo &&
224 git checkout initial -- foo &&
225 git ls-files --stage foo &&
226 git checkout picked -- foo &&
227 git ls-files --stage foo
233 " stages >expected &&
234 git read-tree -u --reset HEAD &&
236 test_must_fail git cherry-pick picked &&
237 git ls-files --stage --unmerged >actual &&
239 test_cmp expected actual
242 test_expect_success \
243 'cherry-pick conflict, ensure commit.cleanup = scissors places scissors line properly' '
244 pristine_detach initial &&
245 git config commit.cleanup scissors &&
246 cat <<-EOF >expected &&
249 # ------------------------ >8 ------------------------
250 # Do not modify or remove the line above.
251 # Everything below it will be ignored.
257 test_must_fail git cherry-pick picked &&
259 test_cmp expected .git/MERGE_MSG
262 test_expect_success \
263 'cherry-pick conflict, ensure cleanup=scissors places scissors line properly' '
264 pristine_detach initial &&
265 git config --unset commit.cleanup &&
266 cat <<-EOF >expected &&
269 # ------------------------ >8 ------------------------
270 # Do not modify or remove the line above.
271 # Everything below it will be ignored.
277 test_must_fail git cherry-pick --cleanup=scissors picked &&
279 test_cmp expected .git/MERGE_MSG
282 test_expect_success 'failed cherry-pick describes conflict in work tree' '
283 pristine_detach initial &&
284 cat <<-EOF >expected &&
289 >>>>>>> objid (picked)
292 test_must_fail git cherry-pick picked &&
294 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
295 test_cmp expected actual
298 test_expect_success 'diff3 -m style' '
299 pristine_detach initial &&
300 git config merge.conflictstyle diff3 &&
301 cat <<-EOF >expected &&
304 ||||||| parent of objid (picked)
308 >>>>>>> objid (picked)
311 test_must_fail git cherry-pick picked &&
313 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
314 test_cmp expected actual
317 test_expect_success 'revert also handles conflicts sanely' '
318 git config --unset merge.conflictstyle &&
319 pristine_detach initial &&
320 cat <<-EOF >expected &&
325 >>>>>>> parent of objid (picked)
328 git checkout picked -- foo &&
329 git ls-files --stage foo &&
330 git checkout initial -- foo &&
331 git ls-files --stage foo &&
332 git checkout base -- foo &&
333 git ls-files --stage foo
339 " stages >expected-stages &&
340 git read-tree -u --reset HEAD &&
342 head=$(git rev-parse HEAD) &&
343 test_must_fail git revert picked &&
344 newhead=$(git rev-parse HEAD) &&
345 git ls-files --stage --unmerged >actual-stages &&
347 test "$head" = "$newhead" &&
348 test_must_fail git update-index --refresh -q &&
349 test_must_fail git diff-index --exit-code HEAD &&
350 test_cmp expected-stages actual-stages &&
351 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
352 test_cmp expected actual
355 test_expect_success 'failed revert sets REVERT_HEAD' '
356 pristine_detach initial &&
357 test_must_fail git revert picked &&
358 test_cmp_rev picked REVERT_HEAD
361 test_expect_success 'successful revert does not set REVERT_HEAD' '
362 pristine_detach base &&
364 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
365 test_must_fail git rev-parse --verify REVERT_HEAD
368 test_expect_success 'revert --no-commit sets REVERT_HEAD' '
369 pristine_detach base &&
370 git revert --no-commit base &&
371 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
372 test_cmp_rev base REVERT_HEAD
375 test_expect_success 'revert w/dirty tree does not set REVERT_HEAD' '
376 pristine_detach base &&
378 test_must_fail git revert base &&
379 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
380 test_must_fail git rev-parse --verify REVERT_HEAD
383 test_expect_success 'GIT_CHERRY_PICK_HELP does not suppress REVERT_HEAD' '
384 pristine_detach initial &&
386 GIT_CHERRY_PICK_HELP="and then do something else" &&
387 GIT_REVERT_HELP="and then do something else, again" &&
388 export GIT_CHERRY_PICK_HELP GIT_REVERT_HELP &&
389 test_must_fail git revert picked
391 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
392 test_cmp_rev picked REVERT_HEAD
395 test_expect_success 'git reset clears REVERT_HEAD' '
396 pristine_detach initial &&
397 test_must_fail git revert picked &&
399 test_must_fail git rev-parse --verify REVERT_HEAD
402 test_expect_success 'failed commit does not clear REVERT_HEAD' '
403 pristine_detach initial &&
404 test_must_fail git revert picked &&
405 test_must_fail git commit &&
406 test_cmp_rev picked REVERT_HEAD
409 test_expect_success 'successful final commit clears revert state' '
410 pristine_detach picked-signed &&
412 test_must_fail git revert picked-signed base &&
413 echo resolved >foo &&
414 test_path_is_file .git/sequencer/todo &&
416 test_path_is_missing .git/sequencer
419 test_expect_success 'reset after final pick clears revert state' '
420 pristine_detach picked-signed &&
422 test_must_fail git revert picked-signed base &&
423 echo resolved >foo &&
424 test_path_is_file .git/sequencer/todo &&
426 test_path_is_missing .git/sequencer
429 test_expect_success 'revert conflict, diff3 -m style' '
430 pristine_detach initial &&
431 git config merge.conflictstyle diff3 &&
432 cat <<-EOF >expected &&
435 ||||||| objid (picked)
439 >>>>>>> parent of objid (picked)
442 test_must_fail git revert picked &&
444 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
445 test_cmp expected actual
448 test_expect_success \
449 'revert conflict, ensure commit.cleanup = scissors places scissors line properly' '
450 pristine_detach initial &&
451 git config commit.cleanup scissors &&
452 cat >expected <<-EOF &&
455 This reverts commit OBJID.
457 # ------------------------ >8 ------------------------
458 # Do not modify or remove the line above.
459 # Everything below it will be ignored.
465 test_must_fail git revert picked &&
467 sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
468 test_cmp expected actual
471 test_expect_success \
472 'revert conflict, ensure cleanup=scissors places scissors line properly' '
473 pristine_detach initial &&
474 git config --unset commit.cleanup &&
475 cat >expected <<-EOF &&
478 This reverts commit OBJID.
480 # ------------------------ >8 ------------------------
481 # Do not modify or remove the line above.
482 # Everything below it will be ignored.
488 test_must_fail git revert --cleanup=scissors picked &&
490 sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
491 test_cmp expected actual
494 test_expect_success 'failed cherry-pick does not forget -s' '
495 pristine_detach initial &&
496 test_must_fail git cherry-pick -s picked &&
497 test_i18ngrep -e "Signed-off-by" .git/MERGE_MSG
500 test_expect_success 'commit after failed cherry-pick does not add duplicated -s' '
501 pristine_detach initial &&
502 test_must_fail git cherry-pick -s picked-signed &&
504 test $(git show -s >tmp && grep -c "Signed-off-by" tmp && rm tmp) = 1
507 test_expect_success 'commit after failed cherry-pick adds -s at the right place' '
508 pristine_detach initial &&
509 test_must_fail git cherry-pick picked &&
513 # Do S-o-b and Conflicts appear in the right order?
514 cat <<-\EOF >expect &&
515 Signed-off-by: C O Mitter <committer@example.com>
518 grep -e "^# Conflicts:" -e "^Signed-off-by" .git/COMMIT_EDITMSG >actual &&
519 test_cmp expect actual &&
521 cat <<-\EOF >expected &&
524 Signed-off-by: C O Mitter <committer@example.com>
527 git show -s --pretty=format:%B >actual &&
528 test_cmp expected actual
531 test_expect_success 'commit --amend -s places the sign-off at the right place' '
532 pristine_detach initial &&
533 test_must_fail git cherry-pick picked &&
535 # emulate old-style conflicts block
536 mv .git/MERGE_MSG .git/MERGE_MSG+ &&
537 sed -e "/^# Conflicts:/,\$s/^# *//" .git/MERGE_MSG+ >.git/MERGE_MSG &&
540 git commit --amend -s &&
542 # Do S-o-b and Conflicts appear in the right order?
543 cat <<-\EOF >expect &&
544 Signed-off-by: C O Mitter <committer@example.com>
547 grep -e "^Conflicts:" -e "^Signed-off-by" .git/COMMIT_EDITMSG >actual &&
548 test_cmp expect actual
551 test_expect_success 'cherry-pick preserves sparse-checkout' '
552 pristine_detach initial &&
553 test_config core.sparseCheckout true &&
555 echo \"/*\" >.git/info/sparse-checkout
556 git read-tree --reset -u HEAD
557 rm .git/info/sparse-checkout" &&
558 echo /unrelated >.git/info/sparse-checkout &&
559 git read-tree --reset -u HEAD &&
560 test_must_fail git cherry-pick -Xours picked>actual &&
561 test_i18ngrep ! "Changes not staged for commit:" actual
564 test_expect_success 'cherry-pick --continue remembers --keep-redundant-commits' '
565 test_when_finished "git cherry-pick --abort || :" &&
566 pristine_detach initial &&
567 test_must_fail git cherry-pick --keep-redundant-commits picked redundant &&
570 git cherry-pick --continue
573 test_expect_success 'cherry-pick --continue remembers --allow-empty and --allow-empty-message' '
574 test_when_finished "git cherry-pick --abort || :" &&
575 pristine_detach initial &&
576 test_must_fail git cherry-pick --allow-empty --allow-empty-message \
580 git cherry-pick --continue