]> git.ipfire.org Git - thirdparty/git.git/blame - t/t3510-cherry-pick-sequence.sh
sha1-file: split OBJECT_INFO_FOR_PREFETCH
[thirdparty/git.git] / t / t3510-cherry-pick-sequence.sh
CommitLineData
04d3d3cf
RR
1#!/bin/sh
2
3test_description='Test cherry-pick continuation features
4
093a3091 5 + conflicting: rewrites unrelated to conflicting
539047c1 6 + yetanotherpick: rewrites foo to e
04d3d3cf
RR
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
12
13'
14
15. ./test-lib.sh
16
6bc1a235
RR
17# Repeat first match 10 times
18_r10='\1\1\1\1\1\1\1\1\1\1'
19
04d3d3cf 20pristine_detach () {
f80a8726 21 git cherry-pick --quit &&
04d3d3cf
RR
22 git checkout -f "$1^0" &&
23 git read-tree -u --reset HEAD &&
24 git clean -d -f -f -q -x
25}
26
27test_expect_success setup '
070bad6d 28 git config advice.detachedhead false &&
04d3d3cf
RR
29 echo unrelated >unrelated &&
30 git add unrelated &&
31 test_commit initial foo a &&
32 test_commit base foo b &&
33 test_commit unrelatedpick unrelated reallyunrelated &&
34 test_commit picked foo c &&
35 test_commit anotherpick foo d &&
539047c1 36 test_commit yetanotherpick foo e &&
093a3091
JN
37 pristine_detach initial &&
38 test_commit conflicting unrelated
04d3d3cf
RR
39'
40
41test_expect_success 'cherry-pick persists data on failure' '
42 pristine_detach initial &&
c6b7c7f3 43 test_expect_code 1 git cherry-pick -s base..anotherpick &&
04d3d3cf
RR
44 test_path_is_dir .git/sequencer &&
45 test_path_is_file .git/sequencer/head &&
6f032263
RR
46 test_path_is_file .git/sequencer/todo &&
47 test_path_is_file .git/sequencer/opts
48'
49
7acaaac2
JN
50test_expect_success 'cherry-pick mid-cherry-pick-sequence' '
51 pristine_detach initial &&
52 test_must_fail git cherry-pick base..anotherpick &&
53 test_cmp_rev picked CHERRY_PICK_HEAD &&
54 # "oops, I forgot that these patches rely on the change from base"
55 git checkout HEAD foo &&
56 git cherry-pick base &&
57 git cherry-pick picked &&
58 git cherry-pick --continue &&
59 git diff --exit-code anotherpick
60'
61
6f032263
RR
62test_expect_success 'cherry-pick persists opts correctly' '
63 pristine_detach initial &&
c812bd46
SO
64 # to make sure that the session to cherry-pick a sequence
65 # gets interrupted, use a high-enough number that is larger
66 # than the number of parents of any commit we have created
67 mainline=4 &&
68 test_expect_code 128 git cherry-pick -s -m $mainline --strategy=recursive -X patience -X ours initial..anotherpick &&
6f032263
RR
69 test_path_is_dir .git/sequencer &&
70 test_path_is_file .git/sequencer/head &&
71 test_path_is_file .git/sequencer/todo &&
72 test_path_is_file .git/sequencer/opts &&
73 echo "true" >expect &&
74 git config --file=.git/sequencer/opts --get-all options.signoff >actual &&
75 test_cmp expect actual &&
c812bd46 76 echo "$mainline" >expect &&
6f032263
RR
77 git config --file=.git/sequencer/opts --get-all options.mainline >actual &&
78 test_cmp expect actual &&
79 echo "recursive" >expect &&
80 git config --file=.git/sequencer/opts --get-all options.strategy >actual &&
81 test_cmp expect actual &&
82 cat >expect <<-\EOF &&
83 patience
84 ours
85 EOF
86 git config --file=.git/sequencer/opts --get-all options.strategy-option >actual &&
87 test_cmp expect actual
04d3d3cf
RR
88'
89
90test_expect_success 'cherry-pick cleans up sequencer state upon success' '
91 pristine_detach initial &&
92 git cherry-pick initial..picked &&
93 test_path_is_missing .git/sequencer
94'
95
f80a8726 96test_expect_success '--quit does not complain when no cherry-pick is in progress' '
26ae337b 97 pristine_detach initial &&
f80a8726 98 git cherry-pick --quit
26ae337b
RR
99'
100
539047c1
JN
101test_expect_success '--abort requires cherry-pick in progress' '
102 pristine_detach initial &&
103 test_must_fail git cherry-pick --abort
104'
105
f80a8726 106test_expect_success '--quit cleans up sequencer state' '
26ae337b 107 pristine_detach initial &&
c6b7c7f3 108 test_expect_code 1 git cherry-pick base..picked &&
f80a8726 109 git cherry-pick --quit &&
3e7dd992
NTND
110 test_path_is_missing .git/sequencer &&
111 test_path_is_missing .git/CHERRY_PICK_HEAD
26ae337b
RR
112'
113
c427b211 114test_expect_success '--quit keeps HEAD and conflicted index intact' '
f80a8726
JN
115 pristine_detach initial &&
116 cat >expect <<-\EOF &&
117 OBJID
118 :100644 100644 OBJID OBJID M unrelated
119 OBJID
120 :000000 100644 OBJID OBJID A foo
121 :000000 100644 OBJID OBJID A unrelated
122 EOF
c6b7c7f3 123 test_expect_code 1 git cherry-pick base..picked &&
c427b211 124 git cherry-pick --quit &&
f80a8726
JN
125 test_path_is_missing .git/sequencer &&
126 test_must_fail git update-index --refresh &&
127 {
128 git rev-list HEAD |
129 git diff-tree --root --stdin |
2ece6ad2 130 sed "s/$OID_REGEX/OBJID/g"
f80a8726
JN
131 } >actual &&
132 test_cmp expect actual
133'
134
539047c1
JN
135test_expect_success '--abort to cancel multiple cherry-pick' '
136 pristine_detach initial &&
c6b7c7f3 137 test_expect_code 1 git cherry-pick base..anotherpick &&
539047c1
JN
138 git cherry-pick --abort &&
139 test_path_is_missing .git/sequencer &&
3e7dd992 140 test_path_is_missing .git/CHERRY_PICK_HEAD &&
539047c1
JN
141 test_cmp_rev initial HEAD &&
142 git update-index --refresh &&
143 git diff-index --exit-code HEAD
144'
145
146test_expect_success '--abort to cancel single cherry-pick' '
147 pristine_detach initial &&
c6b7c7f3 148 test_expect_code 1 git cherry-pick picked &&
539047c1
JN
149 git cherry-pick --abort &&
150 test_path_is_missing .git/sequencer &&
3e7dd992 151 test_path_is_missing .git/CHERRY_PICK_HEAD &&
539047c1
JN
152 test_cmp_rev initial HEAD &&
153 git update-index --refresh &&
154 git diff-index --exit-code HEAD
155'
156
1e41229d 157test_expect_success '--abort does not unsafely change HEAD' '
aeebd98e
SB
158 pristine_detach initial &&
159 test_must_fail git cherry-pick picked anotherpick &&
160 git reset --hard base &&
161 test_must_fail git cherry-pick picked anotherpick &&
162 git cherry-pick --abort 2>actual &&
163 test_i18ngrep "You seem to have moved HEAD" actual &&
164 test_cmp_rev base HEAD
165'
166
539047c1
JN
167test_expect_success 'cherry-pick --abort to cancel multiple revert' '
168 pristine_detach anotherpick &&
c6b7c7f3 169 test_expect_code 1 git revert base..picked &&
539047c1
JN
170 git cherry-pick --abort &&
171 test_path_is_missing .git/sequencer &&
3e7dd992 172 test_path_is_missing .git/CHERRY_PICK_HEAD &&
539047c1
JN
173 test_cmp_rev anotherpick HEAD &&
174 git update-index --refresh &&
175 git diff-index --exit-code HEAD
176'
177
178test_expect_success 'revert --abort works, too' '
179 pristine_detach anotherpick &&
c6b7c7f3 180 test_expect_code 1 git revert base..picked &&
539047c1
JN
181 git revert --abort &&
182 test_path_is_missing .git/sequencer &&
183 test_cmp_rev anotherpick HEAD
184'
185
186test_expect_success '--abort to cancel single revert' '
187 pristine_detach anotherpick &&
c6b7c7f3 188 test_expect_code 1 git revert picked &&
539047c1
JN
189 git revert --abort &&
190 test_path_is_missing .git/sequencer &&
191 test_cmp_rev anotherpick HEAD &&
192 git update-index --refresh &&
193 git diff-index --exit-code HEAD
194'
195
196test_expect_success '--abort keeps unrelated change, easy case' '
197 pristine_detach unrelatedpick &&
198 echo changed >expect &&
c6b7c7f3 199 test_expect_code 1 git cherry-pick picked..yetanotherpick &&
539047c1
JN
200 echo changed >unrelated &&
201 git cherry-pick --abort &&
202 test_cmp expect unrelated
203'
204
205test_expect_success '--abort refuses to clobber unrelated change, harder case' '
206 pristine_detach initial &&
207 echo changed >expect &&
c6b7c7f3 208 test_expect_code 1 git cherry-pick base..anotherpick &&
539047c1
JN
209 echo changed >unrelated &&
210 test_must_fail git cherry-pick --abort &&
211 test_cmp expect unrelated &&
212 git rev-list HEAD >log &&
213 test_line_count = 2 log &&
214 test_must_fail git update-index --refresh &&
215
216 git checkout unrelated &&
217 git cherry-pick --abort &&
218 test_cmp_rev initial HEAD
219'
220
218b65fb 221test_expect_success 'cherry-pick still writes sequencer state when one commit is left' '
2d27daa9 222 pristine_detach initial &&
c6b7c7f3 223 test_expect_code 1 git cherry-pick base..picked &&
218b65fb 224 test_path_is_dir .git/sequencer &&
2d27daa9
RR
225 echo "resolved" >foo &&
226 git add foo &&
227 git commit &&
228 {
229 git rev-list HEAD |
230 git diff-tree --root --stdin |
2ece6ad2 231 sed "s/$OID_REGEX/OBJID/g"
2d27daa9
RR
232 } >actual &&
233 cat >expect <<-\EOF &&
234 OBJID
235 :100644 100644 OBJID OBJID M foo
236 OBJID
237 :100644 100644 OBJID OBJID M unrelated
238 OBJID
239 :000000 100644 OBJID OBJID A foo
240 :000000 100644 OBJID OBJID A unrelated
241 EOF
242 test_cmp expect actual
243'
244
218b65fb 245test_expect_success '--abort after last commit in sequence' '
539047c1 246 pristine_detach initial &&
c6b7c7f3 247 test_expect_code 1 git cherry-pick base..picked &&
539047c1
JN
248 git cherry-pick --abort &&
249 test_path_is_missing .git/sequencer &&
3e7dd992 250 test_path_is_missing .git/CHERRY_PICK_HEAD &&
539047c1
JN
251 test_cmp_rev initial HEAD &&
252 git update-index --refresh &&
253 git diff-index --exit-code HEAD
254'
255
21afd080
RR
256test_expect_success 'cherry-pick does not implicitly stomp an existing operation' '
257 pristine_detach initial &&
c6b7c7f3 258 test_expect_code 1 git cherry-pick base..anotherpick &&
deb9845a 259 test-tool chmtime --get .git/sequencer >expect &&
c6b7c7f3 260 test_expect_code 128 git cherry-pick unrelatedpick &&
deb9845a 261 test-tool chmtime --get .git/sequencer >actual &&
21afd080
RR
262 test_cmp expect actual
263'
264
5a5d80f4
RR
265test_expect_success '--continue complains when no cherry-pick is in progress' '
266 pristine_detach initial &&
c6b7c7f3 267 test_expect_code 128 git cherry-pick --continue
5a5d80f4
RR
268'
269
270test_expect_success '--continue complains when there are unresolved conflicts' '
271 pristine_detach initial &&
c6b7c7f3
RR
272 test_expect_code 1 git cherry-pick base..anotherpick &&
273 test_expect_code 128 git cherry-pick --continue
5a5d80f4
RR
274'
275
093a3091
JN
276test_expect_success '--continue of single cherry-pick' '
277 pristine_detach initial &&
278 echo c >expect &&
279 test_must_fail git cherry-pick picked &&
280 echo c >foo &&
281 git add foo &&
282 git cherry-pick --continue &&
283
284 test_cmp expect foo &&
285 test_cmp_rev initial HEAD^ &&
286 git diff --exit-code HEAD &&
287 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
288'
289
290test_expect_success '--continue of single revert' '
291 pristine_detach initial &&
292 echo resolved >expect &&
293 echo "Revert \"picked\"" >expect.msg &&
294 test_must_fail git revert picked &&
295 echo resolved >foo &&
296 git add foo &&
297 git cherry-pick --continue &&
298
299 git diff --exit-code HEAD &&
300 test_cmp expect foo &&
301 test_cmp_rev initial HEAD^ &&
302 git diff-tree -s --pretty=tformat:%s HEAD >msg &&
303 test_cmp expect.msg msg &&
304 test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
305 test_must_fail git rev-parse --verify REVERT_HEAD
306'
307
308test_expect_success '--continue after resolving conflicts' '
309 pristine_detach initial &&
310 echo d >expect &&
311 cat >expect.log <<-\EOF &&
312 OBJID
313 :100644 100644 OBJID OBJID M foo
314 OBJID
315 :100644 100644 OBJID OBJID M foo
316 OBJID
317 :100644 100644 OBJID OBJID M unrelated
318 OBJID
319 :000000 100644 OBJID OBJID A foo
320 :000000 100644 OBJID OBJID A unrelated
321 EOF
322 test_must_fail git cherry-pick base..anotherpick &&
323 echo c >foo &&
324 git add foo &&
325 git cherry-pick --continue &&
326 {
327 git rev-list HEAD |
328 git diff-tree --root --stdin |
2ece6ad2 329 sed "s/$OID_REGEX/OBJID/g"
093a3091
JN
330 } >actual.log &&
331 test_cmp expect foo &&
332 test_cmp expect.log actual.log
333'
334
335test_expect_success '--continue after resolving conflicts and committing' '
5a5d80f4 336 pristine_detach initial &&
c6b7c7f3 337 test_expect_code 1 git cherry-pick base..anotherpick &&
5a5d80f4
RR
338 echo "c" >foo &&
339 git add foo &&
340 git commit &&
341 git cherry-pick --continue &&
342 test_path_is_missing .git/sequencer &&
343 {
344 git rev-list HEAD |
345 git diff-tree --root --stdin |
2ece6ad2 346 sed "s/$OID_REGEX/OBJID/g"
5a5d80f4
RR
347 } >actual &&
348 cat >expect <<-\EOF &&
349 OBJID
350 :100644 100644 OBJID OBJID M foo
351 OBJID
352 :100644 100644 OBJID OBJID M foo
353 OBJID
354 :100644 100644 OBJID OBJID M unrelated
355 OBJID
356 :000000 100644 OBJID OBJID A foo
357 :000000 100644 OBJID OBJID A unrelated
358 EOF
359 test_cmp expect actual
360'
361
093a3091
JN
362test_expect_success '--continue asks for help after resolving patch to nil' '
363 pristine_detach conflicting &&
364 test_must_fail git cherry-pick initial..picked &&
365
366 test_cmp_rev unrelatedpick CHERRY_PICK_HEAD &&
367 git checkout HEAD -- unrelated &&
368 test_must_fail git cherry-pick --continue 2>msg &&
369 test_i18ngrep "The previous cherry-pick is now empty" msg
370'
371
a7eff1e0 372test_expect_success 'follow advice and skip nil patch' '
093a3091
JN
373 pristine_detach conflicting &&
374 test_must_fail git cherry-pick initial..picked &&
375
376 git checkout HEAD -- unrelated &&
377 test_must_fail git cherry-pick --continue &&
378 git reset &&
379 git cherry-pick --continue &&
380
381 git rev-list initial..HEAD >commits &&
382 test_line_count = 3 commits
383'
384
5a5d80f4
RR
385test_expect_success '--continue respects opts' '
386 pristine_detach initial &&
c6b7c7f3 387 test_expect_code 1 git cherry-pick -x base..anotherpick &&
5a5d80f4
RR
388 echo "c" >foo &&
389 git add foo &&
390 git commit &&
391 git cherry-pick --continue &&
392 test_path_is_missing .git/sequencer &&
393 git cat-file commit HEAD >anotherpick_msg &&
394 git cat-file commit HEAD~1 >picked_msg &&
395 git cat-file commit HEAD~2 >unrelatedpick_msg &&
396 git cat-file commit HEAD~3 >initial_msg &&
c7cf9566 397 ! grep "cherry picked from" initial_msg &&
5a5d80f4
RR
398 grep "cherry picked from" unrelatedpick_msg &&
399 grep "cherry picked from" picked_msg &&
400 grep "cherry picked from" anotherpick_msg
401'
402
093a3091
JN
403test_expect_success '--continue of single-pick respects -x' '
404 pristine_detach initial &&
405 test_must_fail git cherry-pick -x picked &&
406 echo c >foo &&
407 git add foo &&
408 git cherry-pick --continue &&
409 test_path_is_missing .git/sequencer &&
410 git cat-file commit HEAD >msg &&
411 grep "cherry picked from" msg
412'
413
414test_expect_success '--continue respects -x in first commit in multi-pick' '
415 pristine_detach initial &&
416 test_must_fail git cherry-pick -x picked anotherpick &&
417 echo c >foo &&
418 git add foo &&
419 git cherry-pick --continue &&
420 test_path_is_missing .git/sequencer &&
421 git cat-file commit HEAD^ >msg &&
422 picked=$(git rev-parse --verify picked) &&
423 grep "cherry picked from.*$picked" msg
424'
425
5ed75e2a 426test_expect_failure '--signoff is automatically propagated to resolved conflict' '
5a5d80f4 427 pristine_detach initial &&
c6b7c7f3 428 test_expect_code 1 git cherry-pick --signoff base..anotherpick &&
5a5d80f4
RR
429 echo "c" >foo &&
430 git add foo &&
431 git commit &&
432 git cherry-pick --continue &&
433 test_path_is_missing .git/sequencer &&
434 git cat-file commit HEAD >anotherpick_msg &&
435 git cat-file commit HEAD~1 >picked_msg &&
436 git cat-file commit HEAD~2 >unrelatedpick_msg &&
437 git cat-file commit HEAD~3 >initial_msg &&
c7cf9566 438 ! grep "Signed-off-by:" initial_msg &&
5a5d80f4 439 grep "Signed-off-by:" unrelatedpick_msg &&
c7cf9566 440 ! grep "Signed-off-by:" picked_msg &&
5a5d80f4
RR
441 grep "Signed-off-by:" anotherpick_msg
442'
443
5ed75e2a 444test_expect_failure '--signoff dropped for implicit commit of resolution, multi-pick case' '
093a3091
JN
445 pristine_detach initial &&
446 test_must_fail git cherry-pick -s picked anotherpick &&
447 echo c >foo &&
448 git add foo &&
449 git cherry-pick --continue &&
450
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
455'
456
5ed75e2a 457test_expect_failure 'sign-off needs to be reaffirmed after conflict resolution, single-pick case' '
093a3091
JN
458 pristine_detach initial &&
459 test_must_fail git cherry-pick -s picked &&
460 echo c >foo &&
461 git add foo &&
462 git cherry-pick --continue &&
463
464 git diff --exit-code HEAD &&
465 test_cmp_rev initial HEAD^ &&
466 git cat-file commit HEAD >msg &&
467 ! grep Signed-off-by: msg
468'
469
5a5d80f4
RR
470test_expect_success 'malformed instruction sheet 1' '
471 pristine_detach initial &&
c6b7c7f3 472 test_expect_code 1 git cherry-pick base..anotherpick &&
5a5d80f4
RR
473 echo "resolved" >foo &&
474 git add foo &&
475 git commit &&
476 sed "s/pick /pick/" .git/sequencer/todo >new_sheet &&
477 cp new_sheet .git/sequencer/todo &&
c6b7c7f3 478 test_expect_code 128 git cherry-pick --continue
5a5d80f4
RR
479'
480
481test_expect_success 'malformed instruction sheet 2' '
482 pristine_detach initial &&
c6b7c7f3 483 test_expect_code 1 git cherry-pick base..anotherpick &&
5a5d80f4
RR
484 echo "resolved" >foo &&
485 git add foo &&
486 git commit &&
487 sed "s/pick/revert/" .git/sequencer/todo >new_sheet &&
488 cp new_sheet .git/sequencer/todo &&
c6b7c7f3 489 test_expect_code 128 git cherry-pick --continue
5a5d80f4
RR
490'
491
8530c739 492test_expect_success 'empty commit set (no commits to walk)' '
7f13334e
JN
493 pristine_detach initial &&
494 test_expect_code 128 git cherry-pick base..base
495'
496
8530c739
JK
497test_expect_success 'empty commit set (culled during walk)' '
498 pristine_detach initial &&
499 test_expect_code 128 git cherry-pick -2 --author=no.such.author base
500'
501
6bc1a235
RR
502test_expect_success 'malformed instruction sheet 3' '
503 pristine_detach initial &&
c6b7c7f3 504 test_expect_code 1 git cherry-pick base..anotherpick &&
6bc1a235
RR
505 echo "resolved" >foo &&
506 git add foo &&
507 git commit &&
508 sed "s/pick \([0-9a-f]*\)/pick $_r10/" .git/sequencer/todo >new_sheet &&
509 cp new_sheet .git/sequencer/todo &&
c6b7c7f3 510 test_expect_code 128 git cherry-pick --continue
6bc1a235
RR
511'
512
0db76962
RR
513test_expect_success 'instruction sheet, fat-fingers version' '
514 pristine_detach initial &&
c6b7c7f3 515 test_expect_code 1 git cherry-pick base..anotherpick &&
0db76962
RR
516 echo "c" >foo &&
517 git add foo &&
518 git commit &&
519 sed "s/pick \([0-9a-f]*\)/pick \1 /" .git/sequencer/todo >new_sheet &&
520 cp new_sheet .git/sequencer/todo &&
521 git cherry-pick --continue
522'
523
6bc1a235
RR
524test_expect_success 'commit descriptions in insn sheet are optional' '
525 pristine_detach initial &&
c6b7c7f3 526 test_expect_code 1 git cherry-pick base..anotherpick &&
6bc1a235
RR
527 echo "c" >foo &&
528 git add foo &&
529 git commit &&
530 cut -d" " -f1,2 .git/sequencer/todo >new_sheet &&
531 cp new_sheet .git/sequencer/todo &&
532 git cherry-pick --continue &&
533 test_path_is_missing .git/sequencer &&
534 git rev-list HEAD >commits &&
535 test_line_count = 4 commits
536'
537
04d3d3cf 538test_done