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