]> git.ipfire.org Git - thirdparty/git.git/blob - t/t3507-cherry-pick-conflict.sh
clone: allow "--bare" with "-o"
[thirdparty/git.git] / t / t3507-cherry-pick-conflict.sh
1 #!/bin/sh
2
3 test_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
12 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
13 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
14
15 . ./test-lib.sh
16
17 pristine_detach () {
18 git checkout -f "$1^0" &&
19 git read-tree -u --reset HEAD &&
20 git clean -d -f -f -q -x
21 }
22
23 test_expect_success setup '
24
25 echo unrelated >unrelated &&
26 git add 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 &&
34 git tag empty &&
35 git checkout main &&
36 git config advice.detachedhead false
37
38 '
39
40 test_expect_success 'failed cherry-pick does not advance HEAD' '
41 pristine_detach initial &&
42
43 head=$(git rev-parse HEAD) &&
44 test_must_fail git cherry-pick picked &&
45 newhead=$(git rev-parse HEAD) &&
46
47 test "$head" = "$newhead"
48 '
49
50 test_expect_success 'advice from failed cherry-pick' '
51 pristine_detach initial &&
52
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 them with
57 hint: "git add/rm <pathspec>", then run
58 hint: "git cherry-pick --continue".
59 hint: You can instead skip this commit with "git cherry-pick --skip".
60 hint: To abort and get back to the state before "git cherry-pick",
61 hint: run "git cherry-pick --abort".
62 EOF
63 test_must_fail git cherry-pick picked 2>actual &&
64
65 test_cmp expected actual
66 '
67
68 test_expect_success 'advice from failed cherry-pick --no-commit' "
69 pristine_detach initial &&
70
71 picked=\$(git rev-parse --short picked) &&
72 cat <<-EOF >expected &&
73 error: could not apply \$picked... picked
74 hint: after resolving the conflicts, mark the corrected paths
75 hint: with 'git add <paths>' or 'git rm <paths>'
76 EOF
77 test_must_fail git cherry-pick --no-commit picked 2>actual &&
78
79 test_cmp expected actual
80 "
81
82 test_expect_success 'failed cherry-pick sets CHERRY_PICK_HEAD' '
83 pristine_detach initial &&
84 test_must_fail git cherry-pick picked &&
85 test_cmp_rev picked CHERRY_PICK_HEAD
86 '
87
88 test_expect_success 'successful cherry-pick does not set CHERRY_PICK_HEAD' '
89 pristine_detach initial &&
90 git cherry-pick base &&
91 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
92 '
93
94 test_expect_success 'cherry-pick --no-commit does not set CHERRY_PICK_HEAD' '
95 pristine_detach initial &&
96 git cherry-pick --no-commit base &&
97 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
98 '
99
100 test_expect_success 'cherry-pick w/dirty tree does not set CHERRY_PICK_HEAD' '
101 pristine_detach initial &&
102 echo foo >foo &&
103 test_must_fail git cherry-pick base &&
104 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
105 '
106
107 test_expect_success \
108 'cherry-pick --strategy=resolve w/dirty tree does not set CHERRY_PICK_HEAD' '
109 pristine_detach initial &&
110 echo foo >foo &&
111 test_must_fail git cherry-pick --strategy=resolve base &&
112 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
113 '
114
115 test_expect_success 'GIT_CHERRY_PICK_HELP suppresses CHERRY_PICK_HEAD' '
116 pristine_detach initial &&
117 (
118 GIT_CHERRY_PICK_HELP="and then do something else" &&
119 export GIT_CHERRY_PICK_HELP &&
120 test_must_fail git cherry-pick picked
121 ) &&
122 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
123 '
124
125 test_expect_success 'git reset clears CHERRY_PICK_HEAD' '
126 pristine_detach initial &&
127
128 test_must_fail git cherry-pick picked &&
129 git reset &&
130
131 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
132 '
133
134 test_expect_success 'failed commit does not clear CHERRY_PICK_HEAD' '
135 pristine_detach initial &&
136
137 test_must_fail git cherry-pick picked &&
138 test_must_fail git commit &&
139
140 test_cmp_rev picked CHERRY_PICK_HEAD
141 '
142
143 test_expect_success 'cancelled commit does not clear CHERRY_PICK_HEAD' '
144 pristine_detach initial &&
145
146 test_must_fail git cherry-pick picked &&
147 echo resolved >foo &&
148 git add foo &&
149 git update-index --refresh -q &&
150 test_must_fail git diff-index --exit-code HEAD &&
151 (
152 GIT_EDITOR=false &&
153 export GIT_EDITOR &&
154 test_must_fail git commit
155 ) &&
156
157 test_cmp_rev picked CHERRY_PICK_HEAD
158 '
159
160 test_expect_success 'successful commit clears CHERRY_PICK_HEAD' '
161 pristine_detach initial &&
162
163 test_must_fail git cherry-pick picked &&
164 echo resolved >foo &&
165 git add foo &&
166 git commit &&
167
168 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
169 '
170
171 test_expect_success 'partial commit of cherry-pick fails' '
172 pristine_detach initial &&
173
174 test_must_fail git cherry-pick picked &&
175 echo resolved >foo &&
176 git add foo &&
177 test_must_fail git commit foo 2>err &&
178
179 test_i18ngrep "cannot do a partial commit during a cherry-pick." err
180 '
181
182 test_expect_success 'commit --amend of cherry-pick fails' '
183 pristine_detach initial &&
184
185 test_must_fail git cherry-pick picked &&
186 echo resolved >foo &&
187 git add foo &&
188 test_must_fail git commit --amend 2>err &&
189
190 test_i18ngrep "in the middle of a cherry-pick -- cannot amend." err
191 '
192
193 test_expect_success 'successful final commit clears cherry-pick state' '
194 pristine_detach initial &&
195
196 test_must_fail git cherry-pick base picked-signed &&
197 echo resolved >foo &&
198 test_path_is_file .git/sequencer/todo &&
199 git commit -a &&
200 test_path_is_missing .git/sequencer
201 '
202
203 test_expect_success 'reset after final pick clears cherry-pick state' '
204 pristine_detach initial &&
205
206 test_must_fail git cherry-pick base picked-signed &&
207 echo resolved >foo &&
208 test_path_is_file .git/sequencer/todo &&
209 git reset &&
210 test_path_is_missing .git/sequencer
211 '
212
213 test_expect_success 'failed cherry-pick produces dirty index' '
214 pristine_detach initial &&
215
216 test_must_fail git cherry-pick picked &&
217
218 test_must_fail git update-index --refresh -q &&
219 test_must_fail git diff-index --exit-code HEAD
220 '
221
222 test_expect_success 'failed cherry-pick registers participants in index' '
223 pristine_detach initial &&
224 {
225 git checkout base -- foo &&
226 git ls-files --stage foo &&
227 git checkout initial -- foo &&
228 git ls-files --stage foo &&
229 git checkout picked -- foo &&
230 git ls-files --stage foo
231 } >stages &&
232 sed "
233 1 s/ 0 / 1 /
234 2 s/ 0 / 2 /
235 3 s/ 0 / 3 /
236 " stages >expected &&
237 git read-tree -u --reset HEAD &&
238
239 test_must_fail git cherry-pick picked &&
240 git ls-files --stage --unmerged >actual &&
241
242 test_cmp expected actual
243 '
244
245 test_expect_success \
246 'cherry-pick conflict, ensure commit.cleanup = scissors places scissors line properly' '
247 pristine_detach initial &&
248 git config commit.cleanup scissors &&
249 cat <<-EOF >expected &&
250 picked
251
252 # ------------------------ >8 ------------------------
253 # Do not modify or remove the line above.
254 # Everything below it will be ignored.
255 #
256 # Conflicts:
257 # foo
258 EOF
259
260 test_must_fail git cherry-pick picked &&
261
262 test_cmp expected .git/MERGE_MSG
263 '
264
265 test_expect_success \
266 'cherry-pick conflict, ensure cleanup=scissors places scissors line properly' '
267 pristine_detach initial &&
268 git config --unset commit.cleanup &&
269 cat <<-EOF >expected &&
270 picked
271
272 # ------------------------ >8 ------------------------
273 # Do not modify or remove the line above.
274 # Everything below it will be ignored.
275 #
276 # Conflicts:
277 # foo
278 EOF
279
280 test_must_fail git cherry-pick --cleanup=scissors picked &&
281
282 test_cmp expected .git/MERGE_MSG
283 '
284
285 test_expect_success 'failed cherry-pick describes conflict in work tree' '
286 pristine_detach initial &&
287 cat <<-EOF >expected &&
288 <<<<<<< HEAD
289 a
290 =======
291 c
292 >>>>>>> objid (picked)
293 EOF
294
295 test_must_fail git cherry-pick picked &&
296
297 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
298 test_cmp expected actual
299 '
300
301 test_expect_success 'diff3 -m style' '
302 pristine_detach initial &&
303 git config merge.conflictstyle diff3 &&
304 cat <<-EOF >expected &&
305 <<<<<<< HEAD
306 a
307 ||||||| parent of objid (picked)
308 b
309 =======
310 c
311 >>>>>>> objid (picked)
312 EOF
313
314 test_must_fail git cherry-pick picked &&
315
316 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
317 test_cmp expected actual
318 '
319
320 test_expect_success 'revert also handles conflicts sanely' '
321 git config --unset merge.conflictstyle &&
322 pristine_detach initial &&
323 cat <<-EOF >expected &&
324 <<<<<<< HEAD
325 a
326 =======
327 b
328 >>>>>>> parent of objid (picked)
329 EOF
330 {
331 git checkout picked -- foo &&
332 git ls-files --stage foo &&
333 git checkout initial -- foo &&
334 git ls-files --stage foo &&
335 git checkout base -- foo &&
336 git ls-files --stage foo
337 } >stages &&
338 sed "
339 1 s/ 0 / 1 /
340 2 s/ 0 / 2 /
341 3 s/ 0 / 3 /
342 " stages >expected-stages &&
343 git read-tree -u --reset HEAD &&
344
345 head=$(git rev-parse HEAD) &&
346 test_must_fail git revert picked &&
347 newhead=$(git rev-parse HEAD) &&
348 git ls-files --stage --unmerged >actual-stages &&
349
350 test "$head" = "$newhead" &&
351 test_must_fail git update-index --refresh -q &&
352 test_must_fail git diff-index --exit-code HEAD &&
353 test_cmp expected-stages actual-stages &&
354 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
355 test_cmp expected actual
356 '
357
358 test_expect_success 'failed revert sets REVERT_HEAD' '
359 pristine_detach initial &&
360 test_must_fail git revert picked &&
361 test_cmp_rev picked REVERT_HEAD
362 '
363
364 test_expect_success 'successful revert does not set REVERT_HEAD' '
365 pristine_detach base &&
366 git revert base &&
367 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
368 test_must_fail git rev-parse --verify REVERT_HEAD
369 '
370
371 test_expect_success 'revert --no-commit sets REVERT_HEAD' '
372 pristine_detach base &&
373 git revert --no-commit base &&
374 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
375 test_cmp_rev base REVERT_HEAD
376 '
377
378 test_expect_success 'revert w/dirty tree does not set REVERT_HEAD' '
379 pristine_detach base &&
380 echo foo >foo &&
381 test_must_fail git revert base &&
382 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
383 test_must_fail git rev-parse --verify REVERT_HEAD
384 '
385
386 test_expect_success 'GIT_CHERRY_PICK_HELP does not suppress REVERT_HEAD' '
387 pristine_detach initial &&
388 (
389 GIT_CHERRY_PICK_HELP="and then do something else" &&
390 GIT_REVERT_HELP="and then do something else, again" &&
391 export GIT_CHERRY_PICK_HELP GIT_REVERT_HELP &&
392 test_must_fail git revert picked
393 ) &&
394 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
395 test_cmp_rev picked REVERT_HEAD
396 '
397
398 test_expect_success 'git reset clears REVERT_HEAD' '
399 pristine_detach initial &&
400 test_must_fail git revert picked &&
401 git reset &&
402 test_must_fail git rev-parse --verify REVERT_HEAD
403 '
404
405 test_expect_success 'failed commit does not clear REVERT_HEAD' '
406 pristine_detach initial &&
407 test_must_fail git revert picked &&
408 test_must_fail git commit &&
409 test_cmp_rev picked REVERT_HEAD
410 '
411
412 test_expect_success 'successful final commit clears revert state' '
413 pristine_detach picked-signed &&
414
415 test_must_fail git revert picked-signed base &&
416 echo resolved >foo &&
417 test_path_is_file .git/sequencer/todo &&
418 git commit -a &&
419 test_path_is_missing .git/sequencer
420 '
421
422 test_expect_success 'reset after final pick clears revert state' '
423 pristine_detach picked-signed &&
424
425 test_must_fail git revert picked-signed base &&
426 echo resolved >foo &&
427 test_path_is_file .git/sequencer/todo &&
428 git reset &&
429 test_path_is_missing .git/sequencer
430 '
431
432 test_expect_success 'revert conflict, diff3 -m style' '
433 pristine_detach initial &&
434 git config merge.conflictstyle diff3 &&
435 cat <<-EOF >expected &&
436 <<<<<<< HEAD
437 a
438 ||||||| objid (picked)
439 c
440 =======
441 b
442 >>>>>>> parent of objid (picked)
443 EOF
444
445 test_must_fail git revert picked &&
446
447 sed "s/[a-f0-9]* (/objid (/" foo >actual &&
448 test_cmp expected actual
449 '
450
451 test_expect_success \
452 'revert conflict, ensure commit.cleanup = scissors places scissors line properly' '
453 pristine_detach initial &&
454 git config commit.cleanup scissors &&
455 cat >expected <<-EOF &&
456 Revert "picked"
457
458 This reverts commit OBJID.
459
460 # ------------------------ >8 ------------------------
461 # Do not modify or remove the line above.
462 # Everything below it will be ignored.
463 #
464 # Conflicts:
465 # foo
466 EOF
467
468 test_must_fail git revert picked &&
469
470 sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
471 test_cmp expected actual
472 '
473
474 test_expect_success \
475 'revert conflict, ensure cleanup=scissors places scissors line properly' '
476 pristine_detach initial &&
477 git config --unset commit.cleanup &&
478 cat >expected <<-EOF &&
479 Revert "picked"
480
481 This reverts commit OBJID.
482
483 # ------------------------ >8 ------------------------
484 # Do not modify or remove the line above.
485 # Everything below it will be ignored.
486 #
487 # Conflicts:
488 # foo
489 EOF
490
491 test_must_fail git revert --cleanup=scissors picked &&
492
493 sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
494 test_cmp expected actual
495 '
496
497 test_expect_success 'failed cherry-pick does not forget -s' '
498 pristine_detach initial &&
499 test_must_fail git cherry-pick -s picked &&
500 test_i18ngrep -e "Signed-off-by" .git/MERGE_MSG
501 '
502
503 test_expect_success 'commit after failed cherry-pick does not add duplicated -s' '
504 pristine_detach initial &&
505 test_must_fail git cherry-pick -s picked-signed &&
506 git commit -a -s &&
507 test $(git show -s >tmp && grep -c "Signed-off-by" tmp && rm tmp) = 1
508 '
509
510 test_expect_success 'commit after failed cherry-pick adds -s at the right place' '
511 pristine_detach initial &&
512 test_must_fail git cherry-pick picked &&
513
514 git commit -a -s &&
515
516 # Do S-o-b and Conflicts appear in the right order?
517 cat <<-\EOF >expect &&
518 Signed-off-by: C O Mitter <committer@example.com>
519 # Conflicts:
520 EOF
521 grep -e "^# Conflicts:" -e "^Signed-off-by" .git/COMMIT_EDITMSG >actual &&
522 test_cmp expect actual &&
523
524 cat <<-\EOF >expected &&
525 picked
526
527 Signed-off-by: C O Mitter <committer@example.com>
528 EOF
529
530 git show -s --pretty=format:%B >actual &&
531 test_cmp expected actual
532 '
533
534 test_expect_success 'commit --amend -s places the sign-off at the right place' '
535 pristine_detach initial &&
536 test_must_fail git cherry-pick picked &&
537
538 # emulate old-style conflicts block
539 mv .git/MERGE_MSG .git/MERGE_MSG+ &&
540 sed -e "/^# Conflicts:/,\$s/^# *//" .git/MERGE_MSG+ >.git/MERGE_MSG &&
541
542 git commit -a &&
543 git commit --amend -s &&
544
545 # Do S-o-b and Conflicts appear in the right order?
546 cat <<-\EOF >expect &&
547 Signed-off-by: C O Mitter <committer@example.com>
548 Conflicts:
549 EOF
550 grep -e "^Conflicts:" -e "^Signed-off-by" .git/COMMIT_EDITMSG >actual &&
551 test_cmp expect actual
552 '
553
554 test_expect_success 'cherry-pick preserves sparse-checkout' '
555 pristine_detach initial &&
556 test_config core.sparseCheckout true &&
557 test_when_finished "
558 echo \"/*\" >.git/info/sparse-checkout
559 git read-tree --reset -u HEAD
560 rm .git/info/sparse-checkout" &&
561 echo /unrelated >.git/info/sparse-checkout &&
562 git read-tree --reset -u HEAD &&
563 test_must_fail git cherry-pick -Xours picked>actual &&
564 test_i18ngrep ! "Changes not staged for commit:" actual
565 '
566
567 test_expect_success 'cherry-pick --continue remembers --keep-redundant-commits' '
568 test_when_finished "git cherry-pick --abort || :" &&
569 pristine_detach initial &&
570 test_must_fail git cherry-pick --keep-redundant-commits picked redundant &&
571 echo c >foo &&
572 git add foo &&
573 git cherry-pick --continue
574 '
575
576 test_expect_success 'cherry-pick --continue remembers --allow-empty and --allow-empty-message' '
577 test_when_finished "git cherry-pick --abort || :" &&
578 pristine_detach initial &&
579 test_must_fail git cherry-pick --allow-empty --allow-empty-message \
580 picked empty &&
581 echo c >foo &&
582 git add foo &&
583 git cherry-pick --continue
584 '
585
586 test_done