]> git.ipfire.org Git - thirdparty/git.git/blame - t/t3507-cherry-pick-conflict.sh
hashmap: use *_entry APIs for iteration
[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'
b07d9bfd
PW
164test_expect_success 'successful final commit clears cherry-pick state' '
165 pristine_detach initial &&
166
167 test_must_fail git cherry-pick base picked-signed &&
168 echo resolved >foo &&
169 test_path_is_file .git/sequencer/todo &&
170 git commit -a &&
171 test_must_fail test_path_exists .git/sequencer
172'
173
174test_expect_success 'reset after final pick clears cherry-pick state' '
175 pristine_detach initial &&
176
177 test_must_fail git cherry-pick base picked-signed &&
178 echo resolved >foo &&
179 test_path_is_file .git/sequencer/todo &&
180 git reset &&
181 test_must_fail test_path_exists .git/sequencer
182'
d7e5c0cb 183
6a843348 184test_expect_success 'failed cherry-pick produces dirty index' '
2161da10 185 pristine_detach initial &&
6a843348
JN
186
187 test_must_fail git cherry-pick picked &&
188
189 test_must_fail git update-index --refresh -q &&
190 test_must_fail git diff-index --exit-code HEAD
191'
192
193test_expect_success 'failed cherry-pick registers participants in index' '
2161da10 194 pristine_detach initial &&
6a843348
JN
195 {
196 git checkout base -- foo &&
197 git ls-files --stage foo &&
198 git checkout initial -- foo &&
199 git ls-files --stage foo &&
200 git checkout picked -- foo &&
201 git ls-files --stage foo
5caab8de 202 } >stages &&
6a843348
JN
203 sed "
204 1 s/ 0 / 1 /
205 2 s/ 0 / 2 /
206 3 s/ 0 / 3 /
5caab8de 207 " stages >expected &&
2161da10 208 git read-tree -u --reset HEAD &&
6a843348
JN
209
210 test_must_fail git cherry-pick picked &&
5caab8de 211 git ls-files --stage --unmerged >actual &&
6a843348
JN
212
213 test_cmp expected actual
214'
215
1a2b985f
DL
216test_expect_success \
217 'cherry-pick conflict, ensure commit.cleanup = scissors places scissors line properly' '
218 pristine_detach initial &&
219 git config commit.cleanup scissors &&
220 cat <<-EOF >expected &&
221 picked
222
223 # ------------------------ >8 ------------------------
224 # Do not modify or remove the line above.
225 # Everything below it will be ignored.
226 #
227 # Conflicts:
228 # foo
229 EOF
230
231 test_must_fail git cherry-pick picked &&
232
233 test_i18ncmp expected .git/MERGE_MSG
234'
235
236test_expect_success \
237 'cherry-pick conflict, ensure cleanup=scissors places scissors line properly' '
238 pristine_detach initial &&
239 git config --unset commit.cleanup &&
240 cat <<-EOF >expected &&
241 picked
242
243 # ------------------------ >8 ------------------------
244 # Do not modify or remove the line above.
245 # Everything below it will be ignored.
246 #
247 # Conflicts:
248 # foo
249 EOF
250
251 test_must_fail git cherry-pick --cleanup=scissors picked &&
252
253 test_i18ncmp expected .git/MERGE_MSG
254'
255
6a843348 256test_expect_success 'failed cherry-pick describes conflict in work tree' '
2161da10 257 pristine_detach initial &&
5caab8de 258 cat <<-EOF >expected &&
6a843348
JN
259 <<<<<<< HEAD
260 a
261 =======
262 c
263 >>>>>>> objid picked
264 EOF
265
6a843348
JN
266 test_must_fail git cherry-pick picked &&
267
5caab8de 268 sed "s/[a-f0-9]*\.\.\./objid/" foo >actual &&
6a843348
JN
269 test_cmp expected actual
270'
271
272test_expect_success 'diff3 -m style' '
2161da10 273 pristine_detach initial &&
6a843348 274 git config merge.conflictstyle diff3 &&
5caab8de 275 cat <<-EOF >expected &&
6a843348
JN
276 <<<<<<< HEAD
277 a
bf975d37 278 ||||||| parent of objid picked
6a843348
JN
279 b
280 =======
281 c
282 >>>>>>> objid picked
283 EOF
284
6a843348
JN
285 test_must_fail git cherry-pick picked &&
286
5caab8de 287 sed "s/[a-f0-9]*\.\.\./objid/" foo >actual &&
6a843348
JN
288 test_cmp expected actual
289'
290
291test_expect_success 'revert also handles conflicts sanely' '
6a843348 292 git config --unset merge.conflictstyle &&
2161da10 293 pristine_detach initial &&
5caab8de 294 cat <<-EOF >expected &&
6a843348
JN
295 <<<<<<< HEAD
296 a
297 =======
298 b
d6856540 299 >>>>>>> parent of objid picked
6a843348
JN
300 EOF
301 {
302 git checkout picked -- foo &&
303 git ls-files --stage foo &&
304 git checkout initial -- foo &&
305 git ls-files --stage foo &&
306 git checkout base -- foo &&
307 git ls-files --stage foo
5caab8de 308 } >stages &&
6a843348
JN
309 sed "
310 1 s/ 0 / 1 /
311 2 s/ 0 / 2 /
312 3 s/ 0 / 3 /
5caab8de 313 " stages >expected-stages &&
2161da10 314 git read-tree -u --reset HEAD &&
6a843348
JN
315
316 head=$(git rev-parse HEAD) &&
317 test_must_fail git revert picked &&
318 newhead=$(git rev-parse HEAD) &&
5caab8de 319 git ls-files --stage --unmerged >actual-stages &&
6a843348
JN
320
321 test "$head" = "$newhead" &&
322 test_must_fail git update-index --refresh -q &&
323 test_must_fail git diff-index --exit-code HEAD &&
324 test_cmp expected-stages actual-stages &&
5caab8de 325 sed "s/[a-f0-9]*\.\.\./objid/" foo >actual &&
6a843348
JN
326 test_cmp expected actual
327'
328
82433cdf
JN
329test_expect_success 'failed revert sets REVERT_HEAD' '
330 pristine_detach initial &&
331 test_must_fail git revert picked &&
332 test_cmp_rev picked REVERT_HEAD
333'
334
335test_expect_success 'successful revert does not set REVERT_HEAD' '
336 pristine_detach base &&
337 git revert base &&
338 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
339 test_must_fail git rev-parse --verify REVERT_HEAD
340'
341
342test_expect_success 'revert --no-commit sets REVERT_HEAD' '
343 pristine_detach base &&
344 git revert --no-commit base &&
345 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
346 test_cmp_rev base REVERT_HEAD
347'
348
349test_expect_success 'revert w/dirty tree does not set REVERT_HEAD' '
350 pristine_detach base &&
5caab8de 351 echo foo >foo &&
82433cdf
JN
352 test_must_fail git revert base &&
353 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
354 test_must_fail git rev-parse --verify REVERT_HEAD
355'
356
357test_expect_success 'GIT_CHERRY_PICK_HELP does not suppress REVERT_HEAD' '
358 pristine_detach initial &&
359 (
360 GIT_CHERRY_PICK_HELP="and then do something else" &&
361 GIT_REVERT_HELP="and then do something else, again" &&
362 export GIT_CHERRY_PICK_HELP GIT_REVERT_HELP &&
363 test_must_fail git revert picked
364 ) &&
365 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
366 test_cmp_rev picked REVERT_HEAD
367'
368
369test_expect_success 'git reset clears REVERT_HEAD' '
370 pristine_detach initial &&
371 test_must_fail git revert picked &&
372 git reset &&
373 test_must_fail git rev-parse --verify REVERT_HEAD
374'
375
376test_expect_success 'failed commit does not clear REVERT_HEAD' '
377 pristine_detach initial &&
378 test_must_fail git revert picked &&
379 test_must_fail git commit &&
380 test_cmp_rev picked REVERT_HEAD
381'
382
b07d9bfd
PW
383test_expect_success 'successful final commit clears revert state' '
384 pristine_detach picked-signed &&
385
386 test_must_fail git revert picked-signed base &&
387 echo resolved >foo &&
388 test_path_is_file .git/sequencer/todo &&
389 git commit -a &&
390 test_must_fail test_path_exists .git/sequencer
391'
392
393test_expect_success 'reset after final pick clears revert state' '
394 pristine_detach picked-signed &&
395
396 test_must_fail git revert picked-signed base &&
397 echo resolved >foo &&
398 test_path_is_file .git/sequencer/todo &&
399 git reset &&
400 test_must_fail test_path_exists .git/sequencer
401'
402
6a843348 403test_expect_success 'revert conflict, diff3 -m style' '
2161da10 404 pristine_detach initial &&
6a843348 405 git config merge.conflictstyle diff3 &&
5caab8de 406 cat <<-EOF >expected &&
6a843348
JN
407 <<<<<<< HEAD
408 a
bf975d37 409 ||||||| objid picked
6a843348
JN
410 c
411 =======
412 b
d6856540 413 >>>>>>> parent of objid picked
6a843348
JN
414 EOF
415
6a843348
JN
416 test_must_fail git revert picked &&
417
5caab8de 418 sed "s/[a-f0-9]*\.\.\./objid/" foo >actual &&
6a843348
JN
419 test_cmp expected actual
420'
421
1a2b985f
DL
422test_expect_success \
423 'revert conflict, ensure commit.cleanup = scissors places scissors line properly' '
424 pristine_detach initial &&
425 git config commit.cleanup scissors &&
426 cat >expected <<-EOF &&
427 Revert "picked"
428
429 This reverts commit OBJID.
430
431 # ------------------------ >8 ------------------------
432 # Do not modify or remove the line above.
433 # Everything below it will be ignored.
434 #
435 # Conflicts:
436 # foo
437 EOF
438
439 test_must_fail git revert picked &&
440
441 sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
442 test_i18ncmp expected actual
443'
444
445test_expect_success \
446 'revert conflict, ensure cleanup=scissors places scissors line properly' '
447 pristine_detach initial &&
448 git config --unset commit.cleanup &&
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 --cleanup=scissors picked &&
463
464 sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
465 test_i18ncmp expected actual
466'
467
5ed75e2a
MV
468test_expect_success 'failed cherry-pick does not forget -s' '
469 pristine_detach initial &&
470 test_must_fail git cherry-pick -s picked &&
471 test_i18ngrep -e "Signed-off-by" .git/MERGE_MSG
472'
473
474test_expect_success 'commit after failed cherry-pick does not add duplicated -s' '
475 pristine_detach initial &&
476 test_must_fail git cherry-pick -s picked-signed &&
477 git commit -a -s &&
5caab8de 478 test $(git show -s >tmp && grep -c "Signed-off-by" tmp && rm tmp) = 1
5ed75e2a
MV
479'
480
481test_expect_success 'commit after failed cherry-pick adds -s at the right place' '
482 pristine_detach initial &&
483 test_must_fail git cherry-pick picked &&
261f315b 484
5ed75e2a 485 git commit -a -s &&
5ed75e2a 486
261f315b
JH
487 # Do S-o-b and Conflicts appear in the right order?
488 cat <<-\EOF >expect &&
489 Signed-off-by: C O Mitter <committer@example.com>
490 # Conflicts:
491 EOF
5caab8de 492 grep -e "^# Conflicts:" -e '^Signed-off-by' .git/COMMIT_EDITMSG >actual &&
261f315b
JH
493 test_cmp expect actual &&
494
495 cat <<-\EOF >expected &&
496 picked
5ed75e2a 497
261f315b
JH
498 Signed-off-by: C O Mitter <committer@example.com>
499 EOF
5ed75e2a 500
261f315b 501 git show -s --pretty=format:%B >actual &&
5ed75e2a
MV
502 test_cmp expected actual
503'
504
261f315b
JH
505test_expect_success 'commit --amend -s places the sign-off at the right place' '
506 pristine_detach initial &&
507 test_must_fail git cherry-pick picked &&
508
509 # emulate old-style conflicts block
510 mv .git/MERGE_MSG .git/MERGE_MSG+ &&
5caab8de 511 sed -e "/^# Conflicts:/,\$s/^# *//" .git/MERGE_MSG+ >.git/MERGE_MSG &&
261f315b
JH
512
513 git commit -a &&
514 git commit --amend -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
5caab8de 521 grep -e "^Conflicts:" -e '^Signed-off-by' .git/COMMIT_EDITMSG >actual &&
261f315b
JH
522 test_cmp expect actual
523'
524
2b75fb60 525test_expect_success 'cherry-pick preserves sparse-checkout' '
92203e64
BP
526 pristine_detach initial &&
527 test_config core.sparseCheckout true &&
528 test_when_finished "
529 echo \"/*\" >.git/info/sparse-checkout
530 git read-tree --reset -u HEAD
531 rm .git/info/sparse-checkout" &&
532 echo /unrelated >.git/info/sparse-checkout &&
533 git read-tree --reset -u HEAD &&
534 test_must_fail git cherry-pick -Xours picked>actual &&
535 test_i18ngrep ! "Changes not staged for commit:" actual
536'
537
6860ce5d 538test_expect_success 'cherry-pick --continue remembers --keep-redundant-commits' '
36b0503a
PW
539 test_when_finished "git cherry-pick --abort || :" &&
540 pristine_detach initial &&
541 test_must_fail git cherry-pick --keep-redundant-commits picked redundant &&
542 echo c >foo &&
543 git add foo &&
544 git cherry-pick --continue
545'
546
6860ce5d 547test_expect_success 'cherry-pick --continue remembers --allow-empty and --allow-empty-message' '
36b0503a
PW
548 test_when_finished "git cherry-pick --abort || :" &&
549 pristine_detach initial &&
550 test_must_fail git cherry-pick --allow-empty --allow-empty-message \
551 picked empty &&
552 echo c >foo &&
553 git add foo &&
554 git cherry-pick --continue
555'
556
6a843348 557test_done