blob: 7b5f1c1dcd1f68c74646a5983b6b0d53bd9b4a92 [file] [log] [blame]
Elijah Newrenc04ba512018-04-19 10:58:19 -07001#!/bin/sh
2
3test_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
Elijah Newrenf06481f2020-10-26 17:01:36 +000026. "$TEST_DIRECTORY"/lib-merge.sh
Elijah Newrenc04ba512018-04-19 10:58:19 -070027
28
29###########################################################################
30# SECTION 1: Cases involving no renames (one side has subset of changes of
31# the other side)
32###########################################################################
33
34# Testcase 1a, Changes on A, subset of changes on B
35# Commit O: b_1
36# Commit A: b_2
37# Commit B: b_3
38# Expected: b_2
39
Elijah Newrenda1e2952019-10-22 21:22:51 +000040test_setup_1a () {
41 test_create_repo 1a_$1 &&
Elijah Newrenc04ba512018-04-19 10:58:19 -070042 (
Elijah Newrenda1e2952019-10-22 21:22:51 +000043 cd 1a_$1 &&
Elijah Newrenc04ba512018-04-19 10:58:19 -070044
45 test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
46 git add b &&
47 test_tick &&
48 git commit -m "O" &&
49
50 git branch O &&
51 git branch A &&
52 git branch B &&
53
54 git checkout A &&
55 test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b &&
56 git add b &&
57 test_tick &&
58 git commit -m "A" &&
59
60 git checkout B &&
61 test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b &&
62 git add b &&
63 test_tick &&
64 git commit -m "B"
65 )
Elijah Newrenda1e2952019-10-22 21:22:51 +000066}
Elijah Newrenc04ba512018-04-19 10:58:19 -070067
Elijah Newrenda1e2952019-10-22 21:22:51 +000068test_expect_success '1a-L: Modify(A)/Modify(B), change on B subset of A' '
69 test_setup_1a L &&
Elijah Newrenc04ba512018-04-19 10:58:19 -070070 (
Elijah Newrenda1e2952019-10-22 21:22:51 +000071 cd 1a_L &&
Elijah Newrenc04ba512018-04-19 10:58:19 -070072
73 git checkout A^0 &&
74
Elijah Newren70e24182020-03-13 20:03:02 +000075 test-tool chmtime --get -3600 b >old-mtime &&
Elijah Newrenc04ba512018-04-19 10:58:19 -070076
77 GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
78
Elijah Newrenc04ba512018-04-19 10:58:19 -070079 test_must_be_empty err &&
80
Elijah Newren9f697de2020-02-27 00:14:23 +000081 # Make sure b was NOT updated
82 test-tool chmtime --get b >new-mtime &&
83 test_cmp old-mtime new-mtime &&
Elijah Newrenc04ba512018-04-19 10:58:19 -070084
85 git ls-files -s >index_files &&
86 test_line_count = 1 index_files &&
87
88 git rev-parse >actual HEAD:b &&
89 git rev-parse >expect A:b &&
90 test_cmp expect actual &&
91
92 git hash-object b >actual &&
93 git rev-parse A:b >expect &&
94 test_cmp expect actual
95 )
96'
97
Elijah Newrenda1e2952019-10-22 21:22:51 +000098test_expect_success '1a-R: Modify(A)/Modify(B), change on B subset of A' '
99 test_setup_1a R &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700100 (
Elijah Newrenda1e2952019-10-22 21:22:51 +0000101 cd 1a_R &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700102
103 git checkout B^0 &&
104
Elijah Newren70e24182020-03-13 20:03:02 +0000105 test-tool chmtime --get -3600 b >old-mtime &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700106 GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
107
Elijah Newren9f697de2020-02-27 00:14:23 +0000108 # Make sure b WAS updated
109 test-tool chmtime --get b >new-mtime &&
110 test $(cat old-mtime) -lt $(cat new-mtime) &&
111
Elijah Newrenc04ba512018-04-19 10:58:19 -0700112 test_must_be_empty err &&
113
114 git ls-files -s >index_files &&
115 test_line_count = 1 index_files &&
116
117 git rev-parse >actual HEAD:b &&
118 git rev-parse >expect A:b &&
119 test_cmp expect actual &&
120
121 git hash-object b >actual &&
122 git rev-parse A:b >expect &&
123 test_cmp expect actual
124 )
125'
126
127
128###########################################################################
129# SECTION 2: Cases involving basic renames
130###########################################################################
131
132# Testcase 2a, Changes on A, rename on B
133# Commit O: b_1
134# Commit A: b_2
135# Commit B: c_1
136# Expected: c_2
137
Elijah Newrenda1e2952019-10-22 21:22:51 +0000138test_setup_2a () {
139 test_create_repo 2a_$1 &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700140 (
Elijah Newrenda1e2952019-10-22 21:22:51 +0000141 cd 2a_$1 &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700142
143 test_seq 1 10 >b &&
144 git add b &&
145 test_tick &&
146 git commit -m "O" &&
147
148 git branch O &&
149 git branch A &&
150 git branch B &&
151
152 git checkout A &&
153 test_seq 1 11 >b &&
154 git add b &&
155 test_tick &&
156 git commit -m "A" &&
157
158 git checkout B &&
159 git mv b c &&
160 test_tick &&
161 git commit -m "B"
162 )
Elijah Newrenda1e2952019-10-22 21:22:51 +0000163}
Elijah Newrenc04ba512018-04-19 10:58:19 -0700164
Elijah Newrenda1e2952019-10-22 21:22:51 +0000165test_expect_success '2a-L: Modify/rename, merge into modify side' '
166 test_setup_2a L &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700167 (
Elijah Newrenda1e2952019-10-22 21:22:51 +0000168 cd 2a_L &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700169
170 git checkout A^0 &&
171
Elijah Newren9f697de2020-02-27 00:14:23 +0000172 test_path_is_missing c &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700173 GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
174
Elijah Newren9f697de2020-02-27 00:14:23 +0000175 test_path_is_file c &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700176
177 git ls-files -s >index_files &&
178 test_line_count = 1 index_files &&
179
180 git rev-parse >actual HEAD:c &&
181 git rev-parse >expect A:b &&
182 test_cmp expect actual &&
183
184 git hash-object c >actual &&
185 git rev-parse A:b >expect &&
186 test_cmp expect actual &&
187
188 test_must_fail git rev-parse HEAD:b &&
189 test_path_is_missing b
190 )
191'
192
Elijah Newrenda1e2952019-10-22 21:22:51 +0000193test_expect_success '2a-R: Modify/rename, merge into rename side' '
194 test_setup_2a R &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700195 (
Elijah Newrenda1e2952019-10-22 21:22:51 +0000196 cd 2a_R &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700197
198 git checkout B^0 &&
199
Elijah Newren70e24182020-03-13 20:03:02 +0000200 test-tool chmtime --get -3600 c >old-mtime &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700201 GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
202
Elijah Newren9f697de2020-02-27 00:14:23 +0000203 # Make sure c WAS updated
204 test-tool chmtime --get c >new-mtime &&
205 test $(cat old-mtime) -lt $(cat new-mtime) &&
206
Elijah Newrenc04ba512018-04-19 10:58:19 -0700207 test_must_be_empty err &&
208
209 git ls-files -s >index_files &&
210 test_line_count = 1 index_files &&
211
212 git rev-parse >actual HEAD:c &&
213 git rev-parse >expect A:b &&
214 test_cmp expect actual &&
215
216 git hash-object c >actual &&
217 git rev-parse A:b >expect &&
218 test_cmp expect actual &&
219
220 test_must_fail git rev-parse HEAD:b &&
221 test_path_is_missing b
222 )
223'
224
225# Testcase 2b, Changed and renamed on A, subset of changes on B
226# Commit O: b_1
227# Commit A: c_2
228# Commit B: b_3
229# Expected: c_2
230
Elijah Newrenda1e2952019-10-22 21:22:51 +0000231test_setup_2b () {
232 test_create_repo 2b_$1 &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700233 (
Elijah Newrenda1e2952019-10-22 21:22:51 +0000234 cd 2b_$1 &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700235
236 test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
237 git add b &&
238 test_tick &&
239 git commit -m "O" &&
240
241 git branch O &&
242 git branch A &&
243 git branch B &&
244
245 git checkout A &&
246 test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b &&
247 git add b &&
248 git mv b c &&
249 test_tick &&
250 git commit -m "A" &&
251
252 git checkout B &&
253 test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b &&
254 git add b &&
255 test_tick &&
256 git commit -m "B"
257 )
Elijah Newrenda1e2952019-10-22 21:22:51 +0000258}
Elijah Newrenc04ba512018-04-19 10:58:19 -0700259
Elijah Newrenda1e2952019-10-22 21:22:51 +0000260test_expect_success '2b-L: Rename+Mod(A)/Mod(B), B mods subset of A' '
261 test_setup_2b L &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700262 (
Elijah Newrenda1e2952019-10-22 21:22:51 +0000263 cd 2b_L &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700264
265 git checkout A^0 &&
266
Elijah Newren70e24182020-03-13 20:03:02 +0000267 test-tool chmtime --get -3600 c >old-mtime &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700268 GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
269
Elijah Newrenc04ba512018-04-19 10:58:19 -0700270 test_must_be_empty err &&
271
Elijah Newren9f697de2020-02-27 00:14:23 +0000272 # Make sure c WAS updated
273 test-tool chmtime --get c >new-mtime &&
274 test_cmp old-mtime new-mtime &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700275
276 git ls-files -s >index_files &&
277 test_line_count = 1 index_files &&
278
279 git rev-parse >actual HEAD:c &&
280 git rev-parse >expect A:c &&
281 test_cmp expect actual &&
282
283 git hash-object c >actual &&
284 git rev-parse A:c >expect &&
285 test_cmp expect actual &&
286
287 test_must_fail git rev-parse HEAD:b &&
288 test_path_is_missing b
289 )
290'
291
Elijah Newrenda1e2952019-10-22 21:22:51 +0000292test_expect_success '2b-R: Rename+Mod(A)/Mod(B), B mods subset of A' '
293 test_setup_2b R &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700294 (
Elijah Newrenda1e2952019-10-22 21:22:51 +0000295 cd 2b_R &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700296
297 git checkout B^0 &&
298
Elijah Newren9f697de2020-02-27 00:14:23 +0000299 test_path_is_missing c &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700300 GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
301
Elijah Newren9f697de2020-02-27 00:14:23 +0000302 # Make sure c now present (and thus was updated)
303 test_path_is_file c &&
304
Elijah Newrenc04ba512018-04-19 10:58:19 -0700305 test_must_be_empty err &&
306
307 git ls-files -s >index_files &&
308 test_line_count = 1 index_files &&
309
310 git rev-parse >actual HEAD:c &&
311 git rev-parse >expect A:c &&
312 test_cmp expect actual &&
313
314 git hash-object c >actual &&
315 git rev-parse A:c >expect &&
316 test_cmp expect actual &&
317
318 test_must_fail git rev-parse HEAD:b &&
319 test_path_is_missing b
320 )
321'
322
323# Testcase 2c, Changes on A, rename on B
324# Commit O: b_1
325# Commit A: b_2, c_3
326# Commit B: c_1
327# Expected: rename/add conflict c_2 vs c_3
328#
329# NOTE: Since A modified b_1->b_2, and B renamed b_1->c_1, the threeway
330# merge of those files should result in c_2. We then should have a
331# rename/add conflict between c_2 and c_3. However, if we note in
332# merge_content() that A had the right contents (b_2 has same
333# contents as c_2, just at a different name), and that A had the
334# right path present (c_3 existed) and thus decides that it can
335# skip the update, then we're in trouble. This test verifies we do
336# not make that particular mistake.
337
Elijah Newrenda1e2952019-10-22 21:22:51 +0000338test_setup_2c () {
Elijah Newrenc04ba512018-04-19 10:58:19 -0700339 test_create_repo 2c &&
340 (
341 cd 2c &&
342
343 test_seq 1 10 >b &&
344 git add b &&
345 test_tick &&
346 git commit -m "O" &&
347
348 git branch O &&
349 git branch A &&
350 git branch B &&
351
352 git checkout A &&
353 test_seq 1 11 >b &&
354 echo whatever >c &&
355 git add b c &&
356 test_tick &&
357 git commit -m "A" &&
358
359 git checkout B &&
360 git mv b c &&
361 test_tick &&
362 git commit -m "B"
363 )
Elijah Newrenda1e2952019-10-22 21:22:51 +0000364}
Elijah Newrenc04ba512018-04-19 10:58:19 -0700365
Elijah Newrenda1e2952019-10-22 21:22:51 +0000366test_expect_success '2c: Modify b & add c VS rename b->c' '
367 test_setup_2c &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700368 (
369 cd 2c &&
370
371 git checkout A^0 &&
372
Elijah Newren70e24182020-03-13 20:03:02 +0000373 test-tool chmtime --get -3600 c >old-mtime &&
Eric Sunshine079b0872018-07-13 01:52:02 -0400374 GIT_MERGE_VERBOSITY=3 &&
375 export GIT_MERGE_VERBOSITY &&
376 test_must_fail git merge -s recursive B^0 >out 2>err &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700377
Elijah Newren2a7c16c2020-08-10 22:29:17 +0000378 test_i18ngrep "CONFLICT (.*/add):" out &&
Elijah Newren9f697de2020-02-27 00:14:23 +0000379 test_must_be_empty err &&
380
381 # Make sure c WAS updated
382 test-tool chmtime --get c >new-mtime &&
383 test $(cat old-mtime) -lt $(cat new-mtime)
Elijah Newrenc04ba512018-04-19 10:58:19 -0700384
385 # FIXME: rename/add conflicts are horribly broken right now;
386 # when I get back to my patch series fixing it and
387 # rename/rename(2to1) conflicts to bring them in line with
388 # how add/add conflicts behave, then checks like the below
389 # could be added. But that patch series is waiting until
390 # the rename-directory-detection series lands, which this
391 # is part of. And in the mean time, I do not want to further
392 # enforce broken behavior. So for now, the main test is the
393 # one above that err is an empty file.
394
395 #git ls-files -s >index_files &&
396 #test_line_count = 2 index_files &&
397
398 #git rev-parse >actual :2:c :3:c &&
399 #git rev-parse >expect A:b A:c &&
400 #test_cmp expect actual &&
401
402 #git cat-file -p A:b >>merged &&
403 #git cat-file -p A:c >>merge-me &&
404 #>empty &&
405 #test_must_fail git merge-file \
406 # -L "Temporary merge branch 1" \
407 # -L "" \
408 # -L "Temporary merge branch 2" \
409 # merged empty merge-me &&
410 #sed -e "s/^\([<=>]\)/\1\1\1/" merged >merged-internal &&
411
412 #git hash-object c >actual &&
413 #git hash-object merged-internal >expect &&
414 #test_cmp expect actual &&
415
416 #test_path_is_missing b
417 )
418'
419
420
421###########################################################################
422# SECTION 3: Cases involving directory renames
423#
424# NOTE:
425# Directory renames only apply when one side renames a directory, and the
426# other side adds or renames a path into that directory. Applying the
427# directory rename to that new path creates a new pathname that didn't
428# exist on either side of history. Thus, it is impossible for the
429# merge contents to already be at the right path, so all of these checks
430# exist just to make sure that updates are not skipped.
431###########################################################################
432
433# Testcase 3a, Change + rename into dir foo on A, dir rename foo->bar on B
434# Commit O: bq_1, foo/whatever
435# Commit A: foo/{bq_2, whatever}
436# Commit B: bq_1, bar/whatever
437# Expected: bar/{bq_2, whatever}
438
Elijah Newrenda1e2952019-10-22 21:22:51 +0000439test_setup_3a () {
440 test_create_repo 3a_$1 &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700441 (
Elijah Newrenda1e2952019-10-22 21:22:51 +0000442 cd 3a_$1 &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700443
444 mkdir foo &&
445 test_seq 1 10 >bq &&
446 test_write_lines a b c d e f g h i j k >foo/whatever &&
447 git add bq foo/whatever &&
448 test_tick &&
449 git commit -m "O" &&
450
451 git branch O &&
452 git branch A &&
453 git branch B &&
454
455 git checkout A &&
456 test_seq 1 11 >bq &&
457 git add bq &&
458 git mv bq foo/ &&
459 test_tick &&
460 git commit -m "A" &&
461
462 git checkout B &&
463 git mv foo/ bar/ &&
464 test_tick &&
465 git commit -m "B"
466 )
Elijah Newrenda1e2952019-10-22 21:22:51 +0000467}
Elijah Newrenc04ba512018-04-19 10:58:19 -0700468
Elijah Newrenda1e2952019-10-22 21:22:51 +0000469test_expect_success '3a-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
470 test_setup_3a L &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700471 (
Elijah Newrenda1e2952019-10-22 21:22:51 +0000472 cd 3a_L &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700473
474 git checkout A^0 &&
475
Elijah Newren9f697de2020-02-27 00:14:23 +0000476 test_path_is_missing bar/bq &&
Elijah Newren8c8e5bd2019-04-05 08:00:26 -0700477 GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700478
Elijah Newrenc04ba512018-04-19 10:58:19 -0700479 test_must_be_empty err &&
480
Elijah Newren9f697de2020-02-27 00:14:23 +0000481 test_path_is_file bar/bq &&
482
Elijah Newrenc04ba512018-04-19 10:58:19 -0700483 git ls-files -s >index_files &&
484 test_line_count = 2 index_files &&
485
486 git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever &&
487 git rev-parse >expect A:foo/bq A:foo/whatever &&
488 test_cmp expect actual &&
489
490 git hash-object bar/bq bar/whatever >actual &&
491 git rev-parse A:foo/bq A:foo/whatever >expect &&
492 test_cmp expect actual &&
493
494 test_must_fail git rev-parse HEAD:bq HEAD:foo/bq &&
Ævar Arnfjörð Bjarmason45a26862021-02-12 14:29:41 +0100495 test_path_is_missing bq &&
496 test_path_is_missing foo/bq &&
497 test_path_is_missing foo/whatever
Elijah Newrenc04ba512018-04-19 10:58:19 -0700498 )
499'
500
Elijah Newrenda1e2952019-10-22 21:22:51 +0000501test_expect_success '3a-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
502 test_setup_3a R &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700503 (
Elijah Newrenda1e2952019-10-22 21:22:51 +0000504 cd 3a_R &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700505
506 git checkout B^0 &&
507
Elijah Newren9f697de2020-02-27 00:14:23 +0000508 test_path_is_missing bar/bq &&
Elijah Newren8c8e5bd2019-04-05 08:00:26 -0700509 GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive A^0 >out 2>err &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700510
Elijah Newrenc04ba512018-04-19 10:58:19 -0700511 test_must_be_empty err &&
512
Elijah Newren9f697de2020-02-27 00:14:23 +0000513 test_path_is_file bar/bq &&
514
Elijah Newrenc04ba512018-04-19 10:58:19 -0700515 git ls-files -s >index_files &&
516 test_line_count = 2 index_files &&
517
518 git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever &&
519 git rev-parse >expect A:foo/bq A:foo/whatever &&
520 test_cmp expect actual &&
521
522 git hash-object bar/bq bar/whatever >actual &&
523 git rev-parse A:foo/bq A:foo/whatever >expect &&
524 test_cmp expect actual &&
525
526 test_must_fail git rev-parse HEAD:bq HEAD:foo/bq &&
Ævar Arnfjörð Bjarmason45a26862021-02-12 14:29:41 +0100527 test_path_is_missing bq &&
528 test_path_is_missing foo/bq &&
529 test_path_is_missing foo/whatever
Elijah Newrenc04ba512018-04-19 10:58:19 -0700530 )
531'
532
533# Testcase 3b, rename into dir foo on A, dir rename foo->bar + change on B
534# Commit O: bq_1, foo/whatever
535# Commit A: foo/{bq_1, whatever}
536# Commit B: bq_2, bar/whatever
537# Expected: bar/{bq_2, whatever}
538
Elijah Newrenda1e2952019-10-22 21:22:51 +0000539test_setup_3b () {
540 test_create_repo 3b_$1 &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700541 (
Elijah Newrenda1e2952019-10-22 21:22:51 +0000542 cd 3b_$1 &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700543
544 mkdir foo &&
545 test_seq 1 10 >bq &&
546 test_write_lines a b c d e f g h i j k >foo/whatever &&
547 git add bq foo/whatever &&
548 test_tick &&
549 git commit -m "O" &&
550
551 git branch O &&
552 git branch A &&
553 git branch B &&
554
555 git checkout A &&
556 git mv bq foo/ &&
557 test_tick &&
558 git commit -m "A" &&
559
560 git checkout B &&
561 test_seq 1 11 >bq &&
562 git add bq &&
563 git mv foo/ bar/ &&
564 test_tick &&
565 git commit -m "B"
566 )
Elijah Newrenda1e2952019-10-22 21:22:51 +0000567}
Elijah Newrenc04ba512018-04-19 10:58:19 -0700568
Elijah Newrenda1e2952019-10-22 21:22:51 +0000569test_expect_success '3b-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
570 test_setup_3b L &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700571 (
Elijah Newrenda1e2952019-10-22 21:22:51 +0000572 cd 3b_L &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700573
574 git checkout A^0 &&
575
Elijah Newren9f697de2020-02-27 00:14:23 +0000576 test_path_is_missing bar/bq &&
Elijah Newren8c8e5bd2019-04-05 08:00:26 -0700577 GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700578
Elijah Newrenc04ba512018-04-19 10:58:19 -0700579 test_must_be_empty err &&
580
Elijah Newren9f697de2020-02-27 00:14:23 +0000581 test_path_is_file bar/bq &&
582
Elijah Newrenc04ba512018-04-19 10:58:19 -0700583 git ls-files -s >index_files &&
584 test_line_count = 2 index_files &&
585
586 git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever &&
587 git rev-parse >expect B:bq A:foo/whatever &&
588 test_cmp expect actual &&
589
590 git hash-object bar/bq bar/whatever >actual &&
591 git rev-parse B:bq A:foo/whatever >expect &&
592 test_cmp expect actual &&
593
594 test_must_fail git rev-parse HEAD:bq HEAD:foo/bq &&
Ævar Arnfjörð Bjarmason45a26862021-02-12 14:29:41 +0100595 test_path_is_missing bq &&
596 test_path_is_missing foo/bq &&
597 test_path_is_missing foo/whatever
Elijah Newrenc04ba512018-04-19 10:58:19 -0700598 )
599'
600
Elijah Newrenda1e2952019-10-22 21:22:51 +0000601test_expect_success '3b-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
602 test_setup_3b R &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700603 (
Elijah Newrenda1e2952019-10-22 21:22:51 +0000604 cd 3b_R &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700605
606 git checkout B^0 &&
607
Elijah Newren9f697de2020-02-27 00:14:23 +0000608 test_path_is_missing bar/bq &&
Elijah Newren8c8e5bd2019-04-05 08:00:26 -0700609 GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive A^0 >out 2>err &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700610
Elijah Newrenc04ba512018-04-19 10:58:19 -0700611 test_must_be_empty err &&
612
Elijah Newren9f697de2020-02-27 00:14:23 +0000613 test_path_is_file bar/bq &&
614
Elijah Newrenc04ba512018-04-19 10:58:19 -0700615 git ls-files -s >index_files &&
616 test_line_count = 2 index_files &&
617
618 git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever &&
619 git rev-parse >expect B:bq A:foo/whatever &&
620 test_cmp expect actual &&
621
622 git hash-object bar/bq bar/whatever >actual &&
623 git rev-parse B:bq A:foo/whatever >expect &&
624 test_cmp expect actual &&
625
626 test_must_fail git rev-parse HEAD:bq HEAD:foo/bq &&
Ævar Arnfjörð Bjarmason45a26862021-02-12 14:29:41 +0100627 test_path_is_missing bq &&
628 test_path_is_missing foo/bq &&
629 test_path_is_missing foo/whatever
Elijah Newrenc04ba512018-04-19 10:58:19 -0700630 )
631'
632
633###########################################################################
634# SECTION 4: Cases involving dirty changes
635###########################################################################
636
637# Testcase 4a, Changed on A, subset of changes on B, locally modified
638# Commit O: b_1
639# Commit A: b_2
640# Commit B: b_3
641# Working copy: b_4
642# Expected: b_2 for merge, b_4 in working copy
643
Elijah Newrenda1e2952019-10-22 21:22:51 +0000644test_setup_4a () {
Elijah Newrenc04ba512018-04-19 10:58:19 -0700645 test_create_repo 4a &&
646 (
647 cd 4a &&
648
649 test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
650 git add b &&
651 test_tick &&
652 git commit -m "O" &&
653
654 git branch O &&
655 git branch A &&
656 git branch B &&
657
658 git checkout A &&
659 test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b &&
660 git add b &&
661 test_tick &&
662 git commit -m "A" &&
663
664 git checkout B &&
665 test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b &&
666 git add b &&
667 test_tick &&
668 git commit -m "B"
669 )
Elijah Newrenda1e2952019-10-22 21:22:51 +0000670}
Elijah Newrenc04ba512018-04-19 10:58:19 -0700671
672# NOTE: For as long as we continue using unpack_trees() without index_only
Elijah Newren6d12b532020-07-28 20:45:38 +0000673# set to true, it will error out on a case like this claiming that the locally
Elijah Newrenc04ba512018-04-19 10:58:19 -0700674# modified file would be overwritten by the merge. Getting this testcase
675# correct requires doing the merge in-memory first, then realizing that no
676# updates to the file are necessary, and thus that we can just leave the path
677# alone.
Elijah Newrenf06481f2020-10-26 17:01:36 +0000678test_expect_merge_algorithm failure success '4a: Change on A, change on B subset of A, dirty mods present' '
Elijah Newrenda1e2952019-10-22 21:22:51 +0000679 test_setup_4a &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700680 (
681 cd 4a &&
682
683 git checkout A^0 &&
684 echo "File rewritten" >b &&
685
Elijah Newren70e24182020-03-13 20:03:02 +0000686 test-tool chmtime --get -3600 b >old-mtime &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700687
688 GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
689
Elijah Newrenc04ba512018-04-19 10:58:19 -0700690 test_must_be_empty err &&
691
Elijah Newren9f697de2020-02-27 00:14:23 +0000692 # Make sure b was NOT updated
693 test-tool chmtime --get b >new-mtime &&
694 test_cmp old-mtime new-mtime &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700695
696 git ls-files -s >index_files &&
697 test_line_count = 1 index_files &&
698
699 git rev-parse >actual :0:b &&
700 git rev-parse >expect A:b &&
701 test_cmp expect actual &&
702
703 git hash-object b >actual &&
704 echo "File rewritten" | git hash-object --stdin >expect &&
705 test_cmp expect actual
706 )
707'
708
709# Testcase 4b, Changed+renamed on A, subset of changes on B, locally modified
710# Commit O: b_1
711# Commit A: c_2
712# Commit B: b_3
713# Working copy: c_4
714# Expected: c_2
715
Elijah Newrenda1e2952019-10-22 21:22:51 +0000716test_setup_4b () {
Elijah Newrenc04ba512018-04-19 10:58:19 -0700717 test_create_repo 4b &&
718 (
719 cd 4b &&
720
721 test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
722 git add b &&
723 test_tick &&
724 git commit -m "O" &&
725
726 git branch O &&
727 git branch A &&
728 git branch B &&
729
730 git checkout A &&
731 test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b &&
732 git add b &&
733 git mv b c &&
734 test_tick &&
735 git commit -m "A" &&
736
737 git checkout B &&
738 test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b &&
739 git add b &&
740 test_tick &&
741 git commit -m "B"
742 )
Elijah Newrenda1e2952019-10-22 21:22:51 +0000743}
Elijah Newrenc04ba512018-04-19 10:58:19 -0700744
Elijah Newrenda1e2952019-10-22 21:22:51 +0000745test_expect_success '4b: Rename+Mod(A)/Mod(B), change on B subset of A, dirty mods present' '
746 test_setup_4b &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700747 (
748 cd 4b &&
749
750 git checkout A^0 &&
751 echo "File rewritten" >c &&
752
Elijah Newren70e24182020-03-13 20:03:02 +0000753 test-tool chmtime --get -3600 c >old-mtime &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700754
755 GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
756
Elijah Newrenc04ba512018-04-19 10:58:19 -0700757 test_must_be_empty err &&
758
Elijah Newren9f697de2020-02-27 00:14:23 +0000759 # Make sure c was NOT updated
760 test-tool chmtime --get c >new-mtime &&
761 test_cmp old-mtime new-mtime &&
Elijah Newrenc04ba512018-04-19 10:58:19 -0700762
763 git ls-files -s >index_files &&
764 test_line_count = 1 index_files &&
765
766 git rev-parse >actual :0:c &&
767 git rev-parse >expect A:c &&
768 test_cmp expect actual &&
769
770 git hash-object c >actual &&
771 echo "File rewritten" | git hash-object --stdin >expect &&
772 test_cmp expect actual &&
773
774 test_must_fail git rev-parse HEAD:b &&
775 test_path_is_missing b
776 )
777'
778
779test_done