Merge branch 'js/checkout-untracked-symlink'
[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 test_cmp_rev () {
15         git rev-parse --verify "$1" >expect.rev &&
16         git rev-parse --verify "$2" >actual.rev &&
17         test_cmp expect.rev actual.rev
18 }
19
20 pristine_detach () {
21         git checkout -f "$1^0" &&
22         git read-tree -u --reset HEAD &&
23         git clean -d -f -f -q -x
24 }
25
26 test_expect_success setup '
27
28         echo unrelated >unrelated &&
29         git add unrelated &&
30         test_commit initial foo a &&
31         test_commit base foo b &&
32         test_commit picked foo c &&
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 C_LOCALE_OUTPUT '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_cmp expected actual
60 "
61
62 test_expect_success 'failed cherry-pick sets CHERRY_PICK_HEAD' '
63         pristine_detach initial &&
64         test_must_fail git cherry-pick picked &&
65         test_cmp_rev picked CHERRY_PICK_HEAD
66 '
67
68 test_expect_success 'successful cherry-pick does not set CHERRY_PICK_HEAD' '
69         pristine_detach initial &&
70         git cherry-pick base &&
71         test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
72 '
73
74 test_expect_success 'cherry-pick --no-commit does not set CHERRY_PICK_HEAD' '
75         pristine_detach initial &&
76         git cherry-pick --no-commit base &&
77         test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
78 '
79
80 test_expect_success 'GIT_CHERRY_PICK_HELP suppresses CHERRY_PICK_HEAD' '
81         pristine_detach initial &&
82         (
83                 GIT_CHERRY_PICK_HELP="and then do something else" &&
84                 export GIT_CHERRY_PICK_HELP &&
85                 test_must_fail git cherry-pick picked
86         ) &&
87         test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
88 '
89
90 test_expect_success 'git reset clears CHERRY_PICK_HEAD' '
91         pristine_detach initial &&
92
93         test_must_fail git cherry-pick picked &&
94         git reset &&
95
96         test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
97 '
98
99 test_expect_success 'failed commit does not clear CHERRY_PICK_HEAD' '
100         pristine_detach initial &&
101
102         test_must_fail git cherry-pick picked &&
103         test_must_fail git commit &&
104
105         test_cmp_rev picked CHERRY_PICK_HEAD
106 '
107
108 test_expect_success 'cancelled commit does not clear CHERRY_PICK_HEAD' '
109         pristine_detach initial &&
110
111         test_must_fail git cherry-pick picked &&
112         echo resolved >foo &&
113         git add foo &&
114         git update-index --refresh -q &&
115         test_must_fail git diff-index --exit-code HEAD &&
116         (
117                 GIT_EDITOR=false &&
118                 export GIT_EDITOR &&
119                 test_must_fail git commit
120         ) &&
121
122         test_cmp_rev picked CHERRY_PICK_HEAD
123 '
124
125 test_expect_success 'successful commit clears CHERRY_PICK_HEAD' '
126         pristine_detach initial &&
127
128         test_must_fail git cherry-pick picked &&
129         echo resolved >foo &&
130         git add foo &&
131         git commit &&
132
133         test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
134 '
135
136 test_expect_success 'failed cherry-pick produces dirty index' '
137         pristine_detach initial &&
138
139         test_must_fail git cherry-pick picked &&
140
141         test_must_fail git update-index --refresh -q &&
142         test_must_fail git diff-index --exit-code HEAD
143 '
144
145 test_expect_success 'failed cherry-pick registers participants in index' '
146         pristine_detach initial &&
147         {
148                 git checkout base -- foo &&
149                 git ls-files --stage foo &&
150                 git checkout initial -- foo &&
151                 git ls-files --stage foo &&
152                 git checkout picked -- foo &&
153                 git ls-files --stage foo
154         } > stages &&
155         sed "
156                 1 s/ 0  / 1     /
157                 2 s/ 0  / 2     /
158                 3 s/ 0  / 3     /
159         " < stages > expected &&
160         git read-tree -u --reset HEAD &&
161
162         test_must_fail git cherry-pick picked &&
163         git ls-files --stage --unmerged > actual &&
164
165         test_cmp expected actual
166 '
167
168 test_expect_success 'failed cherry-pick describes conflict in work tree' '
169         pristine_detach initial &&
170         cat <<-EOF > expected &&
171         <<<<<<< HEAD
172         a
173         =======
174         c
175         >>>>>>> objid picked
176         EOF
177
178         test_must_fail git cherry-pick picked &&
179
180         sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
181         test_cmp expected actual
182 '
183
184 test_expect_success 'diff3 -m style' '
185         pristine_detach initial &&
186         git config merge.conflictstyle diff3 &&
187         cat <<-EOF > expected &&
188         <<<<<<< HEAD
189         a
190         ||||||| parent of objid picked
191         b
192         =======
193         c
194         >>>>>>> objid picked
195         EOF
196
197         test_must_fail git cherry-pick picked &&
198
199         sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
200         test_cmp expected actual
201 '
202
203 test_expect_success 'revert also handles conflicts sanely' '
204         git config --unset merge.conflictstyle &&
205         pristine_detach initial &&
206         cat <<-EOF > expected &&
207         <<<<<<< HEAD
208         a
209         =======
210         b
211         >>>>>>> parent of objid picked
212         EOF
213         {
214                 git checkout picked -- foo &&
215                 git ls-files --stage foo &&
216                 git checkout initial -- foo &&
217                 git ls-files --stage foo &&
218                 git checkout base -- foo &&
219                 git ls-files --stage foo
220         } > stages &&
221         sed "
222                 1 s/ 0  / 1     /
223                 2 s/ 0  / 2     /
224                 3 s/ 0  / 3     /
225         " < stages > expected-stages &&
226         git read-tree -u --reset HEAD &&
227
228         head=$(git rev-parse HEAD) &&
229         test_must_fail git revert picked &&
230         newhead=$(git rev-parse HEAD) &&
231         git ls-files --stage --unmerged > actual-stages &&
232
233         test "$head" = "$newhead" &&
234         test_must_fail git update-index --refresh -q &&
235         test_must_fail git diff-index --exit-code HEAD &&
236         test_cmp expected-stages actual-stages &&
237         sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
238         test_cmp expected actual
239 '
240
241 test_expect_success 'revert conflict, diff3 -m style' '
242         pristine_detach initial &&
243         git config merge.conflictstyle diff3 &&
244         cat <<-EOF > expected &&
245         <<<<<<< HEAD
246         a
247         ||||||| objid picked
248         c
249         =======
250         b
251         >>>>>>> parent of objid picked
252         EOF
253
254         test_must_fail git revert picked &&
255
256         sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
257         test_cmp expected actual
258 '
259
260 test_done