Merge branch 'jc/maint-1.6.3-graft-trailing-space' into maint
[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