]> git.ipfire.org Git - thirdparty/git.git/blame - t/t3507-cherry-pick-conflict.sh
Merge branch 'jk/clone-allow-bare-and-o-together'
[thirdparty/git.git] / t / t3507-cherry-pick-conflict.sh
CommitLineData
6a843348
JN
1#!/bin/sh
2
3test_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
cbc75a12 12GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
334afbc7
JS
13export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
14
ead74601 15TEST_CREATE_REPO_NO_TEMPLATE=1
6a843348
JN
16. ./test-lib.sh
17
2161da10
JN
18pristine_detach () {
19 git checkout -f "$1^0" &&
20 git read-tree -u --reset HEAD &&
21 git clean -d -f -f -q -x
22}
23
6a843348
JN
24test_expect_success setup '
25
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 &&
5ed75e2a 31 test_commit --signoff picked-signed foo d &&
36b0503a
PW
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 &&
cbc75a12 36 git checkout main &&
6a843348
JN
37 git config advice.detachedhead false
38
39'
40
41test_expect_success 'failed cherry-pick does not advance HEAD' '
2161da10 42 pristine_detach initial &&
6a843348
JN
43
44 head=$(git rev-parse HEAD) &&
45 test_must_fail git cherry-pick picked &&
46 newhead=$(git rev-parse HEAD) &&
47
48 test "$head" = "$newhead"
49'
50
f172556b 51test_expect_success 'advice from failed cherry-pick' '
2161da10 52 pristine_detach initial &&
314eeb6e 53
f172556b 54 picked=$(git rev-parse --short picked) &&
314eeb6e 55 cat <<-EOF >expected &&
f172556b
ZH
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".
314eeb6e
JN
63 EOF
64 test_must_fail git cherry-pick picked 2>actual &&
65
1108cea7 66 test_cmp expected actual
f172556b 67'
314eeb6e 68
ed727b19
PH
69test_expect_success 'advice from failed cherry-pick --no-commit' "
70 pristine_detach initial &&
71
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 &&
79
1108cea7 80 test_cmp expected actual
ed727b19
PH
81"
82
d7e5c0cb
JS
83test_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
87'
88
89test_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
93'
94
95test_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
99'
9fa8aecd
JS
100
101test_expect_success 'cherry-pick w/dirty tree does not set CHERRY_PICK_HEAD' '
102 pristine_detach initial &&
5caab8de 103 echo foo >foo &&
9fa8aecd
JS
104 test_must_fail git cherry-pick base &&
105 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
106'
107
108test_expect_success \
109 'cherry-pick --strategy=resolve w/dirty tree does not set CHERRY_PICK_HEAD' '
110 pristine_detach initial &&
5caab8de 111 echo foo >foo &&
9fa8aecd
JS
112 test_must_fail git cherry-pick --strategy=resolve base &&
113 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
114'
d7e5c0cb
JS
115
116test_expect_success 'GIT_CHERRY_PICK_HELP suppresses CHERRY_PICK_HEAD' '
117 pristine_detach initial &&
118 (
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
124'
125
126test_expect_success 'git reset clears CHERRY_PICK_HEAD' '
127 pristine_detach initial &&
128
129 test_must_fail git cherry-pick picked &&
130 git reset &&
131
132 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
133'
134
135test_expect_success 'failed commit does not clear CHERRY_PICK_HEAD' '
136 pristine_detach initial &&
137
138 test_must_fail git cherry-pick picked &&
139 test_must_fail git commit &&
140
141 test_cmp_rev picked CHERRY_PICK_HEAD
142'
143
144test_expect_success 'cancelled commit does not clear CHERRY_PICK_HEAD' '
145 pristine_detach initial &&
146
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 &&
152 (
153 GIT_EDITOR=false &&
154 export GIT_EDITOR &&
155 test_must_fail git commit
156 ) &&
157
158 test_cmp_rev picked CHERRY_PICK_HEAD
159'
160
161test_expect_success 'successful commit clears CHERRY_PICK_HEAD' '
162 pristine_detach initial &&
163
164 test_must_fail git cherry-pick picked &&
165 echo resolved >foo &&
166 git add foo &&
167 git commit &&
168
169 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
170'
f028d661
PW
171
172test_expect_success 'partial commit of cherry-pick fails' '
173 pristine_detach initial &&
174
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 &&
179
180 test_i18ngrep "cannot do a partial commit during a cherry-pick." err
181'
182
183test_expect_success 'commit --amend of cherry-pick fails' '
184 pristine_detach initial &&
185
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 &&
190
191 test_i18ngrep "in the middle of a cherry-pick -- cannot amend." err
192'
193
b07d9bfd
PW
194test_expect_success 'successful final commit clears cherry-pick state' '
195 pristine_detach initial &&
196
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 &&
a8c663cf 201 test_path_is_missing .git/sequencer
b07d9bfd
PW
202'
203
204test_expect_success 'reset after final pick clears cherry-pick state' '
205 pristine_detach initial &&
206
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 &&
a8c663cf 211 test_path_is_missing .git/sequencer
b07d9bfd 212'
d7e5c0cb 213
6a843348 214test_expect_success 'failed cherry-pick produces dirty index' '
2161da10 215 pristine_detach initial &&
6a843348
JN
216
217 test_must_fail git cherry-pick picked &&
218
219 test_must_fail git update-index --refresh -q &&
220 test_must_fail git diff-index --exit-code HEAD
221'
222
223test_expect_success 'failed cherry-pick registers participants in index' '
2161da10 224 pristine_detach initial &&
6a843348
JN
225 {
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
5caab8de 232 } >stages &&
6a843348
JN
233 sed "
234 1 s/ 0 / 1 /
235 2 s/ 0 / 2 /
236 3 s/ 0 / 3 /
5caab8de 237 " stages >expected &&
2161da10 238 git read-tree -u --reset HEAD &&
6a843348
JN
239
240 test_must_fail git cherry-pick picked &&
5caab8de 241 git ls-files --stage --unmerged >actual &&
6a843348
JN
242
243 test_cmp expected actual
244'
245
1a2b985f
DL
246test_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
252
253 # ------------------------ >8 ------------------------
254 # Do not modify or remove the line above.
255 # Everything below it will be ignored.
256 #
257 # Conflicts:
258 # foo
259 EOF
260
261 test_must_fail git cherry-pick picked &&
262
1108cea7 263 test_cmp expected .git/MERGE_MSG
1a2b985f
DL
264'
265
266test_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
272
273 # ------------------------ >8 ------------------------
274 # Do not modify or remove the line above.
275 # Everything below it will be ignored.
276 #
277 # Conflicts:
278 # foo
279 EOF
280
281 test_must_fail git cherry-pick --cleanup=scissors picked &&
282
1108cea7 283 test_cmp expected .git/MERGE_MSG
1a2b985f
DL
284'
285
6a843348 286test_expect_success 'failed cherry-pick describes conflict in work tree' '
2161da10 287 pristine_detach initial &&
5caab8de 288 cat <<-EOF >expected &&
6a843348
JN
289 <<<<<<< HEAD
290 a
291 =======
292 c
7d056dea 293 >>>>>>> objid (picked)
6a843348
JN
294 EOF
295
6a843348
JN
296 test_must_fail git cherry-pick picked &&
297
7d056dea 298 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
6a843348
JN
299 test_cmp expected actual
300'
301
302test_expect_success 'diff3 -m style' '
2161da10 303 pristine_detach initial &&
6a843348 304 git config merge.conflictstyle diff3 &&
5caab8de 305 cat <<-EOF >expected &&
6a843348
JN
306 <<<<<<< HEAD
307 a
7d056dea 308 ||||||| parent of objid (picked)
6a843348
JN
309 b
310 =======
311 c
7d056dea 312 >>>>>>> objid (picked)
6a843348
JN
313 EOF
314
6a843348
JN
315 test_must_fail git cherry-pick picked &&
316
7d056dea 317 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
6a843348
JN
318 test_cmp expected actual
319'
320
321test_expect_success 'revert also handles conflicts sanely' '
6a843348 322 git config --unset merge.conflictstyle &&
2161da10 323 pristine_detach initial &&
5caab8de 324 cat <<-EOF >expected &&
6a843348
JN
325 <<<<<<< HEAD
326 a
327 =======
328 b
7d056dea 329 >>>>>>> parent of objid (picked)
6a843348
JN
330 EOF
331 {
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
5caab8de 338 } >stages &&
6a843348
JN
339 sed "
340 1 s/ 0 / 1 /
341 2 s/ 0 / 2 /
342 3 s/ 0 / 3 /
5caab8de 343 " stages >expected-stages &&
2161da10 344 git read-tree -u --reset HEAD &&
6a843348
JN
345
346 head=$(git rev-parse HEAD) &&
347 test_must_fail git revert picked &&
348 newhead=$(git rev-parse HEAD) &&
5caab8de 349 git ls-files --stage --unmerged >actual-stages &&
6a843348
JN
350
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 &&
7d056dea 355 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
6a843348
JN
356 test_cmp expected actual
357'
358
82433cdf
JN
359test_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
363'
364
365test_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
370'
371
372test_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
377'
378
379test_expect_success 'revert w/dirty tree does not set REVERT_HEAD' '
380 pristine_detach base &&
5caab8de 381 echo foo >foo &&
82433cdf
JN
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
385'
386
387test_expect_success 'GIT_CHERRY_PICK_HELP does not suppress REVERT_HEAD' '
388 pristine_detach initial &&
389 (
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
397'
398
399test_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
404'
405
406test_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
411'
412
b07d9bfd 413test_expect_success 'successful final commit clears revert state' '
2def7f01 414 pristine_detach picked-signed &&
b07d9bfd 415
2def7f01
DL
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 &&
a8c663cf 420 test_path_is_missing .git/sequencer
b07d9bfd
PW
421'
422
423test_expect_success 'reset after final pick clears revert state' '
2def7f01 424 pristine_detach picked-signed &&
b07d9bfd 425
2def7f01
DL
426 test_must_fail git revert picked-signed base &&
427 echo resolved >foo &&
428 test_path_is_file .git/sequencer/todo &&
429 git reset &&
a8c663cf 430 test_path_is_missing .git/sequencer
b07d9bfd
PW
431'
432
6a843348 433test_expect_success 'revert conflict, diff3 -m style' '
2161da10 434 pristine_detach initial &&
6a843348 435 git config merge.conflictstyle diff3 &&
5caab8de 436 cat <<-EOF >expected &&
6a843348
JN
437 <<<<<<< HEAD
438 a
7d056dea 439 ||||||| objid (picked)
6a843348
JN
440 c
441 =======
442 b
7d056dea 443 >>>>>>> parent of objid (picked)
6a843348
JN
444 EOF
445
6a843348
JN
446 test_must_fail git revert picked &&
447
7d056dea 448 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
6a843348
JN
449 test_cmp expected actual
450'
451
1a2b985f
DL
452test_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"
458
459 This reverts commit OBJID.
460
461 # ------------------------ >8 ------------------------
462 # Do not modify or remove the line above.
463 # Everything below it will be ignored.
464 #
465 # Conflicts:
466 # foo
467 EOF
468
469 test_must_fail git revert picked &&
470
471 sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
1108cea7 472 test_cmp expected actual
1a2b985f
DL
473'
474
475test_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"
481
482 This reverts commit OBJID.
483
484 # ------------------------ >8 ------------------------
485 # Do not modify or remove the line above.
486 # Everything below it will be ignored.
487 #
488 # Conflicts:
489 # foo
490 EOF
491
492 test_must_fail git revert --cleanup=scissors picked &&
493
494 sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
1108cea7 495 test_cmp expected actual
1a2b985f
DL
496'
497
5ed75e2a
MV
498test_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
502'
503
504test_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 &&
5caab8de 508 test $(git show -s >tmp && grep -c "Signed-off-by" tmp && rm tmp) = 1
5ed75e2a
MV
509'
510
511test_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 &&
261f315b 514
5ed75e2a 515 git commit -a -s &&
5ed75e2a 516
261f315b
JH
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:
521 EOF
c76b84a1 522 grep -e "^# Conflicts:" -e "^Signed-off-by" .git/COMMIT_EDITMSG >actual &&
261f315b
JH
523 test_cmp expect actual &&
524
525 cat <<-\EOF >expected &&
526 picked
5ed75e2a 527
261f315b
JH
528 Signed-off-by: C O Mitter <committer@example.com>
529 EOF
5ed75e2a 530
261f315b 531 git show -s --pretty=format:%B >actual &&
5ed75e2a
MV
532 test_cmp expected actual
533'
534
261f315b
JH
535test_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 &&
538
539 # emulate old-style conflicts block
540 mv .git/MERGE_MSG .git/MERGE_MSG+ &&
5caab8de 541 sed -e "/^# Conflicts:/,\$s/^# *//" .git/MERGE_MSG+ >.git/MERGE_MSG &&
261f315b
JH
542
543 git commit -a &&
544 git commit --amend -s &&
545
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:
550 EOF
c76b84a1 551 grep -e "^Conflicts:" -e "^Signed-off-by" .git/COMMIT_EDITMSG >actual &&
261f315b
JH
552 test_cmp expect actual
553'
554
2b75fb60 555test_expect_success 'cherry-pick preserves sparse-checkout' '
92203e64
BP
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" &&
ead74601 562 mkdir .git/info &&
92203e64
BP
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
567'
568
6860ce5d 569test_expect_success 'cherry-pick --continue remembers --keep-redundant-commits' '
36b0503a
PW
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
576'
577
6860ce5d 578test_expect_success 'cherry-pick --continue remembers --allow-empty and --allow-empty-message' '
36b0503a
PW
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
586'
587
6a843348 588test_done