]>
Commit | Line | Data |
---|---|---|
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 | . ./test-lib.sh | |
13 | ||
14 | pristine_detach () { | |
15 | git checkout -f "$1^0" && | |
16 | git read-tree -u --reset HEAD && | |
17 | git clean -d -f -f -q -x | |
18 | } | |
19 | ||
20 | test_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 && | |
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 && | |
31 | git tag empty && | |
32 | git checkout master && | |
33 | git config advice.detachedhead false | |
34 | ||
35 | ' | |
36 | ||
37 | test_expect_success 'failed cherry-pick does not advance HEAD' ' | |
38 | pristine_detach initial && | |
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 | ||
47 | test_expect_success 'advice from failed cherry-pick' " | |
48 | pristine_detach initial && | |
49 | ||
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' | |
56 | EOF | |
57 | test_must_fail git cherry-pick picked 2>actual && | |
58 | ||
59 | test_i18ncmp expected actual | |
60 | " | |
61 | ||
62 | test_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 | ||
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 | |
80 | ' | |
81 | ||
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 | |
86 | ' | |
87 | ||
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 | |
92 | ' | |
93 | ||
94 | test_expect_success 'cherry-pick w/dirty tree does not set CHERRY_PICK_HEAD' ' | |
95 | pristine_detach initial && | |
96 | echo foo >foo && | |
97 | test_must_fail git cherry-pick base && | |
98 | test_must_fail git rev-parse --verify CHERRY_PICK_HEAD | |
99 | ' | |
100 | ||
101 | test_expect_success \ | |
102 | 'cherry-pick --strategy=resolve w/dirty tree does not set CHERRY_PICK_HEAD' ' | |
103 | pristine_detach initial && | |
104 | echo foo >foo && | |
105 | test_must_fail git cherry-pick --strategy=resolve base && | |
106 | test_must_fail git rev-parse --verify CHERRY_PICK_HEAD | |
107 | ' | |
108 | ||
109 | test_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 | ||
119 | test_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 | ||
128 | test_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 | ||
137 | test_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 | ||
154 | test_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 | ' | |
164 | ||
165 | test_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 | ||
176 | test_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 | ||
187 | test_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 && | |
194 | test_path_is_missing .git/sequencer | |
195 | ' | |
196 | ||
197 | test_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 && | |
204 | test_path_is_missing .git/sequencer | |
205 | ' | |
206 | ||
207 | test_expect_success 'failed cherry-pick produces dirty index' ' | |
208 | pristine_detach initial && | |
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 | ||
216 | test_expect_success 'failed cherry-pick registers participants in index' ' | |
217 | pristine_detach initial && | |
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 | |
225 | } >stages && | |
226 | sed " | |
227 | 1 s/ 0 / 1 / | |
228 | 2 s/ 0 / 2 / | |
229 | 3 s/ 0 / 3 / | |
230 | " stages >expected && | |
231 | git read-tree -u --reset HEAD && | |
232 | ||
233 | test_must_fail git cherry-pick picked && | |
234 | git ls-files --stage --unmerged >actual && | |
235 | ||
236 | test_cmp expected actual | |
237 | ' | |
238 | ||
239 | test_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 | ||
259 | test_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 | ||
279 | test_expect_success 'failed cherry-pick describes conflict in work tree' ' | |
280 | pristine_detach initial && | |
281 | cat <<-EOF >expected && | |
282 | <<<<<<< HEAD | |
283 | a | |
284 | ======= | |
285 | c | |
286 | >>>>>>> objid picked | |
287 | EOF | |
288 | ||
289 | test_must_fail git cherry-pick picked && | |
290 | ||
291 | sed "s/[a-f0-9]*\.\.\./objid/" foo >actual && | |
292 | test_cmp expected actual | |
293 | ' | |
294 | ||
295 | test_expect_success 'diff3 -m style' ' | |
296 | pristine_detach initial && | |
297 | git config merge.conflictstyle diff3 && | |
298 | cat <<-EOF >expected && | |
299 | <<<<<<< HEAD | |
300 | a | |
301 | ||||||| parent of objid picked | |
302 | b | |
303 | ======= | |
304 | c | |
305 | >>>>>>> objid picked | |
306 | EOF | |
307 | ||
308 | test_must_fail git cherry-pick picked && | |
309 | ||
310 | sed "s/[a-f0-9]*\.\.\./objid/" foo >actual && | |
311 | test_cmp expected actual | |
312 | ' | |
313 | ||
314 | test_expect_success 'revert also handles conflicts sanely' ' | |
315 | git config --unset merge.conflictstyle && | |
316 | pristine_detach initial && | |
317 | cat <<-EOF >expected && | |
318 | <<<<<<< HEAD | |
319 | a | |
320 | ======= | |
321 | b | |
322 | >>>>>>> parent of objid picked | |
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 | |
331 | } >stages && | |
332 | sed " | |
333 | 1 s/ 0 / 1 / | |
334 | 2 s/ 0 / 2 / | |
335 | 3 s/ 0 / 3 / | |
336 | " stages >expected-stages && | |
337 | git read-tree -u --reset HEAD && | |
338 | ||
339 | head=$(git rev-parse HEAD) && | |
340 | test_must_fail git revert picked && | |
341 | newhead=$(git rev-parse HEAD) && | |
342 | git ls-files --stage --unmerged >actual-stages && | |
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 && | |
348 | sed "s/[a-f0-9]*\.\.\./objid/" foo >actual && | |
349 | test_cmp expected actual | |
350 | ' | |
351 | ||
352 | test_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 | ||
358 | test_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 | ||
365 | test_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 | ||
372 | test_expect_success 'revert w/dirty tree does not set REVERT_HEAD' ' | |
373 | pristine_detach base && | |
374 | echo foo >foo && | |
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 | ||
380 | test_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 | ||
392 | test_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 | ||
399 | test_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 | ||
406 | test_expect_success 'successful final commit clears revert state' ' | |
407 | pristine_detach picked-signed && | |
408 | ||
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 && | |
413 | test_path_is_missing .git/sequencer | |
414 | ' | |
415 | ||
416 | test_expect_success 'reset after final pick clears revert state' ' | |
417 | pristine_detach picked-signed && | |
418 | ||
419 | test_must_fail git revert picked-signed base && | |
420 | echo resolved >foo && | |
421 | test_path_is_file .git/sequencer/todo && | |
422 | git reset && | |
423 | test_path_is_missing .git/sequencer | |
424 | ' | |
425 | ||
426 | test_expect_success 'revert conflict, diff3 -m style' ' | |
427 | pristine_detach initial && | |
428 | git config merge.conflictstyle diff3 && | |
429 | cat <<-EOF >expected && | |
430 | <<<<<<< HEAD | |
431 | a | |
432 | ||||||| objid picked | |
433 | c | |
434 | ======= | |
435 | b | |
436 | >>>>>>> parent of objid picked | |
437 | EOF | |
438 | ||
439 | test_must_fail git revert picked && | |
440 | ||
441 | sed "s/[a-f0-9]*\.\.\./objid/" foo >actual && | |
442 | test_cmp expected actual | |
443 | ' | |
444 | ||
445 | test_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 | ||
468 | test_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 | ||
491 | test_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 | ||
497 | test_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 && | |
501 | test $(git show -s >tmp && grep -c "Signed-off-by" tmp && rm tmp) = 1 | |
502 | ' | |
503 | ||
504 | test_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 && | |
507 | ||
508 | git commit -a -s && | |
509 | ||
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 | |
515 | grep -e "^# Conflicts:" -e '^Signed-off-by' .git/COMMIT_EDITMSG >actual && | |
516 | test_cmp expect actual && | |
517 | ||
518 | cat <<-\EOF >expected && | |
519 | picked | |
520 | ||
521 | Signed-off-by: C O Mitter <committer@example.com> | |
522 | EOF | |
523 | ||
524 | git show -s --pretty=format:%B >actual && | |
525 | test_cmp expected actual | |
526 | ' | |
527 | ||
528 | test_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+ && | |
534 | sed -e "/^# Conflicts:/,\$s/^# *//" .git/MERGE_MSG+ >.git/MERGE_MSG && | |
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 | |
544 | grep -e "^Conflicts:" -e '^Signed-off-by' .git/COMMIT_EDITMSG >actual && | |
545 | test_cmp expect actual | |
546 | ' | |
547 | ||
548 | test_expect_success 'cherry-pick preserves sparse-checkout' ' | |
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 | ||
561 | test_expect_success 'cherry-pick --continue remembers --keep-redundant-commits' ' | |
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 | ||
570 | test_expect_success 'cherry-pick --continue remembers --allow-empty and --allow-empty-message' ' | |
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 | ||
580 | test_done |