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