Merge branch 'cc/codespeed'
[git] / t / t3030-merge-recursive.sh
1 #!/bin/sh
2
3 test_description='merge-recursive backend test'
4
5 . ./test-lib.sh
6
7 test_expect_success 'setup 1' '
8
9         echo hello >a &&
10         o0=$(git hash-object a) &&
11         cp a b &&
12         cp a c &&
13         mkdir d &&
14         cp a d/e &&
15
16         test_tick &&
17         git add a b c d/e &&
18         git commit -m initial &&
19         c0=$(git rev-parse --verify HEAD) &&
20         git branch side &&
21         git branch df-1 &&
22         git branch df-2 &&
23         git branch df-3 &&
24         git branch remove &&
25         git branch submod &&
26         git branch copy &&
27         git branch rename &&
28         git branch rename-ln &&
29
30         echo hello >>a &&
31         cp a d/e &&
32         o1=$(git hash-object a) &&
33
34         git add a d/e &&
35
36         test_tick &&
37         git commit -m "master modifies a and d/e" &&
38         c1=$(git rev-parse --verify HEAD) &&
39         ( git ls-tree -r HEAD ; git ls-files -s ) >actual &&
40         (
41                 echo "100644 blob $o1   a"
42                 echo "100644 blob $o0   b"
43                 echo "100644 blob $o0   c"
44                 echo "100644 blob $o1   d/e"
45                 echo "100644 $o1 0      a"
46                 echo "100644 $o0 0      b"
47                 echo "100644 $o0 0      c"
48                 echo "100644 $o1 0      d/e"
49         ) >expected &&
50         test_cmp expected actual
51 '
52
53 test_expect_success 'setup 2' '
54
55         rm -rf [abcd] &&
56         git checkout side &&
57         ( git ls-tree -r HEAD ; git ls-files -s ) >actual &&
58         (
59                 echo "100644 blob $o0   a"
60                 echo "100644 blob $o0   b"
61                 echo "100644 blob $o0   c"
62                 echo "100644 blob $o0   d/e"
63                 echo "100644 $o0 0      a"
64                 echo "100644 $o0 0      b"
65                 echo "100644 $o0 0      c"
66                 echo "100644 $o0 0      d/e"
67         ) >expected &&
68         test_cmp expected actual &&
69
70         echo goodbye >>a &&
71         o2=$(git hash-object a) &&
72
73         git add a &&
74
75         test_tick &&
76         git commit -m "side modifies a" &&
77         c2=$(git rev-parse --verify HEAD) &&
78         ( git ls-tree -r HEAD ; git ls-files -s ) >actual &&
79         (
80                 echo "100644 blob $o2   a"
81                 echo "100644 blob $o0   b"
82                 echo "100644 blob $o0   c"
83                 echo "100644 blob $o0   d/e"
84                 echo "100644 $o2 0      a"
85                 echo "100644 $o0 0      b"
86                 echo "100644 $o0 0      c"
87                 echo "100644 $o0 0      d/e"
88         ) >expected &&
89         test_cmp expected actual
90 '
91
92 test_expect_success 'setup 3' '
93
94         rm -rf [abcd] &&
95         git checkout df-1 &&
96         ( git ls-tree -r HEAD ; git ls-files -s ) >actual &&
97         (
98                 echo "100644 blob $o0   a"
99                 echo "100644 blob $o0   b"
100                 echo "100644 blob $o0   c"
101                 echo "100644 blob $o0   d/e"
102                 echo "100644 $o0 0      a"
103                 echo "100644 $o0 0      b"
104                 echo "100644 $o0 0      c"
105                 echo "100644 $o0 0      d/e"
106         ) >expected &&
107         test_cmp expected actual &&
108
109         rm -f b && mkdir b && echo df-1 >b/c && git add b/c &&
110         o3=$(git hash-object b/c) &&
111
112         test_tick &&
113         git commit -m "df-1 makes b/c" &&
114         c3=$(git rev-parse --verify HEAD) &&
115         ( git ls-tree -r HEAD ; git ls-files -s ) >actual &&
116         (
117                 echo "100644 blob $o0   a"
118                 echo "100644 blob $o3   b/c"
119                 echo "100644 blob $o0   c"
120                 echo "100644 blob $o0   d/e"
121                 echo "100644 $o0 0      a"
122                 echo "100644 $o3 0      b/c"
123                 echo "100644 $o0 0      c"
124                 echo "100644 $o0 0      d/e"
125         ) >expected &&
126         test_cmp expected actual
127 '
128
129 test_expect_success 'setup 4' '
130
131         rm -rf [abcd] &&
132         git checkout df-2 &&
133         ( git ls-tree -r HEAD ; git ls-files -s ) >actual &&
134         (
135                 echo "100644 blob $o0   a"
136                 echo "100644 blob $o0   b"
137                 echo "100644 blob $o0   c"
138                 echo "100644 blob $o0   d/e"
139                 echo "100644 $o0 0      a"
140                 echo "100644 $o0 0      b"
141                 echo "100644 $o0 0      c"
142                 echo "100644 $o0 0      d/e"
143         ) >expected &&
144         test_cmp expected actual &&
145
146         rm -f a && mkdir a && echo df-2 >a/c && git add a/c &&
147         o4=$(git hash-object a/c) &&
148
149         test_tick &&
150         git commit -m "df-2 makes a/c" &&
151         c4=$(git rev-parse --verify HEAD) &&
152         ( git ls-tree -r HEAD ; git ls-files -s ) >actual &&
153         (
154                 echo "100644 blob $o4   a/c"
155                 echo "100644 blob $o0   b"
156                 echo "100644 blob $o0   c"
157                 echo "100644 blob $o0   d/e"
158                 echo "100644 $o4 0      a/c"
159                 echo "100644 $o0 0      b"
160                 echo "100644 $o0 0      c"
161                 echo "100644 $o0 0      d/e"
162         ) >expected &&
163         test_cmp expected actual
164 '
165
166 test_expect_success 'setup 5' '
167
168         rm -rf [abcd] &&
169         git checkout remove &&
170         ( git ls-tree -r HEAD ; git ls-files -s ) >actual &&
171         (
172                 echo "100644 blob $o0   a"
173                 echo "100644 blob $o0   b"
174                 echo "100644 blob $o0   c"
175                 echo "100644 blob $o0   d/e"
176                 echo "100644 $o0 0      a"
177                 echo "100644 $o0 0      b"
178                 echo "100644 $o0 0      c"
179                 echo "100644 $o0 0      d/e"
180         ) >expected &&
181         test_cmp expected actual &&
182
183         rm -f b &&
184         echo remove-conflict >a &&
185
186         git add a &&
187         git rm b &&
188         o5=$(git hash-object a) &&
189
190         test_tick &&
191         git commit -m "remove removes b and modifies a" &&
192         c5=$(git rev-parse --verify HEAD) &&
193         ( git ls-tree -r HEAD ; git ls-files -s ) >actual &&
194         (
195                 echo "100644 blob $o5   a"
196                 echo "100644 blob $o0   c"
197                 echo "100644 blob $o0   d/e"
198                 echo "100644 $o5 0      a"
199                 echo "100644 $o0 0      c"
200                 echo "100644 $o0 0      d/e"
201         ) >expected &&
202         test_cmp expected actual
203
204 '
205
206 test_expect_success 'setup 6' '
207
208         rm -rf [abcd] &&
209         git checkout df-3 &&
210         ( git ls-tree -r HEAD ; git ls-files -s ) >actual &&
211         (
212                 echo "100644 blob $o0   a"
213                 echo "100644 blob $o0   b"
214                 echo "100644 blob $o0   c"
215                 echo "100644 blob $o0   d/e"
216                 echo "100644 $o0 0      a"
217                 echo "100644 $o0 0      b"
218                 echo "100644 $o0 0      c"
219                 echo "100644 $o0 0      d/e"
220         ) >expected &&
221         test_cmp expected actual &&
222
223         rm -fr d && echo df-3 >d && git add d &&
224         o6=$(git hash-object d) &&
225
226         test_tick &&
227         git commit -m "df-3 makes d" &&
228         c6=$(git rev-parse --verify HEAD) &&
229         ( git ls-tree -r HEAD ; git ls-files -s ) >actual &&
230         (
231                 echo "100644 blob $o0   a"
232                 echo "100644 blob $o0   b"
233                 echo "100644 blob $o0   c"
234                 echo "100644 blob $o6   d"
235                 echo "100644 $o0 0      a"
236                 echo "100644 $o0 0      b"
237                 echo "100644 $o0 0      c"
238                 echo "100644 $o6 0      d"
239         ) >expected &&
240         test_cmp expected actual
241 '
242
243 test_expect_success 'setup 7' '
244
245         git checkout submod &&
246         git rm d/e &&
247         test_tick &&
248         git commit -m "remove d/e" &&
249         git update-index --add --cacheinfo 160000 $c1 d &&
250         test_tick &&
251         git commit -m "make d/ a submodule"
252 '
253
254 test_expect_success 'setup 8' '
255         git checkout rename &&
256         git mv a e &&
257         git add e &&
258         test_tick &&
259         git commit -m "rename a->e" &&
260         c7=$(git rev-parse --verify HEAD) &&
261         git checkout rename-ln &&
262         git mv a e &&
263         test_ln_s_add e a &&
264         test_tick &&
265         git commit -m "rename a->e, symlink a->e" &&
266         oln=$(printf e | git hash-object --stdin)
267 '
268
269 test_expect_success 'setup 9' '
270         git checkout copy &&
271         cp a e &&
272         git add e &&
273         test_tick &&
274         git commit -m "copy a->e"
275 '
276
277 test_expect_success 'merge-recursive simple' '
278
279         rm -fr [abcd] &&
280         git checkout -f "$c2" &&
281
282         test_expect_code 1 git merge-recursive "$c0" -- "$c2" "$c1"
283 '
284
285 test_expect_success 'merge-recursive result' '
286
287         git ls-files -s >actual &&
288         (
289                 echo "100644 $o0 1      a"
290                 echo "100644 $o2 2      a"
291                 echo "100644 $o1 3      a"
292                 echo "100644 $o0 0      b"
293                 echo "100644 $o0 0      c"
294                 echo "100644 $o1 0      d/e"
295         ) >expected &&
296         test_cmp expected actual
297
298 '
299
300 test_expect_success 'fail if the index has unresolved entries' '
301
302         rm -fr [abcd] &&
303         git checkout -f "$c1" &&
304
305         test_must_fail git merge "$c5" &&
306         test_must_fail git merge "$c5" 2> out &&
307         test_i18ngrep "not possible because you have unmerged files" out &&
308         git add -u &&
309         test_must_fail git merge "$c5" 2> out &&
310         test_i18ngrep "You have not concluded your merge" out &&
311         rm -f .git/MERGE_HEAD &&
312         test_must_fail git merge "$c5" 2> out &&
313         test_i18ngrep "Your local changes to the following files would be overwritten by merge:" out
314 '
315
316 test_expect_success 'merge-recursive remove conflict' '
317
318         rm -fr [abcd] &&
319         git checkout -f "$c1" &&
320
321         test_expect_code 1 git merge-recursive "$c0" -- "$c1" "$c5"
322 '
323
324 test_expect_success 'merge-recursive remove conflict' '
325
326         git ls-files -s >actual &&
327         (
328                 echo "100644 $o0 1      a"
329                 echo "100644 $o1 2      a"
330                 echo "100644 $o5 3      a"
331                 echo "100644 $o0 0      c"
332                 echo "100644 $o1 0      d/e"
333         ) >expected &&
334         test_cmp expected actual
335
336 '
337
338 test_expect_success 'merge-recursive d/f simple' '
339         rm -fr [abcd] &&
340         git reset --hard &&
341         git checkout -f "$c1" &&
342
343         git merge-recursive "$c0" -- "$c1" "$c3"
344 '
345
346 test_expect_success 'merge-recursive result' '
347
348         git ls-files -s >actual &&
349         (
350                 echo "100644 $o1 0      a"
351                 echo "100644 $o3 0      b/c"
352                 echo "100644 $o0 0      c"
353                 echo "100644 $o1 0      d/e"
354         ) >expected &&
355         test_cmp expected actual
356
357 '
358
359 test_expect_success 'merge-recursive d/f conflict' '
360
361         rm -fr [abcd] &&
362         git reset --hard &&
363         git checkout -f "$c1" &&
364
365         test_expect_code 1 git merge-recursive "$c0" -- "$c1" "$c4"
366 '
367
368 test_expect_success 'merge-recursive d/f conflict result' '
369
370         git ls-files -s >actual &&
371         (
372                 echo "100644 $o0 1      a"
373                 echo "100644 $o1 2      a"
374                 echo "100644 $o4 0      a/c"
375                 echo "100644 $o0 0      b"
376                 echo "100644 $o0 0      c"
377                 echo "100644 $o1 0      d/e"
378         ) >expected &&
379         test_cmp expected actual
380
381 '
382
383 test_expect_success 'merge-recursive d/f conflict the other way' '
384
385         rm -fr [abcd] &&
386         git reset --hard &&
387         git checkout -f "$c4" &&
388
389         test_expect_code 1 git merge-recursive "$c0" -- "$c4" "$c1"
390 '
391
392 test_expect_success 'merge-recursive d/f conflict result the other way' '
393
394         git ls-files -s >actual &&
395         (
396                 echo "100644 $o0 1      a"
397                 echo "100644 $o1 3      a"
398                 echo "100644 $o4 0      a/c"
399                 echo "100644 $o0 0      b"
400                 echo "100644 $o0 0      c"
401                 echo "100644 $o1 0      d/e"
402         ) >expected &&
403         test_cmp expected actual
404
405 '
406
407 test_expect_success 'merge-recursive d/f conflict' '
408
409         rm -fr [abcd] &&
410         git reset --hard &&
411         git checkout -f "$c1" &&
412
413         test_expect_code 1 git merge-recursive "$c0" -- "$c1" "$c6"
414 '
415
416 test_expect_success 'merge-recursive d/f conflict result' '
417
418         git ls-files -s >actual &&
419         (
420                 echo "100644 $o1 0      a"
421                 echo "100644 $o0 0      b"
422                 echo "100644 $o0 0      c"
423                 echo "100644 $o6 3      d"
424                 echo "100644 $o0 1      d/e"
425                 echo "100644 $o1 2      d/e"
426         ) >expected &&
427         test_cmp expected actual
428
429 '
430
431 test_expect_success 'merge-recursive d/f conflict' '
432
433         rm -fr [abcd] &&
434         git reset --hard &&
435         git checkout -f "$c6" &&
436
437         test_expect_code 1 git merge-recursive "$c0" -- "$c6" "$c1"
438 '
439
440 test_expect_success 'merge-recursive d/f conflict result' '
441
442         git ls-files -s >actual &&
443         (
444                 echo "100644 $o1 0      a"
445                 echo "100644 $o0 0      b"
446                 echo "100644 $o0 0      c"
447                 echo "100644 $o6 2      d"
448                 echo "100644 $o0 1      d/e"
449                 echo "100644 $o1 3      d/e"
450         ) >expected &&
451         test_cmp expected actual
452
453 '
454
455 test_expect_success 'reset and 3-way merge' '
456
457         git reset --hard "$c2" &&
458         git read-tree -m "$c0" "$c2" "$c1"
459
460 '
461
462 test_expect_success 'reset and bind merge' '
463
464         git reset --hard master &&
465         git read-tree --prefix=M/ master &&
466         git ls-files -s >actual &&
467         (
468                 echo "100644 $o1 0      M/a"
469                 echo "100644 $o0 0      M/b"
470                 echo "100644 $o0 0      M/c"
471                 echo "100644 $o1 0      M/d/e"
472                 echo "100644 $o1 0      a"
473                 echo "100644 $o0 0      b"
474                 echo "100644 $o0 0      c"
475                 echo "100644 $o1 0      d/e"
476         ) >expected &&
477         test_cmp expected actual &&
478
479         git read-tree --prefix=a1/ master &&
480         git ls-files -s >actual &&
481         (
482                 echo "100644 $o1 0      M/a"
483                 echo "100644 $o0 0      M/b"
484                 echo "100644 $o0 0      M/c"
485                 echo "100644 $o1 0      M/d/e"
486                 echo "100644 $o1 0      a"
487                 echo "100644 $o1 0      a1/a"
488                 echo "100644 $o0 0      a1/b"
489                 echo "100644 $o0 0      a1/c"
490                 echo "100644 $o1 0      a1/d/e"
491                 echo "100644 $o0 0      b"
492                 echo "100644 $o0 0      c"
493                 echo "100644 $o1 0      d/e"
494         ) >expected &&
495         test_cmp expected actual &&
496
497         git read-tree --prefix=z/ master &&
498         git ls-files -s >actual &&
499         (
500                 echo "100644 $o1 0      M/a"
501                 echo "100644 $o0 0      M/b"
502                 echo "100644 $o0 0      M/c"
503                 echo "100644 $o1 0      M/d/e"
504                 echo "100644 $o1 0      a"
505                 echo "100644 $o1 0      a1/a"
506                 echo "100644 $o0 0      a1/b"
507                 echo "100644 $o0 0      a1/c"
508                 echo "100644 $o1 0      a1/d/e"
509                 echo "100644 $o0 0      b"
510                 echo "100644 $o0 0      c"
511                 echo "100644 $o1 0      d/e"
512                 echo "100644 $o1 0      z/a"
513                 echo "100644 $o0 0      z/b"
514                 echo "100644 $o0 0      z/c"
515                 echo "100644 $o1 0      z/d/e"
516         ) >expected &&
517         test_cmp expected actual
518
519 '
520
521 test_expect_success 'merge-recursive w/ empty work tree - ours has rename' '
522         (
523                 GIT_WORK_TREE="$PWD/ours-has-rename-work" &&
524                 export GIT_WORK_TREE &&
525                 GIT_INDEX_FILE="$PWD/ours-has-rename-index" &&
526                 export GIT_INDEX_FILE &&
527                 mkdir "$GIT_WORK_TREE" &&
528                 git read-tree -i -m $c7 &&
529                 git update-index --ignore-missing --refresh &&
530                 git merge-recursive $c0 -- $c7 $c3 &&
531                 git ls-files -s >actual-files
532         ) 2>actual-err &&
533         >expected-err &&
534         cat >expected-files <<-EOF &&
535         100644 $o3 0    b/c
536         100644 $o0 0    c
537         100644 $o0 0    d/e
538         100644 $o0 0    e
539         EOF
540         test_cmp expected-files actual-files &&
541         test_cmp expected-err actual-err
542 '
543
544 test_expect_success 'merge-recursive w/ empty work tree - theirs has rename' '
545         (
546                 GIT_WORK_TREE="$PWD/theirs-has-rename-work" &&
547                 export GIT_WORK_TREE &&
548                 GIT_INDEX_FILE="$PWD/theirs-has-rename-index" &&
549                 export GIT_INDEX_FILE &&
550                 mkdir "$GIT_WORK_TREE" &&
551                 git read-tree -i -m $c3 &&
552                 git update-index --ignore-missing --refresh &&
553                 git merge-recursive $c0 -- $c3 $c7 &&
554                 git ls-files -s >actual-files
555         ) 2>actual-err &&
556         >expected-err &&
557         cat >expected-files <<-EOF &&
558         100644 $o3 0    b/c
559         100644 $o0 0    c
560         100644 $o0 0    d/e
561         100644 $o0 0    e
562         EOF
563         test_cmp expected-files actual-files &&
564         test_cmp expected-err actual-err
565 '
566
567 test_expect_success 'merge removes empty directories' '
568
569         git reset --hard master &&
570         git checkout -b rm &&
571         git rm d/e &&
572         git commit -mremoved-d/e &&
573         git checkout master &&
574         git merge -s recursive rm &&
575         test_must_fail test -d d
576 '
577
578 test_expect_success 'merge-recursive simple w/submodule' '
579
580         git checkout submod &&
581         git merge remove
582 '
583
584 test_expect_success 'merge-recursive simple w/submodule result' '
585
586         git ls-files -s >actual &&
587         (
588                 echo "100644 $o5 0      a"
589                 echo "100644 $o0 0      c"
590                 echo "160000 $c1 0      d"
591         ) >expected &&
592         test_cmp expected actual
593 '
594
595 test_expect_success 'merge-recursive copy vs. rename' '
596         git checkout -f copy &&
597         git merge rename &&
598         ( git ls-tree -r HEAD && git ls-files -s ) >actual &&
599         (
600                 echo "100644 blob $o0   b"
601                 echo "100644 blob $o0   c"
602                 echo "100644 blob $o0   d/e"
603                 echo "100644 blob $o0   e"
604                 echo "100644 $o0 0      b"
605                 echo "100644 $o0 0      c"
606                 echo "100644 $o0 0      d/e"
607                 echo "100644 $o0 0      e"
608         ) >expected &&
609         test_cmp expected actual
610 '
611
612 test_expect_failure 'merge-recursive rename vs. rename/symlink' '
613
614         git checkout -f rename &&
615         git merge rename-ln &&
616         ( git ls-tree -r HEAD ; git ls-files -s ) >actual &&
617         (
618                 echo "120000 blob $oln  a"
619                 echo "100644 blob $o0   b"
620                 echo "100644 blob $o0   c"
621                 echo "100644 blob $o0   d/e"
622                 echo "100644 blob $o0   e"
623                 echo "120000 $oln 0     a"
624                 echo "100644 $o0 0      b"
625                 echo "100644 $o0 0      c"
626                 echo "100644 $o0 0      d/e"
627                 echo "100644 $o0 0      e"
628         ) >expected &&
629         test_cmp expected actual
630 '
631
632 test_expect_success 'merging with triple rename across D/F conflict' '
633         git reset --hard HEAD &&
634         git checkout -b main &&
635         git rm -rf . &&
636
637         echo "just a file" >sub1 &&
638         mkdir -p sub2 &&
639         echo content1 >sub2/file1 &&
640         echo content2 >sub2/file2 &&
641         echo content3 >sub2/file3 &&
642         mkdir simple &&
643         echo base >simple/bar &&
644         git add -A &&
645         test_tick &&
646         git commit -m base &&
647
648         git checkout -b other &&
649         echo more >>simple/bar &&
650         test_tick &&
651         git commit -a -m changesimplefile &&
652
653         git checkout main &&
654         git rm sub1 &&
655         git mv sub2 sub1 &&
656         test_tick &&
657         git commit -m changefiletodir &&
658
659         test_tick &&
660         git merge other
661 '
662
663 test_expect_success 'merge-recursive remembers the names of all base trees' '
664         git reset --hard HEAD &&
665
666         # more trees than static slots used by oid_to_hex()
667         for commit in $c0 $c2 $c4 $c5 $c6 $c7
668         do
669                 git rev-parse "$commit^{tree}"
670         done >trees &&
671
672         # ignore the return code -- it only fails because the input is weird
673         test_must_fail git -c merge.verbosity=5 merge-recursive $(cat trees) -- $c1 $c3 >out &&
674
675         # merge-recursive prints in reverse order, but we do not care
676         sort <trees >expect &&
677         sed -n "s/^virtual //p" out | sort >actual &&
678         test_cmp expect actual
679 '
680
681 test_expect_success 'merge-recursive internal merge resolves to the sameness' '
682         git reset --hard HEAD &&
683
684         # We are going to create a history leading to two criss-cross
685         # branches A and B.  The common ancestor at the bottom, O0,
686         # has two child commits O1 and O2, both of which will be merge
687         # base between A and B, like so:
688         #
689         #       O1---A
690         #      /  \ /
691         #    O0    .
692         #      \  / \
693         #       O2---B
694         #
695         # The recently added "check to see if the index is different from
696         # the tree into which something else is getting merged" check must
697         # NOT kick in when an inner merge between O1 and O2 is made.  Both
698         # O1 and O2 happen to have the same tree as O0 in this test to
699         # trigger the bug---whether the inner merge is made by merging O2
700         # into O1 or O1 into O2, their common ancestor O0 and the branch
701         # being merged have the same tree.  We should not trigger the "is
702         # the index dirty?" check in this case.
703
704         echo "zero" >file &&
705         git add file &&
706         test_tick &&
707         git commit -m "O0" &&
708         O0=$(git rev-parse HEAD) &&
709
710         test_tick &&
711         git commit --allow-empty -m "O1" &&
712         O1=$(git rev-parse HEAD) &&
713
714         git reset --hard $O0 &&
715         test_tick &&
716         git commit --allow-empty -m "O2" &&
717         O2=$(git rev-parse HEAD) &&
718
719         test_tick &&
720         git merge -s ours $O1 &&
721         B=$(git rev-parse HEAD) &&
722
723         git reset --hard $O1 &&
724         test_tick &&
725         git merge -s ours $O2 &&
726         A=$(git rev-parse HEAD) &&
727
728         git merge $B
729 '
730
731 test_done