submodule: Use cat instead of echo to avoid DOS line-endings
[git/dscho.git] / t / t3510-cherry-pick-sequence.sh
blob2e2dca24467a42bed1516bb3ccc82730d8cca9ad
1 #!/bin/sh
3 test_description='Test cherry-pick continuation features
5 + yetanotherpick: rewrites foo to e
6 + anotherpick: rewrites foo to d
7 + picked: rewrites foo to c
8 + unrelatedpick: rewrites unrelated to reallyunrelated
9 + base: rewrites foo to b
10 + initial: writes foo as a, unrelated as unrelated
14 . ./test-lib.sh
16 # Repeat first match 10 times
17 _r10='\1\1\1\1\1\1\1\1\1\1'
19 pristine_detach () {
20 git cherry-pick --quit &&
21 git checkout -f "$1^0" &&
22 git read-tree -u --reset HEAD &&
23 git clean -d -f -f -q -x
26 test_cmp_rev () {
27 git rev-parse --verify "$1" >expect.rev &&
28 git rev-parse --verify "$2" >actual.rev &&
29 test_cmp expect.rev actual.rev
32 test_expect_success setup '
33 echo unrelated >unrelated &&
34 git add unrelated &&
35 test_commit initial foo a &&
36 test_commit base foo b &&
37 test_commit unrelatedpick unrelated reallyunrelated &&
38 test_commit picked foo c &&
39 test_commit anotherpick foo d &&
40 test_commit yetanotherpick foo e &&
41 git config advice.detachedhead false
45 test_expect_success 'cherry-pick persists data on failure' '
46 pristine_detach initial &&
47 test_must_fail git cherry-pick -s base..anotherpick &&
48 test_path_is_dir .git/sequencer &&
49 test_path_is_file .git/sequencer/head &&
50 test_path_is_file .git/sequencer/todo &&
51 test_path_is_file .git/sequencer/opts
54 test_expect_success 'cherry-pick persists opts correctly' '
55 pristine_detach initial &&
56 test_must_fail git cherry-pick -s -m 1 --strategy=recursive -X patience -X ours base..anotherpick &&
57 test_path_is_dir .git/sequencer &&
58 test_path_is_file .git/sequencer/head &&
59 test_path_is_file .git/sequencer/todo &&
60 test_path_is_file .git/sequencer/opts &&
61 echo "true" >expect &&
62 git config --file=.git/sequencer/opts --get-all options.signoff >actual &&
63 test_cmp expect actual &&
64 echo "1" >expect &&
65 git config --file=.git/sequencer/opts --get-all options.mainline >actual &&
66 test_cmp expect actual &&
67 echo "recursive" >expect &&
68 git config --file=.git/sequencer/opts --get-all options.strategy >actual &&
69 test_cmp expect actual &&
70 cat >expect <<-\EOF &&
71 patience
72 ours
73 EOF
74 git config --file=.git/sequencer/opts --get-all options.strategy-option >actual &&
75 test_cmp expect actual
78 test_expect_success 'cherry-pick cleans up sequencer state upon success' '
79 pristine_detach initial &&
80 git cherry-pick initial..picked &&
81 test_path_is_missing .git/sequencer
84 test_expect_success '--quit does not complain when no cherry-pick is in progress' '
85 pristine_detach initial &&
86 git cherry-pick --quit
89 test_expect_success '--abort requires cherry-pick in progress' '
90 pristine_detach initial &&
91 test_must_fail git cherry-pick --abort
94 test_expect_success '--quit cleans up sequencer state' '
95 pristine_detach initial &&
96 test_must_fail git cherry-pick base..picked &&
97 git cherry-pick --quit &&
98 test_path_is_missing .git/sequencer
101 test_expect_success '--quit keeps HEAD and conflicted index intact' '
102 pristine_detach initial &&
103 cat >expect <<-\EOF &&
104 OBJID
105 :100644 100644 OBJID OBJID M unrelated
106 OBJID
107 :000000 100644 OBJID OBJID A foo
108 :000000 100644 OBJID OBJID A unrelated
110 test_must_fail git cherry-pick base..picked &&
111 git cherry-pick --quit &&
112 test_path_is_missing .git/sequencer &&
113 test_must_fail git update-index --refresh &&
115 git rev-list HEAD |
116 git diff-tree --root --stdin |
117 sed "s/$_x40/OBJID/g"
118 } >actual &&
119 test_cmp expect actual
122 test_expect_success '--abort to cancel multiple cherry-pick' '
123 pristine_detach initial &&
124 test_must_fail git cherry-pick base..anotherpick &&
125 git cherry-pick --abort &&
126 test_path_is_missing .git/sequencer &&
127 test_cmp_rev initial HEAD &&
128 git update-index --refresh &&
129 git diff-index --exit-code HEAD
132 test_expect_success '--abort to cancel single cherry-pick' '
133 pristine_detach initial &&
134 test_must_fail git cherry-pick picked &&
135 git cherry-pick --abort &&
136 test_path_is_missing .git/sequencer &&
137 test_cmp_rev initial HEAD &&
138 git update-index --refresh &&
139 git diff-index --exit-code HEAD
142 test_expect_success 'cherry-pick --abort to cancel multiple revert' '
143 pristine_detach anotherpick &&
144 test_must_fail git revert base..picked &&
145 git cherry-pick --abort &&
146 test_path_is_missing .git/sequencer &&
147 test_cmp_rev anotherpick HEAD &&
148 git update-index --refresh &&
149 git diff-index --exit-code HEAD
152 test_expect_success 'revert --abort works, too' '
153 pristine_detach anotherpick &&
154 test_must_fail git revert base..picked &&
155 git revert --abort &&
156 test_path_is_missing .git/sequencer &&
157 test_cmp_rev anotherpick HEAD
160 test_expect_success '--abort to cancel single revert' '
161 pristine_detach anotherpick &&
162 test_must_fail git revert picked &&
163 git revert --abort &&
164 test_path_is_missing .git/sequencer &&
165 test_cmp_rev anotherpick HEAD &&
166 git update-index --refresh &&
167 git diff-index --exit-code HEAD
170 test_expect_success '--abort keeps unrelated change, easy case' '
171 pristine_detach unrelatedpick &&
172 echo changed >expect &&
173 test_must_fail git cherry-pick picked..yetanotherpick &&
174 echo changed >unrelated &&
175 git cherry-pick --abort &&
176 test_cmp expect unrelated
179 test_expect_success '--abort refuses to clobber unrelated change, harder case' '
180 pristine_detach initial &&
181 echo changed >expect &&
182 test_must_fail git cherry-pick base..anotherpick &&
183 echo changed >unrelated &&
184 test_must_fail git cherry-pick --abort &&
185 test_cmp expect unrelated &&
186 git rev-list HEAD >log &&
187 test_line_count = 2 log &&
188 test_must_fail git update-index --refresh &&
190 git checkout unrelated &&
191 git cherry-pick --abort &&
192 test_cmp_rev initial HEAD
195 test_expect_success 'cherry-pick cleans up sequencer state when one commit is left' '
196 pristine_detach initial &&
197 test_must_fail git cherry-pick base..picked &&
198 test_path_is_missing .git/sequencer &&
199 echo "resolved" >foo &&
200 git add foo &&
201 git commit &&
203 git rev-list HEAD |
204 git diff-tree --root --stdin |
205 sed "s/$_x40/OBJID/g"
206 } >actual &&
207 cat >expect <<-\EOF &&
208 OBJID
209 :100644 100644 OBJID OBJID M foo
210 OBJID
211 :100644 100644 OBJID OBJID M unrelated
212 OBJID
213 :000000 100644 OBJID OBJID A foo
214 :000000 100644 OBJID OBJID A unrelated
216 test_cmp expect actual
219 test_expect_failure '--abort after last commit in sequence' '
220 pristine_detach initial &&
221 test_must_fail git cherry-pick base..picked &&
222 git cherry-pick --abort &&
223 test_path_is_missing .git/sequencer &&
224 test_cmp_rev initial HEAD &&
225 git update-index --refresh &&
226 git diff-index --exit-code HEAD
229 test_expect_success 'cherry-pick does not implicitly stomp an existing operation' '
230 pristine_detach initial &&
231 test_must_fail git cherry-pick base..anotherpick &&
232 test-chmtime -v +0 .git/sequencer >expect &&
233 test_must_fail git cherry-pick unrelatedpick &&
234 test-chmtime -v +0 .git/sequencer >actual &&
235 test_cmp expect actual
238 test_expect_success '--continue complains when no cherry-pick is in progress' '
239 pristine_detach initial &&
240 test_must_fail git cherry-pick --continue
243 test_expect_success '--continue complains when there are unresolved conflicts' '
244 pristine_detach initial &&
245 test_must_fail git cherry-pick base..anotherpick &&
246 test_must_fail git cherry-pick --continue
249 test_expect_success '--continue continues after conflicts are resolved' '
250 pristine_detach initial &&
251 test_must_fail git cherry-pick base..anotherpick &&
252 echo "c" >foo &&
253 git add foo &&
254 git commit &&
255 git cherry-pick --continue &&
256 test_path_is_missing .git/sequencer &&
258 git rev-list HEAD |
259 git diff-tree --root --stdin |
260 sed "s/$_x40/OBJID/g"
261 } >actual &&
262 cat >expect <<-\EOF &&
263 OBJID
264 :100644 100644 OBJID OBJID M foo
265 OBJID
266 :100644 100644 OBJID OBJID M foo
267 OBJID
268 :100644 100644 OBJID OBJID M unrelated
269 OBJID
270 :000000 100644 OBJID OBJID A foo
271 :000000 100644 OBJID OBJID A unrelated
273 test_cmp expect actual
276 test_expect_success '--continue respects opts' '
277 pristine_detach initial &&
278 test_must_fail git cherry-pick -x base..anotherpick &&
279 echo "c" >foo &&
280 git add foo &&
281 git commit &&
282 git cherry-pick --continue &&
283 test_path_is_missing .git/sequencer &&
284 git cat-file commit HEAD >anotherpick_msg &&
285 git cat-file commit HEAD~1 >picked_msg &&
286 git cat-file commit HEAD~2 >unrelatedpick_msg &&
287 git cat-file commit HEAD~3 >initial_msg &&
288 test_must_fail grep "cherry picked from" initial_msg &&
289 grep "cherry picked from" unrelatedpick_msg &&
290 grep "cherry picked from" picked_msg &&
291 grep "cherry picked from" anotherpick_msg
294 test_expect_success '--signoff is not automatically propagated to resolved conflict' '
295 pristine_detach initial &&
296 test_must_fail git cherry-pick --signoff base..anotherpick &&
297 echo "c" >foo &&
298 git add foo &&
299 git commit &&
300 git cherry-pick --continue &&
301 test_path_is_missing .git/sequencer &&
302 git cat-file commit HEAD >anotherpick_msg &&
303 git cat-file commit HEAD~1 >picked_msg &&
304 git cat-file commit HEAD~2 >unrelatedpick_msg &&
305 git cat-file commit HEAD~3 >initial_msg &&
306 test_must_fail grep "Signed-off-by:" initial_msg &&
307 grep "Signed-off-by:" unrelatedpick_msg &&
308 test_must_fail grep "Signed-off-by:" picked_msg &&
309 grep "Signed-off-by:" anotherpick_msg
312 test_expect_success 'malformed instruction sheet 1' '
313 pristine_detach initial &&
314 test_must_fail git cherry-pick base..anotherpick &&
315 echo "resolved" >foo &&
316 git add foo &&
317 git commit &&
318 sed "s/pick /pick/" .git/sequencer/todo >new_sheet &&
319 cp new_sheet .git/sequencer/todo &&
320 test_must_fail git cherry-pick --continue
323 test_expect_success 'malformed instruction sheet 2' '
324 pristine_detach initial &&
325 test_must_fail git cherry-pick base..anotherpick &&
326 echo "resolved" >foo &&
327 git add foo &&
328 git commit &&
329 sed "s/pick/revert/" .git/sequencer/todo >new_sheet &&
330 cp new_sheet .git/sequencer/todo &&
331 test_must_fail git cherry-pick --continue
334 test_expect_success 'malformed instruction sheet 3' '
335 pristine_detach initial &&
336 test_must_fail git cherry-pick base..anotherpick &&
337 echo "resolved" >foo &&
338 git add foo &&
339 git commit &&
340 sed "s/pick \([0-9a-f]*\)/pick $_r10/" .git/sequencer/todo >new_sheet &&
341 cp new_sheet .git/sequencer/todo &&
342 test_must_fail git cherry-pick --continue
345 test_expect_success 'commit descriptions in insn sheet are optional' '
346 pristine_detach initial &&
347 test_must_fail git cherry-pick base..anotherpick &&
348 echo "c" >foo &&
349 git add foo &&
350 git commit &&
351 cut -d" " -f1,2 .git/sequencer/todo >new_sheet &&
352 cp new_sheet .git/sequencer/todo &&
353 git cherry-pick --continue &&
354 test_path_is_missing .git/sequencer &&
355 git rev-list HEAD >commits
356 test_line_count = 4 commits
359 test_expect_success 'revert --continue continues after cherry-pick' '
360 pristine_detach initial &&
361 test_must_fail git cherry-pick base..anotherpick &&
362 echo "c" >foo &&
363 git add foo &&
364 git commit &&
365 git revert --continue &&
366 test_path_is_missing .git/sequencer &&
368 git rev-list HEAD |
369 git diff-tree --root --stdin |
370 sed "s/$_x40/OBJID/g"
371 } >actual &&
372 cat >expect <<-\EOF &&
373 OBJID
374 :100644 100644 OBJID OBJID M foo
375 OBJID
376 :100644 100644 OBJID OBJID M foo
377 OBJID
378 :100644 100644 OBJID OBJID M unrelated
379 OBJID
380 :000000 100644 OBJID OBJID A foo
381 :000000 100644 OBJID OBJID A unrelated
383 test_cmp expect actual
386 test_expect_success 'mixed pick and revert instructions' '
387 pristine_detach initial &&
388 test_must_fail git cherry-pick base..anotherpick &&
389 echo "c" >foo &&
390 git add foo &&
391 git commit &&
392 oldsha=`git rev-parse --short HEAD~1` &&
393 echo "revert $oldsha unrelatedpick" >>.git/sequencer/todo &&
394 git cherry-pick --continue &&
395 test_path_is_missing .git/sequencer &&
397 git rev-list HEAD |
398 git diff-tree --root --stdin |
399 sed "s/$_x40/OBJID/g"
400 } >actual &&
401 cat >expect <<-\EOF &&
402 OBJID
403 :100644 100644 OBJID OBJID M unrelated
404 OBJID
405 :100644 100644 OBJID OBJID M foo
406 OBJID
407 :100644 100644 OBJID OBJID M foo
408 OBJID
409 :100644 100644 OBJID OBJID M unrelated
410 OBJID
411 :000000 100644 OBJID OBJID A foo
412 :000000 100644 OBJID OBJID A unrelated
414 test_cmp expect actual
417 test_done