Merge branch 'jk/diff-graph-cleanup'
[git] / t / t3507-cherry-pick-conflict.sh
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 config advice.detachedhead false
29
30 '
31
32 test_expect_success 'failed cherry-pick does not advance HEAD' '
33         pristine_detach initial &&
34
35         head=$(git rev-parse HEAD) &&
36         test_must_fail git cherry-pick picked &&
37         newhead=$(git rev-parse HEAD) &&
38
39         test "$head" = "$newhead"
40 '
41
42 test_expect_success 'advice from failed cherry-pick' "
43         pristine_detach initial &&
44
45         picked=\$(git rev-parse --short picked) &&
46         cat <<-EOF >expected &&
47         error: could not apply \$picked... picked
48         hint: after resolving the conflicts, mark the corrected paths
49         hint: with 'git add <paths>' or 'git rm <paths>'
50         hint: and commit the result with 'git commit'
51         EOF
52         test_must_fail git cherry-pick picked 2>actual &&
53
54         test_i18ncmp expected actual
55 "
56
57 test_expect_success 'advice from failed cherry-pick --no-commit' "
58         pristine_detach initial &&
59
60         picked=\$(git rev-parse --short picked) &&
61         cat <<-EOF >expected &&
62         error: could not apply \$picked... picked
63         hint: after resolving the conflicts, mark the corrected paths
64         hint: with 'git add <paths>' or 'git rm <paths>'
65         EOF
66         test_must_fail git cherry-pick --no-commit picked 2>actual &&
67
68         test_i18ncmp expected actual
69 "
70
71 test_expect_success 'failed cherry-pick sets CHERRY_PICK_HEAD' '
72         pristine_detach initial &&
73         test_must_fail git cherry-pick picked &&
74         test_cmp_rev picked CHERRY_PICK_HEAD
75 '
76
77 test_expect_success 'successful cherry-pick does not set CHERRY_PICK_HEAD' '
78         pristine_detach initial &&
79         git cherry-pick base &&
80         test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
81 '
82
83 test_expect_success 'cherry-pick --no-commit does not set CHERRY_PICK_HEAD' '
84         pristine_detach initial &&
85         git cherry-pick --no-commit base &&
86         test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
87 '
88
89 test_expect_success 'cherry-pick w/dirty tree does not set CHERRY_PICK_HEAD' '
90         pristine_detach initial &&
91         echo foo > foo &&
92         test_must_fail git cherry-pick base &&
93         test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
94 '
95
96 test_expect_success \
97         'cherry-pick --strategy=resolve w/dirty tree does not set CHERRY_PICK_HEAD' '
98         pristine_detach initial &&
99         echo foo > foo &&
100         test_must_fail git cherry-pick --strategy=resolve base &&
101         test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
102 '
103
104 test_expect_success 'GIT_CHERRY_PICK_HELP suppresses CHERRY_PICK_HEAD' '
105         pristine_detach initial &&
106         (
107                 GIT_CHERRY_PICK_HELP="and then do something else" &&
108                 export GIT_CHERRY_PICK_HELP &&
109                 test_must_fail git cherry-pick picked
110         ) &&
111         test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
112 '
113
114 test_expect_success 'git reset clears CHERRY_PICK_HEAD' '
115         pristine_detach initial &&
116
117         test_must_fail git cherry-pick picked &&
118         git reset &&
119
120         test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
121 '
122
123 test_expect_success 'failed commit does not clear CHERRY_PICK_HEAD' '
124         pristine_detach initial &&
125
126         test_must_fail git cherry-pick picked &&
127         test_must_fail git commit &&
128
129         test_cmp_rev picked CHERRY_PICK_HEAD
130 '
131
132 test_expect_success 'cancelled commit does not clear CHERRY_PICK_HEAD' '
133         pristine_detach initial &&
134
135         test_must_fail git cherry-pick picked &&
136         echo resolved >foo &&
137         git add foo &&
138         git update-index --refresh -q &&
139         test_must_fail git diff-index --exit-code HEAD &&
140         (
141                 GIT_EDITOR=false &&
142                 export GIT_EDITOR &&
143                 test_must_fail git commit
144         ) &&
145
146         test_cmp_rev picked CHERRY_PICK_HEAD
147 '
148
149 test_expect_success 'successful commit clears CHERRY_PICK_HEAD' '
150         pristine_detach initial &&
151
152         test_must_fail git cherry-pick picked &&
153         echo resolved >foo &&
154         git add foo &&
155         git commit &&
156
157         test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
158 '
159
160 test_expect_success 'failed cherry-pick produces dirty index' '
161         pristine_detach initial &&
162
163         test_must_fail git cherry-pick picked &&
164
165         test_must_fail git update-index --refresh -q &&
166         test_must_fail git diff-index --exit-code HEAD
167 '
168
169 test_expect_success 'failed cherry-pick registers participants in index' '
170         pristine_detach initial &&
171         {
172                 git checkout base -- foo &&
173                 git ls-files --stage foo &&
174                 git checkout initial -- foo &&
175                 git ls-files --stage foo &&
176                 git checkout picked -- foo &&
177                 git ls-files --stage foo
178         } > stages &&
179         sed "
180                 1 s/ 0  / 1     /
181                 2 s/ 0  / 2     /
182                 3 s/ 0  / 3     /
183         " < stages > expected &&
184         git read-tree -u --reset HEAD &&
185
186         test_must_fail git cherry-pick picked &&
187         git ls-files --stage --unmerged > actual &&
188
189         test_cmp expected actual
190 '
191
192 test_expect_success 'failed cherry-pick describes conflict in work tree' '
193         pristine_detach initial &&
194         cat <<-EOF > expected &&
195         <<<<<<< HEAD
196         a
197         =======
198         c
199         >>>>>>> objid picked
200         EOF
201
202         test_must_fail git cherry-pick picked &&
203
204         sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
205         test_cmp expected actual
206 '
207
208 test_expect_success 'diff3 -m style' '
209         pristine_detach initial &&
210         git config merge.conflictstyle diff3 &&
211         cat <<-EOF > expected &&
212         <<<<<<< HEAD
213         a
214         ||||||| parent of objid picked
215         b
216         =======
217         c
218         >>>>>>> objid picked
219         EOF
220
221         test_must_fail git cherry-pick picked &&
222
223         sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
224         test_cmp expected actual
225 '
226
227 test_expect_success 'revert also handles conflicts sanely' '
228         git config --unset merge.conflictstyle &&
229         pristine_detach initial &&
230         cat <<-EOF > expected &&
231         <<<<<<< HEAD
232         a
233         =======
234         b
235         >>>>>>> parent of objid picked
236         EOF
237         {
238                 git checkout picked -- foo &&
239                 git ls-files --stage foo &&
240                 git checkout initial -- foo &&
241                 git ls-files --stage foo &&
242                 git checkout base -- foo &&
243                 git ls-files --stage foo
244         } > stages &&
245         sed "
246                 1 s/ 0  / 1     /
247                 2 s/ 0  / 2     /
248                 3 s/ 0  / 3     /
249         " < stages > expected-stages &&
250         git read-tree -u --reset HEAD &&
251
252         head=$(git rev-parse HEAD) &&
253         test_must_fail git revert picked &&
254         newhead=$(git rev-parse HEAD) &&
255         git ls-files --stage --unmerged > actual-stages &&
256
257         test "$head" = "$newhead" &&
258         test_must_fail git update-index --refresh -q &&
259         test_must_fail git diff-index --exit-code HEAD &&
260         test_cmp expected-stages actual-stages &&
261         sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
262         test_cmp expected actual
263 '
264
265 test_expect_success 'failed revert sets REVERT_HEAD' '
266         pristine_detach initial &&
267         test_must_fail git revert picked &&
268         test_cmp_rev picked REVERT_HEAD
269 '
270
271 test_expect_success 'successful revert does not set REVERT_HEAD' '
272         pristine_detach base &&
273         git revert base &&
274         test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
275         test_must_fail git rev-parse --verify REVERT_HEAD
276 '
277
278 test_expect_success 'revert --no-commit sets REVERT_HEAD' '
279         pristine_detach base &&
280         git revert --no-commit base &&
281         test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
282         test_cmp_rev base REVERT_HEAD
283 '
284
285 test_expect_success 'revert w/dirty tree does not set REVERT_HEAD' '
286         pristine_detach base &&
287         echo foo > foo &&
288         test_must_fail git revert base &&
289         test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
290         test_must_fail git rev-parse --verify REVERT_HEAD
291 '
292
293 test_expect_success 'GIT_CHERRY_PICK_HELP does not suppress REVERT_HEAD' '
294         pristine_detach initial &&
295         (
296                 GIT_CHERRY_PICK_HELP="and then do something else" &&
297                 GIT_REVERT_HELP="and then do something else, again" &&
298                 export GIT_CHERRY_PICK_HELP GIT_REVERT_HELP &&
299                 test_must_fail git revert picked
300         ) &&
301         test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
302         test_cmp_rev picked REVERT_HEAD
303 '
304
305 test_expect_success 'git reset clears REVERT_HEAD' '
306         pristine_detach initial &&
307         test_must_fail git revert picked &&
308         git reset &&
309         test_must_fail git rev-parse --verify REVERT_HEAD
310 '
311
312 test_expect_success 'failed commit does not clear REVERT_HEAD' '
313         pristine_detach initial &&
314         test_must_fail git revert picked &&
315         test_must_fail git commit &&
316         test_cmp_rev picked REVERT_HEAD
317 '
318
319 test_expect_success 'revert conflict, diff3 -m style' '
320         pristine_detach initial &&
321         git config merge.conflictstyle diff3 &&
322         cat <<-EOF > expected &&
323         <<<<<<< HEAD
324         a
325         ||||||| objid picked
326         c
327         =======
328         b
329         >>>>>>> parent of objid picked
330         EOF
331
332         test_must_fail git revert picked &&
333
334         sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
335         test_cmp expected actual
336 '
337
338 test_expect_success 'failed cherry-pick does not forget -s' '
339         pristine_detach initial &&
340         test_must_fail git cherry-pick -s picked &&
341         test_i18ngrep -e "Signed-off-by" .git/MERGE_MSG
342 '
343
344 test_expect_success 'commit after failed cherry-pick does not add duplicated -s' '
345         pristine_detach initial &&
346         test_must_fail git cherry-pick -s picked-signed &&
347         git commit -a -s &&
348         test $(git show -s |grep -c "Signed-off-by") = 1
349 '
350
351 test_expect_success 'commit after failed cherry-pick adds -s at the right place' '
352         pristine_detach initial &&
353         test_must_fail git cherry-pick picked &&
354         git commit -a -s &&
355         pwd &&
356         cat <<EOF > expected &&
357 picked
358
359 Signed-off-by: C O Mitter <committer@example.com>
360
361 Conflicts:
362         foo
363 EOF
364
365         git show -s --pretty=format:%B > actual &&
366         test_cmp expected actual
367 '
368
369 test_done