Merge branch 'jc/pickaxe'
[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
51 sed -e "/^g /s/.*/g : master changes a line/" <A >A+ &&
52 mv A+ A &&
53 git commit -a -m "master updates A" &&
54
55 git checkout yellow &&
56 rm -f M &&
57 git commit -a -m "yellow removes M" &&
58
59 git checkout white &&
60 sed -e "/^g /s/.*/g : white changes a line/" <A >B &&
61 sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
62 rm -f A M &&
63 git update-index --add --remove A B M N &&
64 git commit -m "white renames A->B, M->N" &&
65
66 git checkout red &&
67 sed -e "/^g /s/.*/g : red changes a line/" <A >B &&
68 sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
69 rm -f A M &&
70 git update-index --add --remove A B M N &&
71 git commit -m "red renames A->B, M->N" &&
72
73 git checkout blue &&
74 sed -e "/^g /s/.*/g : blue changes a line/" <A >C &&
75 sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
76 rm -f A M &&
77 git update-index --add --remove A C M N &&
78 git commit -m "blue renames A->C, M->N" &&
79
80 git checkout master'
81
82 test_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
111 test_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
141 test_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
170 test_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
207 test_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
222 test_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
239 test_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
257 test_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
277 test_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
298 test_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
321 test_done