t / t3030-merge-recursive.shon commit Merge branch 'jk/ident-ai-canonname-could-be-null' into maint (11738dd)
   1#!/bin/sh
   2
   3test_description='merge-recursive backend test'
   4
   5. ./test-lib.sh
   6
   7test_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
  53test_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
  92test_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
 129test_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
 166test_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
 206test_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
 243test_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
 254test_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
 269test_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
 277test_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
 285test_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
 300test_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
 316test_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
 324test_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
 338test_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
 346test_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
 359test_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
 368test_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
 383test_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
 392test_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
 407test_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
 416test_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
 431test_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
 440test_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
 455test_expect_success 'reset and 3-way merge' '
 456
 457        git reset --hard "$c2" &&
 458        git read-tree -m "$c0" "$c2" "$c1"
 459
 460'
 461
 462test_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
 521test_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
 544test_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
 567test_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
 578test_expect_failure 'merge-recursive simple w/submodule' '
 579
 580        git checkout submod &&
 581        git merge remove
 582'
 583
 584test_expect_failure '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
 595test_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
 612test_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
 632test_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
 663test_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
 681test_done