]>
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 | ||
509555d8 EN |
442 | |
443 | ########################################################################### | |
444 | # SECTION 2: Split into multiple directories, with equal number of paths | |
445 | # | |
446 | # Explore the splitting-a-directory rules a bit; what happens in the | |
447 | # edge cases? | |
448 | # | |
449 | # Note that there is a closely related case of a directory not being | |
450 | # split on either side of history, but being renamed differently on | |
451 | # each side. See testcase 8e for that. | |
452 | ########################################################################### | |
453 | ||
454 | # Testcase 2a, Directory split into two on one side, with equal numbers of paths | |
455 | # Commit O: z/{b,c} | |
456 | # Commit A: y/b, w/c | |
457 | # Commit B: z/{b,c,d} | |
458 | # Expected: y/b, w/c, z/d, with warning about z/ -> (y/ vs. w/) conflict | |
459 | test_expect_success '2a-setup: Directory split into two on one side, with equal numbers of paths' ' | |
460 | test_create_repo 2a && | |
461 | ( | |
462 | cd 2a && | |
463 | ||
464 | mkdir z && | |
465 | echo b >z/b && | |
466 | echo c >z/c && | |
467 | git add z && | |
468 | test_tick && | |
469 | git commit -m "O" && | |
470 | ||
471 | git branch O && | |
472 | git branch A && | |
473 | git branch B && | |
474 | ||
475 | git checkout A && | |
476 | mkdir y && | |
477 | mkdir w && | |
478 | git mv z/b y/ && | |
479 | git mv z/c w/ && | |
480 | test_tick && | |
481 | git commit -m "A" && | |
482 | ||
483 | git checkout B && | |
484 | echo d >z/d && | |
485 | git add z/d && | |
486 | test_tick && | |
487 | git commit -m "B" | |
488 | ) | |
489 | ' | |
490 | ||
491 | test_expect_failure '2a-check: Directory split into two on one side, with equal numbers of paths' ' | |
492 | ( | |
493 | cd 2a && | |
494 | ||
495 | git checkout A^0 && | |
496 | ||
497 | test_must_fail git merge -s recursive B^0 >out && | |
498 | test_i18ngrep "CONFLICT.*directory rename split" out && | |
499 | ||
500 | git ls-files -s >out && | |
501 | test_line_count = 3 out && | |
502 | git ls-files -u >out && | |
503 | test_line_count = 0 out && | |
504 | git ls-files -o >out && | |
505 | test_line_count = 1 out && | |
506 | ||
507 | git rev-parse >actual \ | |
508 | :0:y/b :0:w/c :0:z/d && | |
509 | git rev-parse >expect \ | |
510 | O:z/b O:z/c B:z/d && | |
511 | test_cmp expect actual | |
512 | ) | |
513 | ' | |
514 | ||
515 | # Testcase 2b, Directory split into two on one side, with equal numbers of paths | |
516 | # Commit O: z/{b,c} | |
517 | # Commit A: y/b, w/c | |
518 | # Commit B: z/{b,c}, x/d | |
519 | # Expected: y/b, w/c, x/d; No warning about z/ -> (y/ vs. w/) conflict | |
520 | test_expect_success '2b-setup: Directory split into two on one side, with equal numbers of paths' ' | |
521 | test_create_repo 2b && | |
522 | ( | |
523 | cd 2b && | |
524 | ||
525 | mkdir z && | |
526 | echo b >z/b && | |
527 | echo c >z/c && | |
528 | git add z && | |
529 | test_tick && | |
530 | git commit -m "O" && | |
531 | ||
532 | git branch O && | |
533 | git branch A && | |
534 | git branch B && | |
535 | ||
536 | git checkout A && | |
537 | mkdir y && | |
538 | mkdir w && | |
539 | git mv z/b y/ && | |
540 | git mv z/c w/ && | |
541 | test_tick && | |
542 | git commit -m "A" && | |
543 | ||
544 | git checkout B && | |
545 | mkdir x && | |
546 | echo d >x/d && | |
547 | git add x/d && | |
548 | test_tick && | |
549 | git commit -m "B" | |
550 | ) | |
551 | ' | |
552 | ||
553 | test_expect_success '2b-check: Directory split into two on one side, with equal numbers of paths' ' | |
554 | ( | |
555 | cd 2b && | |
556 | ||
557 | git checkout A^0 && | |
558 | ||
559 | git merge -s recursive B^0 >out && | |
560 | ||
561 | git ls-files -s >out && | |
562 | test_line_count = 3 out && | |
563 | git ls-files -u >out && | |
564 | test_line_count = 0 out && | |
565 | git ls-files -o >out && | |
566 | test_line_count = 1 out && | |
567 | ||
568 | git rev-parse >actual \ | |
569 | :0:y/b :0:w/c :0:x/d && | |
570 | git rev-parse >expect \ | |
571 | O:z/b O:z/c B:x/d && | |
572 | test_cmp expect actual && | |
573 | test_i18ngrep ! "CONFLICT.*directory rename split" out | |
574 | ) | |
575 | ' | |
576 | ||
577 | ########################################################################### | |
578 | # Rules suggested by section 2: | |
579 | # | |
580 | # None; the rule was already covered in section 1. These testcases are | |
581 | # here just to make sure the conflict resolution and necessary warning | |
582 | # messages are handled correctly. | |
583 | ########################################################################### | |
584 | ||
04550ab5 | 585 | test_done |