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
15 git checkout -f "$1^0" &&
16 git read-tree -u --reset HEAD &&
17 git clean -d -f -f -q -x
20 test_expect_success setup '
22 echo unrelated >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 &&
32 git checkout master &&
33 git config advice.detachedhead false
37 test_expect_success 'failed cherry-pick does not advance HEAD' '
38 pristine_detach initial &&
40 head=$(git rev-parse HEAD) &&
41 test_must_fail git cherry-pick picked &&
42 newhead=$(git rev-parse HEAD) &&
44 test "$head" = "$newhead"
47 test_expect_success 'advice from failed cherry-pick' "
48 pristine_detach initial &&
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'
57 test_must_fail git cherry-pick picked 2>actual &&
59 test_i18ncmp expected actual
62 test_expect_success 'advice from failed cherry-pick --no-commit' "
63 pristine_detach initial &&
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>'
71 test_must_fail git cherry-pick --no-commit picked 2>actual &&
73 test_i18ncmp expected actual
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
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
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
94 test_expect_success 'cherry-pick w/dirty tree does not set CHERRY_PICK_HEAD' '
95 pristine_detach initial &&
97 test_must_fail git cherry-pick base &&
98 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
101 test_expect_success \
102 'cherry-pick --strategy=resolve w/dirty tree does not set CHERRY_PICK_HEAD' '
103 pristine_detach initial &&
105 test_must_fail git cherry-pick --strategy=resolve base &&
106 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
109 test_expect_success 'GIT_CHERRY_PICK_HELP suppresses CHERRY_PICK_HEAD' '
110 pristine_detach initial &&
112 GIT_CHERRY_PICK_HELP="and then do something else" &&
113 export GIT_CHERRY_PICK_HELP &&
114 test_must_fail git cherry-pick picked
116 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
119 test_expect_success 'git reset clears CHERRY_PICK_HEAD' '
120 pristine_detach initial &&
122 test_must_fail git cherry-pick picked &&
125 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
128 test_expect_success 'failed commit does not clear CHERRY_PICK_HEAD' '
129 pristine_detach initial &&
131 test_must_fail git cherry-pick picked &&
132 test_must_fail git commit &&
134 test_cmp_rev picked CHERRY_PICK_HEAD
137 test_expect_success 'cancelled commit does not clear CHERRY_PICK_HEAD' '
138 pristine_detach initial &&
140 test_must_fail git cherry-pick picked &&
141 echo resolved >foo &&
143 git update-index --refresh -q &&
144 test_must_fail git diff-index --exit-code HEAD &&
148 test_must_fail git commit
151 test_cmp_rev picked CHERRY_PICK_HEAD
154 test_expect_success 'successful commit clears CHERRY_PICK_HEAD' '
155 pristine_detach initial &&
157 test_must_fail git cherry-pick picked &&
158 echo resolved >foo &&
162 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
165 test_expect_success 'failed cherry-pick produces dirty index' '
166 pristine_detach initial &&
168 test_must_fail git cherry-pick picked &&
170 test_must_fail git update-index --refresh -q &&
171 test_must_fail git diff-index --exit-code HEAD
174 test_expect_success 'failed cherry-pick registers participants in index' '
175 pristine_detach initial &&
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
188 " stages >expected &&
189 git read-tree -u --reset HEAD &&
191 test_must_fail git cherry-pick picked &&
192 git ls-files --stage --unmerged >actual &&
194 test_cmp expected actual
197 test_expect_success \
198 'cherry-pick conflict, ensure commit.cleanup = scissors places scissors line properly' '
199 pristine_detach initial &&
200 git config commit.cleanup scissors &&
201 cat <<-EOF >expected &&
204 # ------------------------ >8 ------------------------
205 # Do not modify or remove the line above.
206 # Everything below it will be ignored.
212 test_must_fail git cherry-pick picked &&
214 test_i18ncmp expected .git/MERGE_MSG
217 test_expect_success \
218 'cherry-pick conflict, ensure cleanup=scissors places scissors line properly' '
219 pristine_detach initial &&
220 git config --unset commit.cleanup &&
221 cat <<-EOF >expected &&
224 # ------------------------ >8 ------------------------
225 # Do not modify or remove the line above.
226 # Everything below it will be ignored.
232 test_must_fail git cherry-pick --cleanup=scissors picked &&
234 test_i18ncmp expected .git/MERGE_MSG
237 test_expect_success 'failed cherry-pick describes conflict in work tree' '
238 pristine_detach initial &&
239 cat <<-EOF >expected &&
247 test_must_fail git cherry-pick picked &&
249 sed "s/[a-f0-9]*\.\.\./objid/" foo >actual &&
250 test_cmp expected actual
253 test_expect_success 'diff3 -m style' '
254 pristine_detach initial &&
255 git config merge.conflictstyle diff3 &&
256 cat <<-EOF >expected &&
259 ||||||| parent of objid picked
266 test_must_fail git cherry-pick picked &&
268 sed "s/[a-f0-9]*\.\.\./objid/" foo >actual &&
269 test_cmp expected actual
272 test_expect_success 'revert also handles conflicts sanely' '
273 git config --unset merge.conflictstyle &&
274 pristine_detach initial &&
275 cat <<-EOF >expected &&
280 >>>>>>> parent of objid picked
283 git checkout picked -- foo &&
284 git ls-files --stage foo &&
285 git checkout initial -- foo &&
286 git ls-files --stage foo &&
287 git checkout base -- foo &&
288 git ls-files --stage foo
294 " stages >expected-stages &&
295 git read-tree -u --reset HEAD &&
297 head=$(git rev-parse HEAD) &&
298 test_must_fail git revert picked &&
299 newhead=$(git rev-parse HEAD) &&
300 git ls-files --stage --unmerged >actual-stages &&
302 test "$head" = "$newhead" &&
303 test_must_fail git update-index --refresh -q &&
304 test_must_fail git diff-index --exit-code HEAD &&
305 test_cmp expected-stages actual-stages &&
306 sed "s/[a-f0-9]*\.\.\./objid/" foo >actual &&
307 test_cmp expected actual
310 test_expect_success 'failed revert sets REVERT_HEAD' '
311 pristine_detach initial &&
312 test_must_fail git revert picked &&
313 test_cmp_rev picked REVERT_HEAD
316 test_expect_success 'successful revert does not set REVERT_HEAD' '
317 pristine_detach base &&
319 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
320 test_must_fail git rev-parse --verify REVERT_HEAD
323 test_expect_success 'revert --no-commit sets REVERT_HEAD' '
324 pristine_detach base &&
325 git revert --no-commit base &&
326 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
327 test_cmp_rev base REVERT_HEAD
330 test_expect_success 'revert w/dirty tree does not set REVERT_HEAD' '
331 pristine_detach base &&
333 test_must_fail git revert base &&
334 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
335 test_must_fail git rev-parse --verify REVERT_HEAD
338 test_expect_success 'GIT_CHERRY_PICK_HELP does not suppress REVERT_HEAD' '
339 pristine_detach initial &&
341 GIT_CHERRY_PICK_HELP="and then do something else" &&
342 GIT_REVERT_HELP="and then do something else, again" &&
343 export GIT_CHERRY_PICK_HELP GIT_REVERT_HELP &&
344 test_must_fail git revert picked
346 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
347 test_cmp_rev picked REVERT_HEAD
350 test_expect_success 'git reset clears REVERT_HEAD' '
351 pristine_detach initial &&
352 test_must_fail git revert picked &&
354 test_must_fail git rev-parse --verify REVERT_HEAD
357 test_expect_success 'failed commit does not clear REVERT_HEAD' '
358 pristine_detach initial &&
359 test_must_fail git revert picked &&
360 test_must_fail git commit &&
361 test_cmp_rev picked REVERT_HEAD
364 test_expect_success 'revert conflict, diff3 -m style' '
365 pristine_detach initial &&
366 git config merge.conflictstyle diff3 &&
367 cat <<-EOF >expected &&
374 >>>>>>> parent of objid picked
377 test_must_fail git revert picked &&
379 sed "s/[a-f0-9]*\.\.\./objid/" foo >actual &&
380 test_cmp expected actual
383 test_expect_success \
384 'revert conflict, ensure commit.cleanup = scissors places scissors line properly' '
385 pristine_detach initial &&
386 git config commit.cleanup scissors &&
387 cat >expected <<-EOF &&
390 This reverts commit OBJID.
392 # ------------------------ >8 ------------------------
393 # Do not modify or remove the line above.
394 # Everything below it will be ignored.
400 test_must_fail git revert picked &&
402 sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
403 test_i18ncmp expected actual
406 test_expect_success \
407 'revert conflict, ensure cleanup=scissors places scissors line properly' '
408 pristine_detach initial &&
409 git config --unset commit.cleanup &&
410 cat >expected <<-EOF &&
413 This reverts commit OBJID.
415 # ------------------------ >8 ------------------------
416 # Do not modify or remove the line above.
417 # Everything below it will be ignored.
423 test_must_fail git revert --cleanup=scissors picked &&
425 sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
426 test_i18ncmp expected actual
429 test_expect_success 'failed cherry-pick does not forget -s' '
430 pristine_detach initial &&
431 test_must_fail git cherry-pick -s picked &&
432 test_i18ngrep -e "Signed-off-by" .git/MERGE_MSG
435 test_expect_success 'commit after failed cherry-pick does not add duplicated -s' '
436 pristine_detach initial &&
437 test_must_fail git cherry-pick -s picked-signed &&
439 test $(git show -s >tmp && grep -c "Signed-off-by" tmp && rm tmp) = 1
442 test_expect_success 'commit after failed cherry-pick adds -s at the right place' '
443 pristine_detach initial &&
444 test_must_fail git cherry-pick picked &&
448 # Do S-o-b and Conflicts appear in the right order?
449 cat <<-\EOF >expect &&
450 Signed-off-by: C O Mitter <committer@example.com>
453 grep -e "^# Conflicts:" -e '^Signed-off-by' .git/COMMIT_EDITMSG >actual &&
454 test_cmp expect actual &&
456 cat <<-\EOF >expected &&
459 Signed-off-by: C O Mitter <committer@example.com>
462 git show -s --pretty=format:%B >actual &&
463 test_cmp expected actual
466 test_expect_success 'commit --amend -s places the sign-off at the right place' '
467 pristine_detach initial &&
468 test_must_fail git cherry-pick picked &&
470 # emulate old-style conflicts block
471 mv .git/MERGE_MSG .git/MERGE_MSG+ &&
472 sed -e "/^# Conflicts:/,\$s/^# *//" .git/MERGE_MSG+ >.git/MERGE_MSG &&
475 git commit --amend -s &&
477 # Do S-o-b and Conflicts appear in the right order?
478 cat <<-\EOF >expect &&
479 Signed-off-by: C O Mitter <committer@example.com>
482 grep -e "^Conflicts:" -e '^Signed-off-by' .git/COMMIT_EDITMSG >actual &&
483 test_cmp expect actual
486 test_expect_success 'cherry-pick preserves sparse-checkout' '
487 pristine_detach initial &&
488 test_config core.sparseCheckout true &&
490 echo \"/*\" >.git/info/sparse-checkout
491 git read-tree --reset -u HEAD
492 rm .git/info/sparse-checkout" &&
493 echo /unrelated >.git/info/sparse-checkout &&
494 git read-tree --reset -u HEAD &&
495 test_must_fail git cherry-pick -Xours picked>actual &&
496 test_i18ngrep ! "Changes not staged for commit:" actual
499 test_expect_success 'cherry-pick --continue remembers --keep-redundant-commits' '
500 test_when_finished "git cherry-pick --abort || :" &&
501 pristine_detach initial &&
502 test_must_fail git cherry-pick --keep-redundant-commits picked redundant &&
505 git cherry-pick --continue
508 test_expect_success 'cherry-pick --continue remembers --allow-empty and --allow-empty-message' '
509 test_when_finished "git cherry-pick --abort || :" &&
510 pristine_detach initial &&
511 test_must_fail git cherry-pick --allow-empty --allow-empty-message \
515 git cherry-pick --continue