1#!/bin/sh
2
3test_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
14test_expect_success setup '
15
16 echo unrelated >unrelated &&
17 git add unrelated &&
18 test_commit initial foo a &&
19 test_commit base foo b &&
20 test_commit picked foo c &&
21 git config advice.detachedhead false
22
23'
24
25test_expect_success 'failed cherry-pick does not advance HEAD' '
26
27 git checkout -f initial^0 &&
28 git read-tree -u --reset HEAD &&
29 git clean -d -f -f -q -x &&
30
31 git update-index --refresh &&
32 git diff-index --exit-code HEAD &&
33
34 head=$(git rev-parse HEAD) &&
35 test_must_fail git cherry-pick picked &&
36 newhead=$(git rev-parse HEAD) &&
37
38 test "$head" = "$newhead"
39'
40
41test_expect_success 'advice from failed cherry-pick' "
42 git checkout -f initial^0 &&
43 git read-tree -u --reset HEAD &&
44 git clean -d -f -f -q -x &&
45
46 git update-index --refresh &&
47 git diff-index --exit-code HEAD &&
48
49 picked=\$(git rev-parse --short picked) &&
50 cat <<-EOF >expected &&
51 error: could not apply \$picked... picked
52 hint: after resolving the conflicts, mark the corrected paths
53 hint: with 'git add <paths>' or 'git rm <paths>'
54 hint: and commit the result with 'git commit -c \$picked'
55 EOF
56 test_must_fail git cherry-pick picked 2>actual &&
57
58 test_cmp expected actual
59"
60
61test_expect_success 'failed cherry-pick produces dirty index' '
62
63 git checkout -f initial^0 &&
64 git read-tree -u --reset HEAD &&
65 git clean -d -f -f -q -x &&
66
67 git update-index --refresh &&
68 git diff-index --exit-code HEAD &&
69
70 test_must_fail git cherry-pick picked &&
71
72 test_must_fail git update-index --refresh -q &&
73 test_must_fail git diff-index --exit-code HEAD
74'
75
76test_expect_success 'failed cherry-pick registers participants in index' '
77
78 git read-tree -u --reset HEAD &&
79 git clean -d -f -f -q -x &&
80 {
81 git checkout base -- foo &&
82 git ls-files --stage foo &&
83 git checkout initial -- foo &&
84 git ls-files --stage foo &&
85 git checkout picked -- foo &&
86 git ls-files --stage foo
87 } > stages &&
88 sed "
89 1 s/ 0 / 1 /
90 2 s/ 0 / 2 /
91 3 s/ 0 / 3 /
92 " < stages > expected &&
93 git checkout -f initial^0 &&
94
95 git update-index --refresh &&
96 git diff-index --exit-code HEAD &&
97
98 test_must_fail git cherry-pick picked &&
99 git ls-files --stage --unmerged > actual &&
100
101 test_cmp expected actual
102'
103
104test_expect_success 'failed cherry-pick describes conflict in work tree' '
105
106 git checkout -f initial^0 &&
107 git read-tree -u --reset HEAD &&
108 git clean -d -f -f -q -x &&
109 cat <<-EOF > expected &&
110 <<<<<<< HEAD
111 a
112 =======
113 c
114 >>>>>>> objid picked
115 EOF
116
117 git update-index --refresh &&
118 git diff-index --exit-code HEAD &&
119
120 test_must_fail git cherry-pick picked &&
121
122 sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
123 test_cmp expected actual
124'
125
126test_expect_success 'diff3 -m style' '
127
128 git config merge.conflictstyle diff3 &&
129 git checkout -f initial^0 &&
130 git read-tree -u --reset HEAD &&
131 git clean -d -f -f -q -x &&
132 cat <<-EOF > expected &&
133 <<<<<<< HEAD
134 a
135 ||||||| parent of objid picked
136 b
137 =======
138 c
139 >>>>>>> objid picked
140 EOF
141
142 git update-index --refresh &&
143 git diff-index --exit-code HEAD &&
144
145 test_must_fail git cherry-pick picked &&
146
147 sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
148 test_cmp expected actual
149'
150
151test_expect_success 'revert also handles conflicts sanely' '
152
153 git config --unset merge.conflictstyle &&
154 git read-tree -u --reset HEAD &&
155 git clean -d -f -f -q -x &&
156 cat <<-EOF > expected &&
157 <<<<<<< HEAD
158 a
159 =======
160 b
161 >>>>>>> parent of objid picked
162 EOF
163 {
164 git checkout picked -- foo &&
165 git ls-files --stage foo &&
166 git checkout initial -- foo &&
167 git ls-files --stage foo &&
168 git checkout base -- foo &&
169 git ls-files --stage foo
170 } > stages &&
171 sed "
172 1 s/ 0 / 1 /
173 2 s/ 0 / 2 /
174 3 s/ 0 / 3 /
175 " < stages > expected-stages &&
176 git checkout -f initial^0 &&
177
178 git update-index --refresh &&
179 git diff-index --exit-code HEAD &&
180
181 head=$(git rev-parse HEAD) &&
182 test_must_fail git revert picked &&
183 newhead=$(git rev-parse HEAD) &&
184 git ls-files --stage --unmerged > actual-stages &&
185
186 test "$head" = "$newhead" &&
187 test_must_fail git update-index --refresh -q &&
188 test_must_fail git diff-index --exit-code HEAD &&
189 test_cmp expected-stages actual-stages &&
190 sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
191 test_cmp expected actual
192'
193
194test_expect_success 'revert conflict, diff3 -m style' '
195 git config merge.conflictstyle diff3 &&
196 git checkout -f initial^0 &&
197 git read-tree -u --reset HEAD &&
198 git clean -d -f -f -q -x &&
199 cat <<-EOF > expected &&
200 <<<<<<< HEAD
201 a
202 ||||||| objid picked
203 c
204 =======
205 b
206 >>>>>>> parent of objid picked
207 EOF
208
209 git update-index --refresh &&
210 git diff-index --exit-code HEAD &&
211
212 test_must_fail git revert picked &&
213
214 sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
215 test_cmp expected actual
216'
217
218test_done