3 test_description
='Test cherry-pick continuation features
5 + conflicting: rewrites unrelated to conflicting
6 + yetanotherpick: rewrites foo to e
7 + anotherpick: rewrites foo to d
8 + picked: rewrites foo to c
9 + unrelatedpick: rewrites unrelated to reallyunrelated
10 + base: rewrites foo to b
11 + initial: writes foo as a, unrelated as unrelated
17 # Repeat first match 10 times
18 _r10
='\1\1\1\1\1\1\1\1\1\1'
21 git cherry-pick
--quit &&
22 git checkout
-f "$1^0" &&
23 git read-tree
-u --reset HEAD
&&
24 git clean
-d -f -f -q -x
28 git rev-parse
--verify "$1" >expect.
rev &&
29 git rev-parse
--verify "$2" >actual.
rev &&
30 test_cmp expect.
rev actual.
rev
33 test_expect_success setup
'
34 git config advice.detachedhead false &&
35 echo unrelated >unrelated &&
37 test_commit initial foo a &&
38 test_commit base foo b &&
39 test_commit unrelatedpick unrelated reallyunrelated &&
40 test_commit picked foo c &&
41 test_commit anotherpick foo d &&
42 test_commit yetanotherpick foo e &&
43 pristine_detach initial &&
44 test_commit conflicting unrelated
47 test_expect_success
'cherry-pick persists data on failure' '
48 pristine_detach initial &&
49 test_expect_code 1 git cherry-pick -s base..anotherpick &&
50 test_path_is_dir .git/sequencer &&
51 test_path_is_file .git/sequencer/head &&
52 test_path_is_file .git/sequencer/todo &&
53 test_path_is_file .git/sequencer/opts
56 test_expect_success
'cherry-pick mid-cherry-pick-sequence' '
57 pristine_detach initial &&
58 test_must_fail git cherry-pick base..anotherpick &&
59 test_cmp_rev picked CHERRY_PICK_HEAD &&
60 # "oops, I forgot that these patches rely on the change from base"
61 git checkout HEAD foo &&
62 git cherry-pick base &&
63 git cherry-pick picked &&
64 git cherry-pick --continue &&
65 git diff --exit-code anotherpick
68 test_expect_success
'cherry-pick persists opts correctly' '
69 pristine_detach initial &&
70 test_expect_code 128 git cherry-pick -s -m 1 --strategy=recursive -X patience -X ours initial..anotherpick &&
71 test_path_is_dir .git/sequencer &&
72 test_path_is_file .git/sequencer/head &&
73 test_path_is_file .git/sequencer/todo &&
74 test_path_is_file .git/sequencer/opts &&
75 echo "true" >expect &&
76 git config --file=.git/sequencer/opts --get-all options.signoff >actual &&
77 test_cmp expect actual &&
79 git config --file=.git/sequencer/opts --get-all options.mainline >actual &&
80 test_cmp expect actual &&
81 echo "recursive" >expect &&
82 git config --file=.git/sequencer/opts --get-all options.strategy >actual &&
83 test_cmp expect actual &&
84 cat >expect <<-\EOF &&
88 git config --file=.git/sequencer/opts --get-all options.strategy-option >actual &&
89 test_cmp expect actual
92 test_expect_success
'cherry-pick cleans up sequencer state upon success' '
93 pristine_detach initial &&
94 git cherry-pick initial..picked &&
95 test_path_is_missing .git/sequencer
98 test_expect_success
'--quit does not complain when no cherry-pick is in progress' '
99 pristine_detach initial &&
100 git cherry-pick --quit
103 test_expect_success
'--abort requires cherry-pick in progress' '
104 pristine_detach initial &&
105 test_must_fail git cherry-pick --abort
108 test_expect_success
'--quit cleans up sequencer state' '
109 pristine_detach initial &&
110 test_expect_code 1 git cherry-pick base..picked &&
111 git cherry-pick --quit &&
112 test_path_is_missing .git/sequencer
115 test_expect_success
'--quit keeps HEAD and conflicted index intact' '
116 pristine_detach initial &&
117 cat >expect <<-\EOF &&
119 :100644 100644 OBJID OBJID M unrelated
121 :000000 100644 OBJID OBJID A foo
122 :000000 100644 OBJID OBJID A unrelated
124 test_expect_code 1 git cherry-pick base..picked &&
125 git cherry-pick --quit &&
126 test_path_is_missing .git/sequencer &&
127 test_must_fail git update-index --refresh &&
130 git diff-tree --root --stdin |
131 sed "s/$_x40/OBJID/g"
133 test_cmp expect actual
136 test_expect_success
'--abort to cancel multiple cherry-pick' '
137 pristine_detach initial &&
138 test_expect_code 1 git cherry-pick base..anotherpick &&
139 git cherry-pick --abort &&
140 test_path_is_missing .git/sequencer &&
141 test_cmp_rev initial HEAD &&
142 git update-index --refresh &&
143 git diff-index --exit-code HEAD
146 test_expect_success
'--abort to cancel single cherry-pick' '
147 pristine_detach initial &&
148 test_expect_code 1 git cherry-pick picked &&
149 git cherry-pick --abort &&
150 test_path_is_missing .git/sequencer &&
151 test_cmp_rev initial HEAD &&
152 git update-index --refresh &&
153 git diff-index --exit-code HEAD
156 test_expect_success
'cherry-pick --abort to cancel multiple revert' '
157 pristine_detach anotherpick &&
158 test_expect_code 1 git revert base..picked &&
159 git cherry-pick --abort &&
160 test_path_is_missing .git/sequencer &&
161 test_cmp_rev anotherpick HEAD &&
162 git update-index --refresh &&
163 git diff-index --exit-code HEAD
166 test_expect_success
'revert --abort works, too' '
167 pristine_detach anotherpick &&
168 test_expect_code 1 git revert base..picked &&
169 git revert --abort &&
170 test_path_is_missing .git/sequencer &&
171 test_cmp_rev anotherpick HEAD
174 test_expect_success
'--abort to cancel single revert' '
175 pristine_detach anotherpick &&
176 test_expect_code 1 git revert picked &&
177 git revert --abort &&
178 test_path_is_missing .git/sequencer &&
179 test_cmp_rev anotherpick HEAD &&
180 git update-index --refresh &&
181 git diff-index --exit-code HEAD
184 test_expect_success
'--abort keeps unrelated change, easy case' '
185 pristine_detach unrelatedpick &&
186 echo changed >expect &&
187 test_expect_code 1 git cherry-pick picked..yetanotherpick &&
188 echo changed >unrelated &&
189 git cherry-pick --abort &&
190 test_cmp expect unrelated
193 test_expect_success
'--abort refuses to clobber unrelated change, harder case' '
194 pristine_detach initial &&
195 echo changed >expect &&
196 test_expect_code 1 git cherry-pick base..anotherpick &&
197 echo changed >unrelated &&
198 test_must_fail git cherry-pick --abort &&
199 test_cmp expect unrelated &&
200 git rev-list HEAD >log &&
201 test_line_count = 2 log &&
202 test_must_fail git update-index --refresh &&
204 git checkout unrelated &&
205 git cherry-pick --abort &&
206 test_cmp_rev initial HEAD
209 test_expect_success
'cherry-pick still writes sequencer state when one commit is left' '
210 pristine_detach initial &&
211 test_expect_code 1 git cherry-pick base..picked &&
212 test_path_is_dir .git/sequencer &&
213 echo "resolved" >foo &&
218 git diff-tree --root --stdin |
219 sed "s/$_x40/OBJID/g"
221 cat >expect <<-\EOF &&
223 :100644 100644 OBJID OBJID M foo
225 :100644 100644 OBJID OBJID M unrelated
227 :000000 100644 OBJID OBJID A foo
228 :000000 100644 OBJID OBJID A unrelated
230 test_cmp expect actual
233 test_expect_success
'--abort after last commit in sequence' '
234 pristine_detach initial &&
235 test_expect_code 1 git cherry-pick base..picked &&
236 git cherry-pick --abort &&
237 test_path_is_missing .git/sequencer &&
238 test_cmp_rev initial HEAD &&
239 git update-index --refresh &&
240 git diff-index --exit-code HEAD
243 test_expect_success
'cherry-pick does not implicitly stomp an existing operation' '
244 pristine_detach initial &&
245 test_expect_code 1 git cherry-pick base..anotherpick &&
246 test-chmtime -v +0 .git/sequencer >expect &&
247 test_expect_code 128 git cherry-pick unrelatedpick &&
248 test-chmtime -v +0 .git/sequencer >actual &&
249 test_cmp expect actual
252 test_expect_success
'--continue complains when no cherry-pick is in progress' '
253 pristine_detach initial &&
254 test_expect_code 128 git cherry-pick --continue
257 test_expect_success
'--continue complains when there are unresolved conflicts' '
258 pristine_detach initial &&
259 test_expect_code 1 git cherry-pick base..anotherpick &&
260 test_expect_code 128 git cherry-pick --continue
263 test_expect_success
'--continue of single cherry-pick' '
264 pristine_detach initial &&
266 test_must_fail git cherry-pick picked &&
269 git cherry-pick --continue &&
271 test_cmp expect foo &&
272 test_cmp_rev initial HEAD^ &&
273 git diff --exit-code HEAD &&
274 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
277 test_expect_success
'--continue of single revert' '
278 pristine_detach initial &&
279 echo resolved >expect &&
280 echo "Revert \"picked\"" >expect.msg &&
281 test_must_fail git revert picked &&
282 echo resolved >foo &&
284 git cherry-pick --continue &&
286 git diff --exit-code HEAD &&
287 test_cmp expect foo &&
288 test_cmp_rev initial HEAD^ &&
289 git diff-tree -s --pretty=tformat:%s HEAD >msg &&
290 test_cmp expect.msg msg &&
291 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
292 test_must_fail git rev-parse --verify REVERT_HEAD
295 test_expect_success
'--continue after resolving conflicts' '
296 pristine_detach initial &&
298 cat >expect.log <<-\EOF &&
300 :100644 100644 OBJID OBJID M foo
302 :100644 100644 OBJID OBJID M foo
304 :100644 100644 OBJID OBJID M unrelated
306 :000000 100644 OBJID OBJID A foo
307 :000000 100644 OBJID OBJID A unrelated
309 test_must_fail git cherry-pick base..anotherpick &&
312 git cherry-pick --continue &&
315 git diff-tree --root --stdin |
316 sed "s/$_x40/OBJID/g"
318 test_cmp expect foo &&
319 test_cmp expect.log actual.log
322 test_expect_success
'--continue after resolving conflicts and committing' '
323 pristine_detach initial &&
324 test_expect_code 1 git cherry-pick base..anotherpick &&
328 git cherry-pick --continue &&
329 test_path_is_missing .git/sequencer &&
332 git diff-tree --root --stdin |
333 sed "s/$_x40/OBJID/g"
335 cat >expect <<-\EOF &&
337 :100644 100644 OBJID OBJID M foo
339 :100644 100644 OBJID OBJID M foo
341 :100644 100644 OBJID OBJID M unrelated
343 :000000 100644 OBJID OBJID A foo
344 :000000 100644 OBJID OBJID A unrelated
346 test_cmp expect actual
349 test_expect_success
'--continue asks for help after resolving patch to nil' '
350 pristine_detach conflicting &&
351 test_must_fail git cherry-pick initial..picked &&
353 test_cmp_rev unrelatedpick CHERRY_PICK_HEAD &&
354 git checkout HEAD -- unrelated &&
355 test_must_fail git cherry-pick --continue 2>msg &&
356 test_i18ngrep "The previous cherry-pick is now empty" msg
359 test_expect_success
'follow advice and skip nil patch' '
360 pristine_detach conflicting &&
361 test_must_fail git cherry-pick initial..picked &&
363 git checkout HEAD -- unrelated &&
364 test_must_fail git cherry-pick --continue &&
366 git cherry-pick --continue &&
368 git rev-list initial..HEAD >commits &&
369 test_line_count = 3 commits
372 test_expect_success
'--continue respects opts' '
373 pristine_detach initial &&
374 test_expect_code 1 git cherry-pick -x base..anotherpick &&
378 git cherry-pick --continue &&
379 test_path_is_missing .git/sequencer &&
380 git cat-file commit HEAD >anotherpick_msg &&
381 git cat-file commit HEAD~1 >picked_msg &&
382 git cat-file commit HEAD~2 >unrelatedpick_msg &&
383 git cat-file commit HEAD~3 >initial_msg &&
384 test_must_fail grep "cherry picked from" initial_msg &&
385 grep "cherry picked from" unrelatedpick_msg &&
386 grep "cherry picked from" picked_msg &&
387 grep "cherry picked from" anotherpick_msg
390 test_expect_success
'--continue of single-pick respects -x' '
391 pristine_detach initial &&
392 test_must_fail git cherry-pick -x picked &&
395 git cherry-pick --continue &&
396 test_path_is_missing .git/sequencer &&
397 git cat-file commit HEAD >msg &&
398 grep "cherry picked from" msg
401 test_expect_success
'--continue respects -x in first commit in multi-pick' '
402 pristine_detach initial &&
403 test_must_fail git cherry-pick -x picked anotherpick &&
406 git cherry-pick --continue &&
407 test_path_is_missing .git/sequencer &&
408 git cat-file commit HEAD^ >msg &&
409 picked=$(git rev-parse --verify picked) &&
410 grep "cherry picked from.*$picked" msg
413 test_expect_failure
'--signoff is automatically propagated to resolved conflict' '
414 pristine_detach initial &&
415 test_expect_code 1 git cherry-pick --signoff base..anotherpick &&
419 git cherry-pick --continue &&
420 test_path_is_missing .git/sequencer &&
421 git cat-file commit HEAD >anotherpick_msg &&
422 git cat-file commit HEAD~1 >picked_msg &&
423 git cat-file commit HEAD~2 >unrelatedpick_msg &&
424 git cat-file commit HEAD~3 >initial_msg &&
425 test_must_fail grep "Signed-off-by:" initial_msg &&
426 grep "Signed-off-by:" unrelatedpick_msg &&
427 test_must_fail grep "Signed-off-by:" picked_msg &&
428 grep "Signed-off-by:" anotherpick_msg
431 test_expect_failure
'--signoff dropped for implicit commit of resolution, multi-pick case' '
432 pristine_detach initial &&
433 test_must_fail git cherry-pick -s picked anotherpick &&
436 git cherry-pick --continue &&
438 git diff --exit-code HEAD &&
439 test_cmp_rev initial HEAD^^ &&
440 git cat-file commit HEAD^ >msg &&
441 ! grep Signed-off-by: msg
444 test_expect_failure
'sign-off needs to be reaffirmed after conflict resolution, single-pick case' '
445 pristine_detach initial &&
446 test_must_fail git cherry-pick -s picked &&
449 git cherry-pick --continue &&
451 git diff --exit-code HEAD &&
452 test_cmp_rev initial HEAD^ &&
453 git cat-file commit HEAD >msg &&
454 ! grep Signed-off-by: msg
457 test_expect_success
'malformed instruction sheet 1' '
458 pristine_detach initial &&
459 test_expect_code 1 git cherry-pick base..anotherpick &&
460 echo "resolved" >foo &&
463 sed "s/pick /pick/" .git/sequencer/todo >new_sheet &&
464 cp new_sheet .git/sequencer/todo &&
465 test_expect_code 128 git cherry-pick --continue
468 test_expect_success
'malformed instruction sheet 2' '
469 pristine_detach initial &&
470 test_expect_code 1 git cherry-pick base..anotherpick &&
471 echo "resolved" >foo &&
474 sed "s/pick/revert/" .git/sequencer/todo >new_sheet &&
475 cp new_sheet .git/sequencer/todo &&
476 test_expect_code 128 git cherry-pick --continue
479 test_expect_success
'empty commit set' '
480 pristine_detach initial &&
481 test_expect_code 128 git cherry-pick base..base
484 test_expect_success
'malformed instruction sheet 3' '
485 pristine_detach initial &&
486 test_expect_code 1 git cherry-pick base..anotherpick &&
487 echo "resolved" >foo &&
490 sed "s/pick \([0-9a-f]*\)/pick $_r10/" .git/sequencer/todo >new_sheet &&
491 cp new_sheet .git/sequencer/todo &&
492 test_expect_code 128 git cherry-pick --continue
495 test_expect_success
'instruction sheet, fat-fingers version' '
496 pristine_detach initial &&
497 test_expect_code 1 git cherry-pick base..anotherpick &&
501 sed "s/pick \([0-9a-f]*\)/pick \1 /" .git/sequencer/todo >new_sheet &&
502 cp new_sheet .git/sequencer/todo &&
503 git cherry-pick --continue
506 test_expect_success
'commit descriptions in insn sheet are optional' '
507 pristine_detach initial &&
508 test_expect_code 1 git cherry-pick base..anotherpick &&
512 cut -d" " -f1,2 .git/sequencer/todo >new_sheet &&
513 cp new_sheet .git/sequencer/todo &&
514 git cherry-pick --continue &&
515 test_path_is_missing .git/sequencer &&
516 git rev-list HEAD >commits &&
517 test_line_count = 4 commits