]>
Commit | Line | Data |
---|---|---|
c04ba517 EN |
1 | #!/bin/sh |
2 | ||
3 | test_description="merge cases" | |
4 | ||
5 | # The setup for all of them, pictorially, is: | |
6 | # | |
7 | # A | |
8 | # o | |
9 | # / \ | |
10 | # O o ? | |
11 | # \ / | |
12 | # o | |
13 | # B | |
14 | # | |
15 | # To help make it easier to follow the flow of tests, they have been | |
16 | # divided into sections and each test will start with a quick explanation | |
17 | # of what commits O, A, and B contain. | |
18 | # | |
19 | # Notation: | |
20 | # z/{b,c} means files z/b and z/c both exist | |
21 | # x/d_1 means file x/d exists with content d1. (Purpose of the | |
22 | # underscore notation is to differentiate different | |
23 | # files that might be renamed into each other's paths.) | |
24 | ||
25 | . ./test-lib.sh | |
26 | ||
27 | ||
28 | ########################################################################### | |
29 | # SECTION 1: Cases involving no renames (one side has subset of changes of | |
30 | # the other side) | |
31 | ########################################################################### | |
32 | ||
33 | # Testcase 1a, Changes on A, subset of changes on B | |
34 | # Commit O: b_1 | |
35 | # Commit A: b_2 | |
36 | # Commit B: b_3 | |
37 | # Expected: b_2 | |
38 | ||
39 | test_expect_success '1a-setup: Modify(A)/Modify(B), change on B subset of A' ' | |
40 | test_create_repo 1a && | |
41 | ( | |
42 | cd 1a && | |
43 | ||
44 | test_write_lines 1 2 3 4 5 6 7 8 9 10 >b && | |
45 | git add b && | |
46 | test_tick && | |
47 | git commit -m "O" && | |
48 | ||
49 | git branch O && | |
50 | git branch A && | |
51 | git branch B && | |
52 | ||
53 | git checkout A && | |
54 | test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b && | |
55 | git add b && | |
56 | test_tick && | |
57 | git commit -m "A" && | |
58 | ||
59 | git checkout B && | |
60 | test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b && | |
61 | git add b && | |
62 | test_tick && | |
63 | git commit -m "B" | |
64 | ) | |
65 | ' | |
66 | ||
1de70dbd | 67 | test_expect_success '1a-check-L: Modify(A)/Modify(B), change on B subset of A' ' |
c04ba517 EN |
68 | test_when_finished "git -C 1a reset --hard" && |
69 | test_when_finished "git -C 1a clean -fd" && | |
70 | ( | |
71 | cd 1a && | |
72 | ||
73 | git checkout A^0 && | |
74 | ||
75 | test-tool chmtime =31337 b && | |
76 | test-tool chmtime -v +0 b >expected-mtime && | |
77 | ||
78 | GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err && | |
79 | ||
80 | test_i18ngrep "Skipped b" out && | |
81 | test_must_be_empty err && | |
82 | ||
83 | test-tool chmtime -v +0 b >actual-mtime && | |
84 | test_cmp expected-mtime actual-mtime && | |
85 | ||
86 | git ls-files -s >index_files && | |
87 | test_line_count = 1 index_files && | |
88 | ||
89 | git rev-parse >actual HEAD:b && | |
90 | git rev-parse >expect A:b && | |
91 | test_cmp expect actual && | |
92 | ||
93 | git hash-object b >actual && | |
94 | git rev-parse A:b >expect && | |
95 | test_cmp expect actual | |
96 | ) | |
97 | ' | |
98 | ||
99 | test_expect_success '1a-check-R: Modify(A)/Modify(B), change on B subset of A' ' | |
100 | test_when_finished "git -C 1a reset --hard" && | |
101 | test_when_finished "git -C 1a clean -fd" && | |
102 | ( | |
103 | cd 1a && | |
104 | ||
105 | git checkout B^0 && | |
106 | ||
107 | GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err && | |
108 | ||
109 | test_i18ngrep "Auto-merging b" out && | |
110 | test_must_be_empty err && | |
111 | ||
112 | git ls-files -s >index_files && | |
113 | test_line_count = 1 index_files && | |
114 | ||
115 | git rev-parse >actual HEAD:b && | |
116 | git rev-parse >expect A:b && | |
117 | test_cmp expect actual && | |
118 | ||
119 | git hash-object b >actual && | |
120 | git rev-parse A:b >expect && | |
121 | test_cmp expect actual | |
122 | ) | |
123 | ' | |
124 | ||
125 | ||
126 | ########################################################################### | |
127 | # SECTION 2: Cases involving basic renames | |
128 | ########################################################################### | |
129 | ||
130 | # Testcase 2a, Changes on A, rename on B | |
131 | # Commit O: b_1 | |
132 | # Commit A: b_2 | |
133 | # Commit B: c_1 | |
134 | # Expected: c_2 | |
135 | ||
136 | test_expect_success '2a-setup: Modify(A)/rename(B)' ' | |
137 | test_create_repo 2a && | |
138 | ( | |
139 | cd 2a && | |
140 | ||
141 | test_seq 1 10 >b && | |
142 | git add b && | |
143 | test_tick && | |
144 | git commit -m "O" && | |
145 | ||
146 | git branch O && | |
147 | git branch A && | |
148 | git branch B && | |
149 | ||
150 | git checkout A && | |
151 | test_seq 1 11 >b && | |
152 | git add b && | |
153 | test_tick && | |
154 | git commit -m "A" && | |
155 | ||
156 | git checkout B && | |
157 | git mv b c && | |
158 | test_tick && | |
159 | git commit -m "B" | |
160 | ) | |
161 | ' | |
162 | ||
1de70dbd | 163 | test_expect_success '2a-check-L: Modify/rename, merge into modify side' ' |
c04ba517 EN |
164 | test_when_finished "git -C 2a reset --hard" && |
165 | test_when_finished "git -C 2a clean -fd" && | |
166 | ( | |
167 | cd 2a && | |
168 | ||
169 | git checkout A^0 && | |
170 | ||
171 | GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err && | |
172 | ||
173 | test_i18ngrep ! "Skipped c" out && | |
174 | test_must_be_empty err && | |
175 | ||
176 | git ls-files -s >index_files && | |
177 | test_line_count = 1 index_files && | |
178 | ||
179 | git rev-parse >actual HEAD:c && | |
180 | git rev-parse >expect A:b && | |
181 | test_cmp expect actual && | |
182 | ||
183 | git hash-object c >actual && | |
184 | git rev-parse A:b >expect && | |
185 | test_cmp expect actual && | |
186 | ||
187 | test_must_fail git rev-parse HEAD:b && | |
188 | test_path_is_missing b | |
189 | ) | |
190 | ' | |
191 | ||
192 | test_expect_success '2a-check-R: Modify/rename, merge into rename side' ' | |
193 | test_when_finished "git -C 2a reset --hard" && | |
194 | test_when_finished "git -C 2a clean -fd" && | |
195 | ( | |
196 | cd 2a && | |
197 | ||
198 | git checkout B^0 && | |
199 | ||
200 | GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err && | |
201 | ||
202 | test_i18ngrep ! "Skipped c" out && | |
203 | test_must_be_empty err && | |
204 | ||
205 | git ls-files -s >index_files && | |
206 | test_line_count = 1 index_files && | |
207 | ||
208 | git rev-parse >actual HEAD:c && | |
209 | git rev-parse >expect A:b && | |
210 | test_cmp expect actual && | |
211 | ||
212 | git hash-object c >actual && | |
213 | git rev-parse A:b >expect && | |
214 | test_cmp expect actual && | |
215 | ||
216 | test_must_fail git rev-parse HEAD:b && | |
217 | test_path_is_missing b | |
218 | ) | |
219 | ' | |
220 | ||
221 | # Testcase 2b, Changed and renamed on A, subset of changes on B | |
222 | # Commit O: b_1 | |
223 | # Commit A: c_2 | |
224 | # Commit B: b_3 | |
225 | # Expected: c_2 | |
226 | ||
227 | test_expect_success '2b-setup: Rename+Mod(A)/Mod(B), B mods subset of A' ' | |
228 | test_create_repo 2b && | |
229 | ( | |
230 | cd 2b && | |
231 | ||
232 | test_write_lines 1 2 3 4 5 6 7 8 9 10 >b && | |
233 | git add b && | |
234 | test_tick && | |
235 | git commit -m "O" && | |
236 | ||
237 | git branch O && | |
238 | git branch A && | |
239 | git branch B && | |
240 | ||
241 | git checkout A && | |
242 | test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b && | |
243 | git add b && | |
244 | git mv b c && | |
245 | test_tick && | |
246 | git commit -m "A" && | |
247 | ||
248 | git checkout B && | |
249 | test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b && | |
250 | git add b && | |
251 | test_tick && | |
252 | git commit -m "B" | |
253 | ) | |
254 | ' | |
255 | ||
256 | test_expect_success '2b-check-L: Rename+Mod(A)/Mod(B), B mods subset of A' ' | |
257 | test_when_finished "git -C 2b reset --hard" && | |
258 | test_when_finished "git -C 2b clean -fd" && | |
259 | ( | |
260 | cd 2b && | |
261 | ||
262 | git checkout A^0 && | |
263 | ||
264 | test-tool chmtime =31337 c && | |
265 | test-tool chmtime -v +0 c >expected-mtime && | |
266 | ||
267 | GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err && | |
268 | ||
269 | test_i18ngrep "Skipped c" out && | |
270 | test_must_be_empty err && | |
271 | ||
272 | test-tool chmtime -v +0 c >actual-mtime && | |
273 | test_cmp expected-mtime actual-mtime && | |
274 | ||
275 | git ls-files -s >index_files && | |
276 | test_line_count = 1 index_files && | |
277 | ||
278 | git rev-parse >actual HEAD:c && | |
279 | git rev-parse >expect A:c && | |
280 | test_cmp expect actual && | |
281 | ||
282 | git hash-object c >actual && | |
283 | git rev-parse A:c >expect && | |
284 | test_cmp expect actual && | |
285 | ||
286 | test_must_fail git rev-parse HEAD:b && | |
287 | test_path_is_missing b | |
288 | ) | |
289 | ' | |
290 | ||
291 | test_expect_success '2b-check-R: Rename+Mod(A)/Mod(B), B mods subset of A' ' | |
292 | test_when_finished "git -C 2b reset --hard" && | |
293 | test_when_finished "git -C 2b clean -fd" && | |
294 | ( | |
295 | cd 2b && | |
296 | ||
297 | git checkout B^0 && | |
298 | ||
299 | GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err && | |
300 | ||
301 | test_i18ngrep "Auto-merging c" out && | |
302 | test_must_be_empty err && | |
303 | ||
304 | git ls-files -s >index_files && | |
305 | test_line_count = 1 index_files && | |
306 | ||
307 | git rev-parse >actual HEAD:c && | |
308 | git rev-parse >expect A:c && | |
309 | test_cmp expect actual && | |
310 | ||
311 | git hash-object c >actual && | |
312 | git rev-parse A:c >expect && | |
313 | test_cmp expect actual && | |
314 | ||
315 | test_must_fail git rev-parse HEAD:b && | |
316 | test_path_is_missing b | |
317 | ) | |
318 | ' | |
319 | ||
320 | # Testcase 2c, Changes on A, rename on B | |
321 | # Commit O: b_1 | |
322 | # Commit A: b_2, c_3 | |
323 | # Commit B: c_1 | |
324 | # Expected: rename/add conflict c_2 vs c_3 | |
325 | # | |
326 | # NOTE: Since A modified b_1->b_2, and B renamed b_1->c_1, the threeway | |
327 | # merge of those files should result in c_2. We then should have a | |
328 | # rename/add conflict between c_2 and c_3. However, if we note in | |
329 | # merge_content() that A had the right contents (b_2 has same | |
330 | # contents as c_2, just at a different name), and that A had the | |
331 | # right path present (c_3 existed) and thus decides that it can | |
332 | # skip the update, then we're in trouble. This test verifies we do | |
333 | # not make that particular mistake. | |
334 | ||
335 | test_expect_success '2c-setup: Modify b & add c VS rename b->c' ' | |
336 | test_create_repo 2c && | |
337 | ( | |
338 | cd 2c && | |
339 | ||
340 | test_seq 1 10 >b && | |
341 | git add b && | |
342 | test_tick && | |
343 | git commit -m "O" && | |
344 | ||
345 | git branch O && | |
346 | git branch A && | |
347 | git branch B && | |
348 | ||
349 | git checkout A && | |
350 | test_seq 1 11 >b && | |
351 | echo whatever >c && | |
352 | git add b c && | |
353 | test_tick && | |
354 | git commit -m "A" && | |
355 | ||
356 | git checkout B && | |
357 | git mv b c && | |
358 | test_tick && | |
359 | git commit -m "B" | |
360 | ) | |
361 | ' | |
362 | ||
1de70dbd | 363 | test_expect_success '2c-check: Modify b & add c VS rename b->c' ' |
c04ba517 EN |
364 | ( |
365 | cd 2c && | |
366 | ||
367 | git checkout A^0 && | |
368 | ||
079b087c ES |
369 | GIT_MERGE_VERBOSITY=3 && |
370 | export GIT_MERGE_VERBOSITY && | |
371 | test_must_fail git merge -s recursive B^0 >out 2>err && | |
c04ba517 EN |
372 | |
373 | test_i18ngrep "CONFLICT (rename/add): Rename b->c" out && | |
374 | test_i18ngrep ! "Skipped c" out && | |
375 | test_must_be_empty err | |
376 | ||
377 | # FIXME: rename/add conflicts are horribly broken right now; | |
378 | # when I get back to my patch series fixing it and | |
379 | # rename/rename(2to1) conflicts to bring them in line with | |
380 | # how add/add conflicts behave, then checks like the below | |
381 | # could be added. But that patch series is waiting until | |
382 | # the rename-directory-detection series lands, which this | |
383 | # is part of. And in the mean time, I do not want to further | |
384 | # enforce broken behavior. So for now, the main test is the | |
385 | # one above that err is an empty file. | |
386 | ||
387 | #git ls-files -s >index_files && | |
388 | #test_line_count = 2 index_files && | |
389 | ||
390 | #git rev-parse >actual :2:c :3:c && | |
391 | #git rev-parse >expect A:b A:c && | |
392 | #test_cmp expect actual && | |
393 | ||
394 | #git cat-file -p A:b >>merged && | |
395 | #git cat-file -p A:c >>merge-me && | |
396 | #>empty && | |
397 | #test_must_fail git merge-file \ | |
398 | # -L "Temporary merge branch 1" \ | |
399 | # -L "" \ | |
400 | # -L "Temporary merge branch 2" \ | |
401 | # merged empty merge-me && | |
402 | #sed -e "s/^\([<=>]\)/\1\1\1/" merged >merged-internal && | |
403 | ||
404 | #git hash-object c >actual && | |
405 | #git hash-object merged-internal >expect && | |
406 | #test_cmp expect actual && | |
407 | ||
408 | #test_path_is_missing b | |
409 | ) | |
410 | ' | |
411 | ||
412 | ||
413 | ########################################################################### | |
414 | # SECTION 3: Cases involving directory renames | |
415 | # | |
416 | # NOTE: | |
417 | # Directory renames only apply when one side renames a directory, and the | |
418 | # other side adds or renames a path into that directory. Applying the | |
419 | # directory rename to that new path creates a new pathname that didn't | |
420 | # exist on either side of history. Thus, it is impossible for the | |
421 | # merge contents to already be at the right path, so all of these checks | |
422 | # exist just to make sure that updates are not skipped. | |
423 | ########################################################################### | |
424 | ||
425 | # Testcase 3a, Change + rename into dir foo on A, dir rename foo->bar on B | |
426 | # Commit O: bq_1, foo/whatever | |
427 | # Commit A: foo/{bq_2, whatever} | |
428 | # Commit B: bq_1, bar/whatever | |
429 | # Expected: bar/{bq_2, whatever} | |
430 | ||
431 | test_expect_success '3a-setup: bq_1->foo/bq_2 on A, foo/->bar/ on B' ' | |
432 | test_create_repo 3a && | |
433 | ( | |
434 | cd 3a && | |
435 | ||
436 | mkdir foo && | |
437 | test_seq 1 10 >bq && | |
438 | test_write_lines a b c d e f g h i j k >foo/whatever && | |
439 | git add bq foo/whatever && | |
440 | test_tick && | |
441 | git commit -m "O" && | |
442 | ||
443 | git branch O && | |
444 | git branch A && | |
445 | git branch B && | |
446 | ||
447 | git checkout A && | |
448 | test_seq 1 11 >bq && | |
449 | git add bq && | |
450 | git mv bq foo/ && | |
451 | test_tick && | |
452 | git commit -m "A" && | |
453 | ||
454 | git checkout B && | |
455 | git mv foo/ bar/ && | |
456 | test_tick && | |
457 | git commit -m "B" | |
458 | ) | |
459 | ' | |
460 | ||
1de70dbd | 461 | test_expect_success '3a-check-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' ' |
c04ba517 EN |
462 | test_when_finished "git -C 3a reset --hard" && |
463 | test_when_finished "git -C 3a clean -fd" && | |
464 | ( | |
465 | cd 3a && | |
466 | ||
467 | git checkout A^0 && | |
468 | ||
8c8e5bd6 | 469 | GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && |
c04ba517 EN |
470 | |
471 | test_i18ngrep ! "Skipped bar/bq" out && | |
472 | test_must_be_empty err && | |
473 | ||
474 | git ls-files -s >index_files && | |
475 | test_line_count = 2 index_files && | |
476 | ||
477 | git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever && | |
478 | git rev-parse >expect A:foo/bq A:foo/whatever && | |
479 | test_cmp expect actual && | |
480 | ||
481 | git hash-object bar/bq bar/whatever >actual && | |
482 | git rev-parse A:foo/bq A:foo/whatever >expect && | |
483 | test_cmp expect actual && | |
484 | ||
485 | test_must_fail git rev-parse HEAD:bq HEAD:foo/bq && | |
486 | test_path_is_missing bq foo/bq foo/whatever | |
487 | ) | |
488 | ' | |
489 | ||
490 | test_expect_success '3a-check-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' ' | |
491 | test_when_finished "git -C 3a reset --hard" && | |
492 | test_when_finished "git -C 3a clean -fd" && | |
493 | ( | |
494 | cd 3a && | |
495 | ||
496 | git checkout B^0 && | |
497 | ||
8c8e5bd6 | 498 | GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive A^0 >out 2>err && |
c04ba517 EN |
499 | |
500 | test_i18ngrep ! "Skipped bar/bq" out && | |
501 | test_must_be_empty err && | |
502 | ||
503 | git ls-files -s >index_files && | |
504 | test_line_count = 2 index_files && | |
505 | ||
506 | git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever && | |
507 | git rev-parse >expect A:foo/bq A:foo/whatever && | |
508 | test_cmp expect actual && | |
509 | ||
510 | git hash-object bar/bq bar/whatever >actual && | |
511 | git rev-parse A:foo/bq A:foo/whatever >expect && | |
512 | test_cmp expect actual && | |
513 | ||
514 | test_must_fail git rev-parse HEAD:bq HEAD:foo/bq && | |
515 | test_path_is_missing bq foo/bq foo/whatever | |
516 | ) | |
517 | ' | |
518 | ||
519 | # Testcase 3b, rename into dir foo on A, dir rename foo->bar + change on B | |
520 | # Commit O: bq_1, foo/whatever | |
521 | # Commit A: foo/{bq_1, whatever} | |
522 | # Commit B: bq_2, bar/whatever | |
523 | # Expected: bar/{bq_2, whatever} | |
524 | ||
525 | test_expect_success '3b-setup: bq_1->foo/bq_2 on A, foo/->bar/ on B' ' | |
526 | test_create_repo 3b && | |
527 | ( | |
528 | cd 3b && | |
529 | ||
530 | mkdir foo && | |
531 | test_seq 1 10 >bq && | |
532 | test_write_lines a b c d e f g h i j k >foo/whatever && | |
533 | git add bq foo/whatever && | |
534 | test_tick && | |
535 | git commit -m "O" && | |
536 | ||
537 | git branch O && | |
538 | git branch A && | |
539 | git branch B && | |
540 | ||
541 | git checkout A && | |
542 | git mv bq foo/ && | |
543 | test_tick && | |
544 | git commit -m "A" && | |
545 | ||
546 | git checkout B && | |
547 | test_seq 1 11 >bq && | |
548 | git add bq && | |
549 | git mv foo/ bar/ && | |
550 | test_tick && | |
551 | git commit -m "B" | |
552 | ) | |
553 | ' | |
554 | ||
555 | test_expect_success '3b-check-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' ' | |
556 | test_when_finished "git -C 3b reset --hard" && | |
557 | test_when_finished "git -C 3b clean -fd" && | |
558 | ( | |
559 | cd 3b && | |
560 | ||
561 | git checkout A^0 && | |
562 | ||
8c8e5bd6 | 563 | GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err && |
c04ba517 EN |
564 | |
565 | test_i18ngrep ! "Skipped bar/bq" out && | |
566 | test_must_be_empty err && | |
567 | ||
568 | git ls-files -s >index_files && | |
569 | test_line_count = 2 index_files && | |
570 | ||
571 | git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever && | |
572 | git rev-parse >expect B:bq A:foo/whatever && | |
573 | test_cmp expect actual && | |
574 | ||
575 | git hash-object bar/bq bar/whatever >actual && | |
576 | git rev-parse B:bq A:foo/whatever >expect && | |
577 | test_cmp expect actual && | |
578 | ||
579 | test_must_fail git rev-parse HEAD:bq HEAD:foo/bq && | |
580 | test_path_is_missing bq foo/bq foo/whatever | |
581 | ) | |
582 | ' | |
583 | ||
1de70dbd | 584 | test_expect_success '3b-check-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' ' |
c04ba517 EN |
585 | test_when_finished "git -C 3b reset --hard" && |
586 | test_when_finished "git -C 3b clean -fd" && | |
587 | ( | |
588 | cd 3b && | |
589 | ||
590 | git checkout B^0 && | |
591 | ||
8c8e5bd6 | 592 | GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive A^0 >out 2>err && |
c04ba517 EN |
593 | |
594 | test_i18ngrep ! "Skipped bar/bq" out && | |
595 | test_must_be_empty err && | |
596 | ||
597 | git ls-files -s >index_files && | |
598 | test_line_count = 2 index_files && | |
599 | ||
600 | git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever && | |
601 | git rev-parse >expect B:bq A:foo/whatever && | |
602 | test_cmp expect actual && | |
603 | ||
604 | git hash-object bar/bq bar/whatever >actual && | |
605 | git rev-parse B:bq A:foo/whatever >expect && | |
606 | test_cmp expect actual && | |
607 | ||
608 | test_must_fail git rev-parse HEAD:bq HEAD:foo/bq && | |
609 | test_path_is_missing bq foo/bq foo/whatever | |
610 | ) | |
611 | ' | |
612 | ||
613 | ########################################################################### | |
614 | # SECTION 4: Cases involving dirty changes | |
615 | ########################################################################### | |
616 | ||
617 | # Testcase 4a, Changed on A, subset of changes on B, locally modified | |
618 | # Commit O: b_1 | |
619 | # Commit A: b_2 | |
620 | # Commit B: b_3 | |
621 | # Working copy: b_4 | |
622 | # Expected: b_2 for merge, b_4 in working copy | |
623 | ||
624 | test_expect_success '4a-setup: Change on A, change on B subset of A, dirty mods present' ' | |
625 | test_create_repo 4a && | |
626 | ( | |
627 | cd 4a && | |
628 | ||
629 | test_write_lines 1 2 3 4 5 6 7 8 9 10 >b && | |
630 | git add b && | |
631 | test_tick && | |
632 | git commit -m "O" && | |
633 | ||
634 | git branch O && | |
635 | git branch A && | |
636 | git branch B && | |
637 | ||
638 | git checkout A && | |
639 | test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b && | |
640 | git add b && | |
641 | test_tick && | |
642 | git commit -m "A" && | |
643 | ||
644 | git checkout B && | |
645 | test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b && | |
646 | git add b && | |
647 | test_tick && | |
648 | git commit -m "B" | |
649 | ) | |
650 | ' | |
651 | ||
652 | # NOTE: For as long as we continue using unpack_trees() without index_only | |
653 | # set to true, it will error out on a case like this claiming the the locally | |
654 | # modified file would be overwritten by the merge. Getting this testcase | |
655 | # correct requires doing the merge in-memory first, then realizing that no | |
656 | # updates to the file are necessary, and thus that we can just leave the path | |
657 | # alone. | |
658 | test_expect_failure '4a-check: Change on A, change on B subset of A, dirty mods present' ' | |
659 | test_when_finished "git -C 4a reset --hard" && | |
660 | test_when_finished "git -C 4a clean -fd" && | |
661 | ( | |
662 | cd 4a && | |
663 | ||
664 | git checkout A^0 && | |
665 | echo "File rewritten" >b && | |
666 | ||
667 | test-tool chmtime =31337 b && | |
668 | test-tool chmtime -v +0 b >expected-mtime && | |
669 | ||
670 | GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err && | |
671 | ||
672 | test_i18ngrep "Skipped b" out && | |
673 | test_must_be_empty err && | |
674 | ||
675 | test-tool chmtime -v +0 b >actual-mtime && | |
676 | test_cmp expected-mtime actual-mtime && | |
677 | ||
678 | git ls-files -s >index_files && | |
679 | test_line_count = 1 index_files && | |
680 | ||
681 | git rev-parse >actual :0:b && | |
682 | git rev-parse >expect A:b && | |
683 | test_cmp expect actual && | |
684 | ||
685 | git hash-object b >actual && | |
686 | echo "File rewritten" | git hash-object --stdin >expect && | |
687 | test_cmp expect actual | |
688 | ) | |
689 | ' | |
690 | ||
691 | # Testcase 4b, Changed+renamed on A, subset of changes on B, locally modified | |
692 | # Commit O: b_1 | |
693 | # Commit A: c_2 | |
694 | # Commit B: b_3 | |
695 | # Working copy: c_4 | |
696 | # Expected: c_2 | |
697 | ||
698 | test_expect_success '4b-setup: Rename+Mod(A)/Mod(B), change on B subset of A, dirty mods present' ' | |
699 | test_create_repo 4b && | |
700 | ( | |
701 | cd 4b && | |
702 | ||
703 | test_write_lines 1 2 3 4 5 6 7 8 9 10 >b && | |
704 | git add b && | |
705 | test_tick && | |
706 | git commit -m "O" && | |
707 | ||
708 | git branch O && | |
709 | git branch A && | |
710 | git branch B && | |
711 | ||
712 | git checkout A && | |
713 | test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b && | |
714 | git add b && | |
715 | git mv b c && | |
716 | test_tick && | |
717 | git commit -m "A" && | |
718 | ||
719 | git checkout B && | |
720 | test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b && | |
721 | git add b && | |
722 | test_tick && | |
723 | git commit -m "B" | |
724 | ) | |
725 | ' | |
726 | ||
727 | test_expect_success '4b-check: Rename+Mod(A)/Mod(B), change on B subset of A, dirty mods present' ' | |
728 | test_when_finished "git -C 4b reset --hard" && | |
729 | test_when_finished "git -C 4b clean -fd" && | |
730 | ( | |
731 | cd 4b && | |
732 | ||
733 | git checkout A^0 && | |
734 | echo "File rewritten" >c && | |
735 | ||
736 | test-tool chmtime =31337 c && | |
737 | test-tool chmtime -v +0 c >expected-mtime && | |
738 | ||
739 | GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err && | |
740 | ||
741 | test_i18ngrep "Skipped c" out && | |
742 | test_must_be_empty err && | |
743 | ||
744 | test-tool chmtime -v +0 c >actual-mtime && | |
745 | test_cmp expected-mtime actual-mtime && | |
746 | ||
747 | git ls-files -s >index_files && | |
748 | test_line_count = 1 index_files && | |
749 | ||
750 | git rev-parse >actual :0:c && | |
751 | git rev-parse >expect A:c && | |
752 | test_cmp expect actual && | |
753 | ||
754 | git hash-object c >actual && | |
755 | echo "File rewritten" | git hash-object --stdin >expect && | |
756 | test_cmp expect actual && | |
757 | ||
758 | test_must_fail git rev-parse HEAD:b && | |
759 | test_path_is_missing b | |
760 | ) | |
761 | ' | |
762 | ||
763 | test_done |