]>
Commit | Line | Data |
---|---|---|
04550ab5 EN |
1 | #!/bin/sh |
2 | ||
3 | test_description="recursive merge with directory renames" | |
4 | # includes checking of many corner cases, with a similar methodology to: | |
5 | # t6042: corner cases with renames but not criss-cross merges | |
6 | # t6036: corner cases with both renames and criss-cross merges | |
7 | # | |
8 | # The setup for all of them, pictorially, is: | |
9 | # | |
10 | # A | |
11 | # o | |
12 | # / \ | |
13 | # O o ? | |
14 | # \ / | |
15 | # o | |
16 | # B | |
17 | # | |
18 | # To help make it easier to follow the flow of tests, they have been | |
19 | # divided into sections and each test will start with a quick explanation | |
20 | # of what commits O, A, and B contain. | |
21 | # | |
22 | # Notation: | |
23 | # z/{b,c} means files z/b and z/c both exist | |
24 | # x/d_1 means file x/d exists with content d1. (Purpose of the | |
25 | # underscore notation is to differentiate different | |
26 | # files that might be renamed into each other's paths.) | |
27 | ||
28 | . ./test-lib.sh | |
29 | ||
30 | ||
31 | ########################################################################### | |
32 | # SECTION 1: Basic cases we should be able to handle | |
33 | ########################################################################### | |
34 | ||
35 | # Testcase 1a, Basic directory rename. | |
36 | # Commit O: z/{b,c} | |
37 | # Commit A: y/{b,c} | |
38 | # Commit B: z/{b,c,d,e/f} | |
39 | # Expected: y/{b,c,d,e/f} | |
40 | ||
41 | test_expect_success '1a-setup: Simple directory rename detection' ' | |
42 | test_create_repo 1a && | |
43 | ( | |
44 | cd 1a && | |
45 | ||
46 | mkdir z && | |
47 | echo b >z/b && | |
48 | echo c >z/c && | |
49 | git add z && | |
50 | test_tick && | |
51 | git commit -m "O" && | |
52 | ||
53 | git branch O && | |
54 | git branch A && | |
55 | git branch B && | |
56 | ||
57 | git checkout A && | |
58 | git mv z y && | |
59 | test_tick && | |
60 | git commit -m "A" && | |
61 | ||
62 | git checkout B && | |
63 | echo d >z/d && | |
64 | mkdir z/e && | |
65 | echo f >z/e/f && | |
66 | git add z/d z/e/f && | |
67 | test_tick && | |
68 | git commit -m "B" | |
69 | ) | |
70 | ' | |
71 | ||
72 | test_expect_failure '1a-check: Simple directory rename detection' ' | |
73 | ( | |
74 | cd 1a && | |
75 | ||
76 | git checkout A^0 && | |
77 | ||
78 | git merge -s recursive B^0 && | |
79 | ||
80 | git ls-files -s >out && | |
81 | test_line_count = 4 out && | |
82 | ||
83 | git rev-parse >actual \ | |
84 | HEAD:y/b HEAD:y/c HEAD:y/d HEAD:y/e/f && | |
85 | git rev-parse >expect \ | |
86 | O:z/b O:z/c B:z/d B:z/e/f && | |
87 | test_cmp expect actual && | |
88 | ||
89 | git hash-object y/d >actual && | |
90 | git rev-parse B:z/d >expect && | |
91 | test_cmp expect actual && | |
92 | ||
93 | test_must_fail git rev-parse HEAD:z/d && | |
94 | test_must_fail git rev-parse HEAD:z/e/f && | |
95 | test_path_is_missing z/d && | |
96 | test_path_is_missing z/e/f | |
97 | ) | |
98 | ' | |
99 | ||
100 | # Testcase 1b, Merge a directory with another | |
101 | # Commit O: z/{b,c}, y/d | |
102 | # Commit A: z/{b,c,e}, y/d | |
103 | # Commit B: y/{b,c,d} | |
104 | # Expected: y/{b,c,d,e} | |
105 | ||
106 | test_expect_success '1b-setup: Merge a directory with another' ' | |
107 | test_create_repo 1b && | |
108 | ( | |
109 | cd 1b && | |
110 | ||
111 | mkdir z && | |
112 | echo b >z/b && | |
113 | echo c >z/c && | |
114 | mkdir y && | |
115 | echo d >y/d && | |
116 | git add z y && | |
117 | test_tick && | |
118 | git commit -m "O" && | |
119 | ||
120 | git branch O && | |
121 | git branch A && | |
122 | git branch B && | |
123 | ||
124 | git checkout A && | |
125 | echo e >z/e && | |
126 | git add z/e && | |
127 | test_tick && | |
128 | git commit -m "A" && | |
129 | ||
130 | git checkout B && | |
131 | git mv z/b y && | |
132 | git mv z/c y && | |
133 | rmdir z && | |
134 | test_tick && | |
135 | git commit -m "B" | |
136 | ) | |
137 | ' | |
138 | ||
139 | test_expect_failure '1b-check: Merge a directory with another' ' | |
140 | ( | |
141 | cd 1b && | |
142 | ||
143 | git checkout A^0 && | |
144 | ||
145 | git merge -s recursive B^0 && | |
146 | ||
147 | git ls-files -s >out && | |
148 | test_line_count = 4 out && | |
149 | ||
150 | git rev-parse >actual \ | |
151 | HEAD:y/b HEAD:y/c HEAD:y/d HEAD:y/e && | |
152 | git rev-parse >expect \ | |
153 | O:z/b O:z/c O:y/d A:z/e && | |
154 | test_cmp expect actual && | |
155 | test_must_fail git rev-parse HEAD:z/e | |
156 | ) | |
157 | ' | |
158 | ||
159 | # Testcase 1c, Transitive renaming | |
160 | # (Related to testcases 3a and 6d -- when should a transitive rename apply?) | |
161 | # (Related to testcases 9c and 9d -- can transitivity repeat?) | |
162 | # Commit O: z/{b,c}, x/d | |
163 | # Commit A: y/{b,c}, x/d | |
164 | # Commit B: z/{b,c,d} | |
165 | # Expected: y/{b,c,d} (because x/d -> z/d -> y/d) | |
166 | ||
167 | test_expect_success '1c-setup: Transitive renaming' ' | |
168 | test_create_repo 1c && | |
169 | ( | |
170 | cd 1c && | |
171 | ||
172 | mkdir z && | |
173 | echo b >z/b && | |
174 | echo c >z/c && | |
175 | mkdir x && | |
176 | echo d >x/d && | |
177 | git add z x && | |
178 | test_tick && | |
179 | git commit -m "O" && | |
180 | ||
181 | git branch O && | |
182 | git branch A && | |
183 | git branch B && | |
184 | ||
185 | git checkout A && | |
186 | git mv z y && | |
187 | test_tick && | |
188 | git commit -m "A" && | |
189 | ||
190 | git checkout B && | |
191 | git mv x/d z/d && | |
192 | test_tick && | |
193 | git commit -m "B" | |
194 | ) | |
195 | ' | |
196 | ||
197 | test_expect_failure '1c-check: Transitive renaming' ' | |
198 | ( | |
199 | cd 1c && | |
200 | ||
201 | git checkout A^0 && | |
202 | ||
203 | git merge -s recursive B^0 && | |
204 | ||
205 | git ls-files -s >out && | |
206 | test_line_count = 3 out && | |
207 | ||
208 | git rev-parse >actual \ | |
209 | HEAD:y/b HEAD:y/c HEAD:y/d && | |
210 | git rev-parse >expect \ | |
211 | O:z/b O:z/c O:x/d && | |
212 | test_cmp expect actual && | |
213 | test_must_fail git rev-parse HEAD:x/d && | |
214 | test_must_fail git rev-parse HEAD:z/d && | |
215 | test_path_is_missing z/d | |
216 | ) | |
217 | ' | |
218 | ||
219 | # Testcase 1d, Directory renames (merging two directories into one new one) | |
220 | # cause a rename/rename(2to1) conflict | |
221 | # (Related to testcases 1c and 7b) | |
222 | # Commit O. z/{b,c}, y/{d,e} | |
223 | # Commit A. x/{b,c}, y/{d,e,m,wham_1} | |
224 | # Commit B. z/{b,c,n,wham_2}, x/{d,e} | |
225 | # Expected: x/{b,c,d,e,m,n}, CONFLICT:(y/wham_1 & z/wham_2 -> x/wham) | |
226 | # Note: y/m & z/n should definitely move into x. By the same token, both | |
227 | # y/wham_1 & z/wham_2 should too...giving us a conflict. | |
228 | ||
229 | test_expect_success '1d-setup: Directory renames cause a rename/rename(2to1) conflict' ' | |
230 | test_create_repo 1d && | |
231 | ( | |
232 | cd 1d && | |
233 | ||
234 | mkdir z && | |
235 | echo b >z/b && | |
236 | echo c >z/c && | |
237 | mkdir y && | |
238 | echo d >y/d && | |
239 | echo e >y/e && | |
240 | git add z y && | |
241 | test_tick && | |
242 | git commit -m "O" && | |
243 | ||
244 | git branch O && | |
245 | git branch A && | |
246 | git branch B && | |
247 | ||
248 | git checkout A && | |
249 | git mv z x && | |
250 | echo m >y/m && | |
251 | echo wham1 >y/wham && | |
252 | git add y && | |
253 | test_tick && | |
254 | git commit -m "A" && | |
255 | ||
256 | git checkout B && | |
257 | git mv y x && | |
258 | echo n >z/n && | |
259 | echo wham2 >z/wham && | |
260 | git add z && | |
261 | test_tick && | |
262 | git commit -m "B" | |
263 | ) | |
264 | ' | |
265 | ||
266 | test_expect_failure '1d-check: Directory renames cause a rename/rename(2to1) conflict' ' | |
267 | ( | |
268 | cd 1d && | |
269 | ||
270 | git checkout A^0 && | |
271 | ||
272 | test_must_fail git merge -s recursive B^0 >out && | |
273 | test_i18ngrep "CONFLICT (rename/rename)" out && | |
274 | ||
275 | git ls-files -s >out && | |
276 | test_line_count = 8 out && | |
277 | git ls-files -u >out && | |
278 | test_line_count = 2 out && | |
279 | git ls-files -o >out && | |
280 | test_line_count = 3 out && | |
281 | ||
282 | git rev-parse >actual \ | |
283 | :0:x/b :0:x/c :0:x/d :0:x/e :0:x/m :0:x/n && | |
284 | git rev-parse >expect \ | |
285 | O:z/b O:z/c O:y/d O:y/e A:y/m B:z/n && | |
286 | test_cmp expect actual && | |
287 | ||
288 | test_must_fail git rev-parse :0:x/wham && | |
289 | git rev-parse >actual \ | |
290 | :2:x/wham :3:x/wham && | |
291 | git rev-parse >expect \ | |
292 | A:y/wham B:z/wham && | |
293 | test_cmp expect actual && | |
294 | ||
295 | test_path_is_missing x/wham && | |
296 | test_path_is_file x/wham~HEAD && | |
297 | test_path_is_file x/wham~B^0 && | |
298 | ||
299 | git hash-object >actual \ | |
300 | x/wham~HEAD x/wham~B^0 && | |
301 | git rev-parse >expect \ | |
302 | A:y/wham B:z/wham && | |
303 | test_cmp expect actual | |
304 | ) | |
305 | ' | |
306 | ||
307 | # Testcase 1e, Renamed directory, with all filenames being renamed too | |
308 | # Commit O: z/{oldb,oldc} | |
309 | # Commit A: y/{newb,newc} | |
310 | # Commit B: z/{oldb,oldc,d} | |
311 | # Expected: y/{newb,newc,d} | |
312 | ||
313 | test_expect_success '1e-setup: Renamed directory, with all files being renamed too' ' | |
314 | test_create_repo 1e && | |
315 | ( | |
316 | cd 1e && | |
317 | ||
318 | mkdir z && | |
319 | echo b >z/oldb && | |
320 | echo c >z/oldc && | |
321 | git add z && | |
322 | test_tick && | |
323 | git commit -m "O" && | |
324 | ||
325 | git branch O && | |
326 | git branch A && | |
327 | git branch B && | |
328 | ||
329 | git checkout A && | |
330 | mkdir y && | |
331 | git mv z/oldb y/newb && | |
332 | git mv z/oldc y/newc && | |
333 | test_tick && | |
334 | git commit -m "A" && | |
335 | ||
336 | git checkout B && | |
337 | echo d >z/d && | |
338 | git add z/d && | |
339 | test_tick && | |
340 | git commit -m "B" | |
341 | ) | |
342 | ' | |
343 | ||
344 | test_expect_failure '1e-check: Renamed directory, with all files being renamed too' ' | |
345 | ( | |
346 | cd 1e && | |
347 | ||
348 | git checkout A^0 && | |
349 | ||
350 | git merge -s recursive B^0 && | |
351 | ||
352 | git ls-files -s >out && | |
353 | test_line_count = 3 out && | |
354 | ||
355 | git rev-parse >actual \ | |
356 | HEAD:y/newb HEAD:y/newc HEAD:y/d && | |
357 | git rev-parse >expect \ | |
358 | O:z/oldb O:z/oldc B:z/d && | |
359 | test_cmp expect actual && | |
360 | test_must_fail git rev-parse HEAD:z/d | |
361 | ) | |
362 | ' | |
363 | ||
364 | # Testcase 1f, Split a directory into two other directories | |
365 | # (Related to testcases 3a, all of section 2, and all of section 4) | |
366 | # Commit O: z/{b,c,d,e,f} | |
367 | # Commit A: z/{b,c,d,e,f,g} | |
368 | # Commit B: y/{b,c}, x/{d,e,f} | |
369 | # Expected: y/{b,c}, x/{d,e,f,g} | |
370 | ||
371 | test_expect_success '1f-setup: Split a directory into two other directories' ' | |
372 | test_create_repo 1f && | |
373 | ( | |
374 | cd 1f && | |
375 | ||
376 | mkdir z && | |
377 | echo b >z/b && | |
378 | echo c >z/c && | |
379 | echo d >z/d && | |
380 | echo e >z/e && | |
381 | echo f >z/f && | |
382 | git add z && | |
383 | test_tick && | |
384 | git commit -m "O" && | |
385 | ||
386 | git branch O && | |
387 | git branch A && | |
388 | git branch B && | |
389 | ||
390 | git checkout A && | |
391 | echo g >z/g && | |
392 | git add z/g && | |
393 | test_tick && | |
394 | git commit -m "A" && | |
395 | ||
396 | git checkout B && | |
397 | mkdir y && | |
398 | mkdir x && | |
399 | git mv z/b y/ && | |
400 | git mv z/c y/ && | |
401 | git mv z/d x/ && | |
402 | git mv z/e x/ && | |
403 | git mv z/f x/ && | |
404 | rmdir z && | |
405 | test_tick && | |
406 | git commit -m "B" | |
407 | ) | |
408 | ' | |
409 | ||
410 | test_expect_failure '1f-check: Split a directory into two other directories' ' | |
411 | ( | |
412 | cd 1f && | |
413 | ||
414 | git checkout A^0 && | |
415 | ||
416 | git merge -s recursive B^0 && | |
417 | ||
418 | git ls-files -s >out && | |
419 | test_line_count = 6 out && | |
420 | ||
421 | git rev-parse >actual \ | |
422 | HEAD:y/b HEAD:y/c HEAD:x/d HEAD:x/e HEAD:x/f HEAD:x/g && | |
423 | git rev-parse >expect \ | |
424 | O:z/b O:z/c O:z/d O:z/e O:z/f A:z/g && | |
425 | test_cmp expect actual && | |
426 | test_path_is_missing z/g && | |
427 | test_must_fail git rev-parse HEAD:z/g | |
428 | ) | |
429 | ' | |
430 | ||
431 | ########################################################################### | |
432 | # Rules suggested by testcases in section 1: | |
433 | # | |
434 | # We should still detect the directory rename even if it wasn't just | |
435 | # the directory renamed, but the files within it. (see 1b) | |
436 | # | |
437 | # If renames split a directory into two or more others, the directory | |
438 | # with the most renames, "wins" (see 1c). However, see the testcases | |
439 | # in section 2, plus testcases 3a and 4a. | |
440 | ########################################################################### | |
441 | ||
442 | test_done |