1#!/bin/sh
2
3test_description='Merge-recursive merging renames'
4. ./test-lib.sh
5
6test_expect_success setup \
7'
8cat >A <<\EOF &&
9a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
10b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
11c cccccccccccccccccccccccccccccccccccccccccccccccc
12d dddddddddddddddddddddddddddddddddddddddddddddddd
13e eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
14f ffffffffffffffffffffffffffffffffffffffffffffffff
15g gggggggggggggggggggggggggggggggggggggggggggggggg
16h hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
17i iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
18j jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
19k kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
20l llllllllllllllllllllllllllllllllllllllllllllllll
21m mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
22n nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
23o oooooooooooooooooooooooooooooooooooooooooooooooo
24EOF
25
26cat >M <<\EOF &&
27A AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
28B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
29C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
30D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
31E EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
32F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
33G GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
34H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
35I IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
36J JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
37K KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
38L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
39M MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
40N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
41O OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
42EOF
43
44git add A M &&
45git commit -m "initial has A and M" &&
46git branch white &&
47git branch red &&
48git branch blue &&
49git branch yellow &&
50
51sed -e "/^g /s/.*/g : master changes a line/" <A >A+ &&
52mv A+ A &&
53git commit -a -m "master updates A" &&
54
55git checkout yellow &&
56rm -f M &&
57git commit -a -m "yellow removes M" &&
58
59git checkout white &&
60sed -e "/^g /s/.*/g : white changes a line/" <A >B &&
61sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
62rm -f A M &&
63git update-index --add --remove A B M N &&
64git commit -m "white renames A->B, M->N" &&
65
66git checkout red &&
67sed -e "/^g /s/.*/g : red changes a line/" <A >B &&
68sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
69rm -f A M &&
70git update-index --add --remove A B M N &&
71git commit -m "red renames A->B, M->N" &&
72
73git checkout blue &&
74sed -e "/^g /s/.*/g : blue changes a line/" <A >C &&
75sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
76rm -f A M &&
77git update-index --add --remove A C M N &&
78git commit -m "blue renames A->C, M->N" &&
79
80git checkout master'
81
82test_expect_success 'pull renaming branch into unrenaming one' \
83'
84 git show-branch
85 git pull . white && {
86 echo "BAD: should have conflicted"
87 return 1
88 }
89 git ls-files -s
90 test "$(git ls-files -u B | wc -l)" -eq 3 || {
91 echo "BAD: should have left stages for B"
92 return 1
93 }
94 test "$(git ls-files -s N | wc -l)" -eq 1 || {
95 echo "BAD: should have merged N"
96 return 1
97 }
98 sed -ne "/^g/{
99 p
100 q
101 }" B | grep master || {
102 echo "BAD: should have listed our change first"
103 return 1
104 }
105 test "$(git diff white N | wc -l)" -eq 0 || {
106 echo "BAD: should have taken colored branch"
107 return 1
108 }
109'
110
111test_expect_success 'pull renaming branch into another renaming one' \
112'
113 rm -f B
114 git reset --hard
115 git checkout red
116 git pull . white && {
117 echo "BAD: should have conflicted"
118 return 1
119 }
120 test "$(git ls-files -u B | wc -l)" -eq 3 || {
121 echo "BAD: should have left stages"
122 return 1
123 }
124 test "$(git ls-files -s N | wc -l)" -eq 1 || {
125 echo "BAD: should have merged N"
126 return 1
127 }
128 sed -ne "/^g/{
129 p
130 q
131 }" B | grep red || {
132 echo "BAD: should have listed our change first"
133 return 1
134 }
135 test "$(git diff white N | wc -l)" -eq 0 || {
136 echo "BAD: should have taken colored branch"
137 return 1
138 }
139'
140
141test_expect_success 'pull unrenaming branch into renaming one' \
142'
143 git reset --hard
144 git show-branch
145 git pull . master && {
146 echo "BAD: should have conflicted"
147 return 1
148 }
149 test "$(git ls-files -u B | wc -l)" -eq 3 || {
150 echo "BAD: should have left stages"
151 return 1
152 }
153 test "$(git ls-files -s N | wc -l)" -eq 1 || {
154 echo "BAD: should have merged N"
155 return 1
156 }
157 sed -ne "/^g/{
158 p
159 q
160 }" B | grep red || {
161 echo "BAD: should have listed our change first"
162 return 1
163 }
164 test "$(git diff white N | wc -l)" -eq 0 || {
165 echo "BAD: should have taken colored branch"
166 return 1
167 }
168'
169
170test_expect_success 'pull conflicting renames' \
171'
172 git reset --hard
173 git show-branch
174 git pull . blue && {
175 echo "BAD: should have conflicted"
176 return 1
177 }
178 test "$(git ls-files -u A | wc -l)" -eq 1 || {
179 echo "BAD: should have left a stage"
180 return 1
181 }
182 test "$(git ls-files -u B | wc -l)" -eq 1 || {
183 echo "BAD: should have left a stage"
184 return 1
185 }
186 test "$(git ls-files -u C | wc -l)" -eq 1 || {
187 echo "BAD: should have left a stage"
188 return 1
189 }
190 test "$(git ls-files -s N | wc -l)" -eq 1 || {
191 echo "BAD: should have merged N"
192 return 1
193 }
194 sed -ne "/^g/{
195 p
196 q
197 }" B | grep red || {
198 echo "BAD: should have listed our change first"
199 return 1
200 }
201 test "$(git diff white N | wc -l)" -eq 0 || {
202 echo "BAD: should have taken colored branch"
203 return 1
204 }
205'
206
207test_expect_success 'interference with untracked working tree file' '
208
209 git reset --hard
210 git show-branch
211 echo >A this file should not matter
212 git pull . white && {
213 echo "BAD: should have conflicted"
214 return 1
215 }
216 test -f A || {
217 echo "BAD: should have left A intact"
218 return 1
219 }
220'
221
222test_expect_success 'interference with untracked working tree file' '
223
224 git reset --hard
225 git checkout white
226 git show-branch
227 rm -f A
228 echo >A this file should not matter
229 git pull . red && {
230 echo "BAD: should have conflicted"
231 return 1
232 }
233 test -f A || {
234 echo "BAD: should have left A intact"
235 return 1
236 }
237'
238
239test_expect_success 'interference with untracked working tree file' '
240
241 git reset --hard
242 rm -f A M
243 git checkout -f master
244 git tag -f anchor
245 git show-branch
246 git pull . yellow || {
247 echo "BAD: should have cleanly merged"
248 return 1
249 }
250 test -f M && {
251 echo "BAD: should have removed M"
252 return 1
253 }
254 git reset --hard anchor
255'
256
257test_expect_success 'updated working tree file should prevent the merge' '
258
259 git reset --hard
260 rm -f A M
261 git checkout -f master
262 git tag -f anchor
263 git show-branch
264 echo >>M one line addition
265 cat M >M.saved
266 git pull . yellow && {
267 echo "BAD: should have complained"
268 return 1
269 }
270 diff M M.saved || {
271 echo "BAD: should have left M intact"
272 return 1
273 }
274 rm -f M.saved
275'
276
277test_expect_success 'updated working tree file should prevent the merge' '
278
279 git reset --hard
280 rm -f A M
281 git checkout -f master
282 git tag -f anchor
283 git show-branch
284 echo >>M one line addition
285 cat M >M.saved
286 git update-index M
287 git pull . yellow && {
288 echo "BAD: should have complained"
289 return 1
290 }
291 diff M M.saved || {
292 echo "BAD: should have left M intact"
293 return 1
294 }
295 rm -f M.saved
296'
297
298test_expect_success 'interference with untracked working tree file' '
299
300 git reset --hard
301 rm -f A M
302 git checkout -f yellow
303 git tag -f anchor
304 git show-branch
305 echo >M this file should not matter
306 git pull . master || {
307 echo "BAD: should have cleanly merged"
308 return 1
309 }
310 test -f M || {
311 echo "BAD: should have left M intact"
312 return 1
313 }
314 git ls-files -s | grep M && {
315 echo "BAD: M must be untracked in the result"
316 return 1
317 }
318 git reset --hard anchor
319'
320
321test_done