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 &&
50git branch change &&
51git branch change+rename &&
52
53sed -e "/^g /s/.*/g : master changes a line/" <A >A+ &&
54mv A+ A &&
55git commit -a -m "master updates A" &&
56
57git checkout yellow &&
58rm -f M &&
59git commit -a -m "yellow removes M" &&
60
61git checkout white &&
62sed -e "/^g /s/.*/g : white changes a line/" <A >B &&
63sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
64rm -f A M &&
65git update-index --add --remove A B M N &&
66git commit -m "white renames A->B, M->N" &&
67
68git checkout red &&
69sed -e "/^g /s/.*/g : red changes a line/" <A >B &&
70sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
71rm -f A M &&
72git update-index --add --remove A B M N &&
73git commit -m "red renames A->B, M->N" &&
74
75git checkout blue &&
76sed -e "/^g /s/.*/g : blue changes a line/" <A >C &&
77sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
78rm -f A M &&
79git update-index --add --remove A C M N &&
80git commit -m "blue renames A->C, M->N" &&
81
82git checkout change &&
83sed -e "/^g /s/.*/g : changed line/" <A >A+ &&
84mv A+ A &&
85git commit -q -a -m "changed" &&
86
87git checkout change+rename &&
88sed -e "/^g /s/.*/g : changed line/" <A >B &&
89rm A &&
90git update-index --add B &&
91git commit -q -a -m "changed and renamed" &&
92
93git checkout master'
94
95test_expect_success 'pull renaming branch into unrenaming one' \
96'
97 git show-branch &&
98 test_expect_code 1 git pull . white &&
99 git ls-files -s &&
100 git ls-files -u B >b.stages &&
101 test_line_count = 3 b.stages &&
102 git ls-files -s N >n.stages &&
103 test_line_count = 1 n.stages &&
104 sed -ne "/^g/{
105 p
106 q
107 }" B | grep master &&
108 git diff --exit-code white N
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 test_expect_code 1 git pull . white &&
117 git ls-files -u B >b.stages &&
118 test_line_count = 3 b.stages &&
119 git ls-files -s N >n.stages &&
120 test_line_count = 1 n.stages &&
121 sed -ne "/^g/{
122 p
123 q
124 }" B | grep red &&
125 git diff --exit-code white N
126'
127
128test_expect_success 'pull unrenaming branch into renaming one' \
129'
130 git reset --hard &&
131 git show-branch &&
132 test_expect_code 1 git pull . master &&
133 git ls-files -u B >b.stages &&
134 test_line_count = 3 b.stages &&
135 git ls-files -s N >n.stages &&
136 test_line_count = 1 n.stages &&
137 sed -ne "/^g/{
138 p
139 q
140 }" B | grep red &&
141 git diff --exit-code white N
142'
143
144test_expect_success 'pull conflicting renames' \
145'
146 git reset --hard &&
147 git show-branch &&
148 test_expect_code 1 git pull . blue &&
149 git ls-files -u A >a.stages &&
150 test_line_count = 1 a.stages &&
151 git ls-files -u B >b.stages &&
152 test_line_count = 1 b.stages &&
153 git ls-files -u C >c.stages &&
154 test_line_count = 1 c.stages &&
155 git ls-files -s N >n.stages &&
156 test_line_count = 1 n.stages &&
157 sed -ne "/^g/{
158 p
159 q
160 }" B | grep red &&
161 git diff --exit-code white N
162'
163
164test_expect_success 'interference with untracked working tree file' '
165 git reset --hard &&
166 git show-branch &&
167 echo >A this file should not matter &&
168 test_expect_code 1 git pull . white &&
169 test_path_is_file A
170'
171
172test_expect_success 'interference with untracked working tree file' '
173 git reset --hard &&
174 git checkout white &&
175 git show-branch &&
176 rm -f A &&
177 echo >A this file should not matter &&
178 test_expect_code 1 git pull . red &&
179 test_path_is_file A
180'
181
182test_expect_success 'interference with untracked working tree file' '
183 git reset --hard &&
184 rm -f A M &&
185 git checkout -f master &&
186 git tag -f anchor &&
187 git show-branch &&
188 git pull . yellow &&
189 test_path_is_missing M &&
190 git reset --hard anchor
191'
192
193test_expect_success 'updated working tree file should prevent the merge' '
194 git reset --hard &&
195 rm -f A M &&
196 git checkout -f master &&
197 git tag -f anchor &&
198 git show-branch &&
199 echo >>M one line addition &&
200 cat M >M.saved &&
201 test_expect_code 128 git pull . yellow &&
202 test_cmp M M.saved &&
203 rm -f M.saved
204'
205
206test_expect_success 'updated working tree file should prevent the merge' '
207 git reset --hard &&
208 rm -f A M &&
209 git checkout -f master &&
210 git tag -f anchor &&
211 git show-branch &&
212 echo >>M one line addition &&
213 cat M >M.saved &&
214 git update-index M &&
215 test_expect_code 128 git pull . yellow &&
216 test_cmp M M.saved &&
217 rm -f M.saved
218'
219
220test_expect_success 'interference with untracked working tree file' '
221 git reset --hard &&
222 rm -f A M &&
223 git checkout -f yellow &&
224 git tag -f anchor &&
225 git show-branch &&
226 echo >M this file should not matter &&
227 git pull . master &&
228 test_path_is_file M &&
229 ! {
230 git ls-files -s |
231 grep M
232 } &&
233 git reset --hard anchor
234'
235
236test_expect_success 'merge of identical changes in a renamed file' '
237 rm -f A M N &&
238 git reset --hard &&
239 git checkout change+rename &&
240 GIT_MERGE_VERBOSITY=3 git merge change | grep "^Skipped B" &&
241 git reset --hard HEAD^ &&
242 git checkout change &&
243 GIT_MERGE_VERBOSITY=3 git merge change+rename | grep "^Skipped B"
244'
245
246test_done