t / t7201-co.shon commit Merge branch 'bb/unicode-12.1-reiwa' (3dc47c4)
   1#!/bin/sh
   2#
   3# Copyright (c) 2006 Junio C Hamano
   4#
   5
   6test_description='git checkout tests.
   7
   8Creates master, forks renamer and side branches from it.
   9Test switching across them.
  10
  11  ! [master] Initial A one, A two
  12   * [renamer] Renamer R one->uno, M two
  13    ! [side] Side M one, D two, A three
  14     ! [simple] Simple D one, M two
  15  ----
  16     + [simple] Simple D one, M two
  17    +  [side] Side M one, D two, A three
  18   *   [renamer] Renamer R one->uno, M two
  19  +*++ [master] Initial A one, A two
  20
  21'
  22
  23. ./test-lib.sh
  24
  25test_tick
  26
  27fill () {
  28        for i
  29        do
  30                echo "$i"
  31        done
  32}
  33
  34
  35test_expect_success setup '
  36
  37        fill x y z > same &&
  38        fill 1 2 3 4 5 6 7 8 >one &&
  39        fill a b c d e >two &&
  40        git add same one two &&
  41        git commit -m "Initial A one, A two" &&
  42
  43        git checkout -b renamer &&
  44        rm -f one &&
  45        fill 1 3 4 5 6 7 8 >uno &&
  46        git add uno &&
  47        fill a b c d e f >two &&
  48        git commit -a -m "Renamer R one->uno, M two" &&
  49
  50        git checkout -b side master &&
  51        fill 1 2 3 4 5 6 7 >one &&
  52        fill A B C D E >three &&
  53        rm -f two &&
  54        git update-index --add --remove one two three &&
  55        git commit -m "Side M one, D two, A three" &&
  56
  57        git checkout -b simple master &&
  58        rm -f one &&
  59        fill a c e > two &&
  60        git commit -a -m "Simple D one, M two" &&
  61
  62        git checkout master
  63'
  64
  65test_expect_success "checkout from non-existing branch" '
  66
  67        git checkout -b delete-me master &&
  68        git update-ref -d --no-deref refs/heads/delete-me &&
  69        test refs/heads/delete-me = "$(git symbolic-ref HEAD)" &&
  70        git checkout master &&
  71        test refs/heads/master = "$(git symbolic-ref HEAD)"
  72'
  73
  74test_expect_success "checkout with dirty tree without -m" '
  75
  76        fill 0 1 2 3 4 5 6 7 8 >one &&
  77        if git checkout side
  78        then
  79                echo Not happy
  80                false
  81        else
  82                echo "happy - failed correctly"
  83        fi
  84
  85'
  86
  87test_expect_success "checkout with unrelated dirty tree without -m" '
  88
  89        git checkout -f master &&
  90        fill 0 1 2 3 4 5 6 7 8 >same &&
  91        cp same kept &&
  92        git checkout side >messages &&
  93        test_cmp same kept &&
  94        printf "M\t%s\n" same >messages.expect &&
  95        test_cmp messages.expect messages
  96'
  97
  98test_expect_success "checkout -m with dirty tree" '
  99
 100        git checkout -f master &&
 101        git clean -f &&
 102
 103        fill 0 1 2 3 4 5 6 7 8 >one &&
 104        git checkout -m side > messages &&
 105
 106        test "$(git symbolic-ref HEAD)" = "refs/heads/side" &&
 107
 108        printf "M\t%s\n" one >expect.messages &&
 109        test_cmp expect.messages messages &&
 110
 111        fill "M one" "A three" "D       two" >expect.master &&
 112        git diff --name-status master >current.master &&
 113        test_cmp expect.master current.master &&
 114
 115        fill "M one" >expect.side &&
 116        git diff --name-status side >current.side &&
 117        test_cmp expect.side current.side &&
 118
 119        git diff --cached >current.index &&
 120        test_must_be_empty current.index
 121'
 122
 123test_expect_success "checkout -m with dirty tree, renamed" '
 124
 125        git checkout -f master && git clean -f &&
 126
 127        fill 1 2 3 4 5 7 8 >one &&
 128        if git checkout renamer
 129        then
 130                echo Not happy
 131                false
 132        else
 133                echo "happy - failed correctly"
 134        fi &&
 135
 136        git checkout -m renamer &&
 137        fill 1 3 4 5 7 8 >expect &&
 138        test_cmp expect uno &&
 139        ! test -f one &&
 140        git diff --cached >current &&
 141        test_must_be_empty current
 142
 143'
 144
 145test_expect_success 'checkout -m with merge conflict' '
 146
 147        git checkout -f master && git clean -f &&
 148
 149        fill 1 T 3 4 5 6 S 8 >one &&
 150        if git checkout renamer
 151        then
 152                echo Not happy
 153                false
 154        else
 155                echo "happy - failed correctly"
 156        fi &&
 157
 158        git checkout -m renamer &&
 159
 160        git diff master:one :3:uno |
 161        sed -e "1,/^@@/d" -e "/^ /d" -e "s/^-/d/" -e "s/^+/a/" >current &&
 162        fill d2 aT d7 aS >expect &&
 163        test_cmp expect current &&
 164        git diff --cached two >current &&
 165        test_must_be_empty current
 166'
 167
 168test_expect_success 'format of merge conflict from checkout -m' '
 169
 170        git checkout -f master && git clean -f &&
 171
 172        fill b d > two &&
 173        git checkout -m simple &&
 174
 175        git ls-files >current &&
 176        fill same two two two >expect &&
 177        test_cmp expect current &&
 178
 179        cat <<-EOF >expect &&
 180        <<<<<<< simple
 181        a
 182        c
 183        e
 184        =======
 185        b
 186        d
 187        >>>>>>> local
 188        EOF
 189        test_cmp expect two
 190'
 191
 192test_expect_success 'checkout --merge --conflict=diff3 <branch>' '
 193
 194        git checkout -f master && git reset --hard && git clean -f &&
 195
 196        fill b d > two &&
 197        git checkout --merge --conflict=diff3 simple &&
 198
 199        cat <<-EOF >expect &&
 200        <<<<<<< simple
 201        a
 202        c
 203        e
 204        ||||||| master
 205        a
 206        b
 207        c
 208        d
 209        e
 210        =======
 211        b
 212        d
 213        >>>>>>> local
 214        EOF
 215        test_cmp expect two
 216'
 217
 218test_expect_success 'switch to another branch while carrying a deletion' '
 219
 220        git checkout -f master && git reset --hard && git clean -f &&
 221        git rm two &&
 222
 223        test_must_fail git checkout simple 2>errs &&
 224        test_i18ngrep overwritten errs &&
 225
 226        test_must_fail git read-tree --quiet -m -u HEAD simple 2>errs &&
 227        test_must_be_empty errs
 228'
 229
 230test_expect_success 'checkout to detach HEAD (with advice declined)' '
 231
 232        git config advice.detachedHead false &&
 233        git checkout -f renamer && git clean -f &&
 234        git checkout renamer^ 2>messages &&
 235        test_i18ngrep "HEAD is now at 7329388" messages &&
 236        test_line_count = 1 messages &&
 237        H=$(git rev-parse --verify HEAD) &&
 238        M=$(git show-ref -s --verify refs/heads/master) &&
 239        test "z$H" = "z$M" &&
 240        if git symbolic-ref HEAD >/dev/null 2>&1
 241        then
 242                echo "OOPS, HEAD is still symbolic???"
 243                false
 244        else
 245                : happy
 246        fi
 247'
 248
 249test_expect_success 'checkout to detach HEAD' '
 250        git config advice.detachedHead true &&
 251        git checkout -f renamer && git clean -f &&
 252        GIT_TEST_GETTEXT_POISON= git checkout renamer^ 2>messages &&
 253        grep "HEAD is now at 7329388" messages &&
 254        test_line_count -gt 1 messages &&
 255        H=$(git rev-parse --verify HEAD) &&
 256        M=$(git show-ref -s --verify refs/heads/master) &&
 257        test "z$H" = "z$M" &&
 258        if git symbolic-ref HEAD >/dev/null 2>&1
 259        then
 260                echo "OOPS, HEAD is still symbolic???"
 261                false
 262        else
 263                : happy
 264        fi
 265'
 266
 267test_expect_success 'checkout to detach HEAD with branchname^' '
 268
 269        git checkout -f master && git clean -f &&
 270        git checkout renamer^ &&
 271        H=$(git rev-parse --verify HEAD) &&
 272        M=$(git show-ref -s --verify refs/heads/master) &&
 273        test "z$H" = "z$M" &&
 274        if git symbolic-ref HEAD >/dev/null 2>&1
 275        then
 276                echo "OOPS, HEAD is still symbolic???"
 277                false
 278        else
 279                : happy
 280        fi
 281'
 282
 283test_expect_success 'checkout to detach HEAD with :/message' '
 284
 285        git checkout -f master && git clean -f &&
 286        git checkout ":/Initial" &&
 287        H=$(git rev-parse --verify HEAD) &&
 288        M=$(git show-ref -s --verify refs/heads/master) &&
 289        test "z$H" = "z$M" &&
 290        if git symbolic-ref HEAD >/dev/null 2>&1
 291        then
 292                echo "OOPS, HEAD is still symbolic???"
 293                false
 294        else
 295                : happy
 296        fi
 297'
 298
 299test_expect_success 'checkout to detach HEAD with HEAD^0' '
 300
 301        git checkout -f master && git clean -f &&
 302        git checkout HEAD^0 &&
 303        H=$(git rev-parse --verify HEAD) &&
 304        M=$(git show-ref -s --verify refs/heads/master) &&
 305        test "z$H" = "z$M" &&
 306        if git symbolic-ref HEAD >/dev/null 2>&1
 307        then
 308                echo "OOPS, HEAD is still symbolic???"
 309                false
 310        else
 311                : happy
 312        fi
 313'
 314
 315test_expect_success 'checkout with ambiguous tag/branch names' '
 316
 317        git tag both side &&
 318        git branch both master &&
 319        git reset --hard &&
 320        git checkout master &&
 321
 322        git checkout both &&
 323        H=$(git rev-parse --verify HEAD) &&
 324        M=$(git show-ref -s --verify refs/heads/master) &&
 325        test "z$H" = "z$M" &&
 326        name=$(git symbolic-ref HEAD 2>/dev/null) &&
 327        test "z$name" = zrefs/heads/both
 328
 329'
 330
 331test_expect_success 'checkout with ambiguous tag/branch names' '
 332
 333        git reset --hard &&
 334        git checkout master &&
 335
 336        git tag frotz side &&
 337        git branch frotz master &&
 338        git reset --hard &&
 339        git checkout master &&
 340
 341        git checkout tags/frotz &&
 342        H=$(git rev-parse --verify HEAD) &&
 343        S=$(git show-ref -s --verify refs/heads/side) &&
 344        test "z$H" = "z$S" &&
 345        if name=$(git symbolic-ref HEAD 2>/dev/null)
 346        then
 347                echo "Bad -- should have detached"
 348                false
 349        else
 350                : happy
 351        fi
 352
 353'
 354
 355test_expect_success 'switch branches while in subdirectory' '
 356
 357        git reset --hard &&
 358        git checkout master &&
 359
 360        mkdir subs &&
 361        (
 362                cd subs &&
 363                git checkout side
 364        ) &&
 365        ! test -f subs/one &&
 366        rm -fr subs
 367
 368'
 369
 370test_expect_success 'checkout specific path while in subdirectory' '
 371
 372        git reset --hard &&
 373        git checkout side &&
 374        mkdir subs &&
 375        >subs/bero &&
 376        git add subs/bero &&
 377        git commit -m "add subs/bero" &&
 378
 379        git checkout master &&
 380        mkdir -p subs &&
 381        (
 382                cd subs &&
 383                git checkout side -- bero
 384        ) &&
 385        test -f subs/bero
 386
 387'
 388
 389test_expect_success \
 390    'checkout w/--track sets up tracking' '
 391    git config branch.autosetupmerge false &&
 392    git checkout master &&
 393    git checkout --track -b track1 &&
 394    test "$(git config branch.track1.remote)" &&
 395    test "$(git config branch.track1.merge)"'
 396
 397test_expect_success \
 398    'checkout w/autosetupmerge=always sets up tracking' '
 399    test_when_finished git config branch.autosetupmerge false &&
 400    git config branch.autosetupmerge always &&
 401    git checkout master &&
 402    git checkout -b track2 &&
 403    test "$(git config branch.track2.remote)" &&
 404    test "$(git config branch.track2.merge)"'
 405
 406test_expect_success 'checkout w/--track from non-branch HEAD fails' '
 407    git checkout master^0 &&
 408    test_must_fail git symbolic-ref HEAD &&
 409    test_must_fail git checkout --track -b track &&
 410    test_must_fail git rev-parse --verify track &&
 411    test_must_fail git symbolic-ref HEAD &&
 412    test "z$(git rev-parse master^0)" = "z$(git rev-parse HEAD)"
 413'
 414
 415test_expect_success 'checkout w/--track from tag fails' '
 416    git checkout master^0 &&
 417    test_must_fail git symbolic-ref HEAD &&
 418    test_must_fail git checkout --track -b track frotz &&
 419    test_must_fail git rev-parse --verify track &&
 420    test_must_fail git symbolic-ref HEAD &&
 421    test "z$(git rev-parse master^0)" = "z$(git rev-parse HEAD)"
 422'
 423
 424test_expect_success 'detach a symbolic link HEAD' '
 425    git checkout master &&
 426    git config --bool core.prefersymlinkrefs yes &&
 427    git checkout side &&
 428    git checkout master &&
 429    it=$(git symbolic-ref HEAD) &&
 430    test "z$it" = zrefs/heads/master &&
 431    here=$(git rev-parse --verify refs/heads/master) &&
 432    git checkout side^ &&
 433    test "z$(git rev-parse --verify refs/heads/master)" = "z$here"
 434'
 435
 436test_expect_success \
 437    'checkout with --track fakes a sensible -b <name>' '
 438    git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" &&
 439    git update-ref refs/remotes/origin/koala/bear renamer &&
 440
 441    git checkout --track origin/koala/bear &&
 442    test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
 443    test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
 444
 445    git checkout master && git branch -D koala/bear &&
 446
 447    git checkout --track refs/remotes/origin/koala/bear &&
 448    test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
 449    test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
 450
 451    git checkout master && git branch -D koala/bear &&
 452
 453    git checkout --track remotes/origin/koala/bear &&
 454    test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
 455    test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)"
 456'
 457
 458test_expect_success \
 459    'checkout with --track, but without -b, fails with too short tracked name' '
 460    test_must_fail git checkout --track renamer'
 461
 462setup_conflicting_index () {
 463        rm -f .git/index &&
 464        O=$(echo original | git hash-object -w --stdin) &&
 465        A=$(echo ourside | git hash-object -w --stdin) &&
 466        B=$(echo theirside | git hash-object -w --stdin) &&
 467        (
 468                echo "100644 $A 0       fild" &&
 469                echo "100644 $O 1       file" &&
 470                echo "100644 $A 2       file" &&
 471                echo "100644 $B 3       file" &&
 472                echo "100644 $A 0       filf"
 473        ) | git update-index --index-info
 474}
 475
 476test_expect_success 'checkout an unmerged path should fail' '
 477        setup_conflicting_index &&
 478        echo "none of the above" >sample &&
 479        cat sample >fild &&
 480        cat sample >file &&
 481        cat sample >filf &&
 482        test_must_fail git checkout fild file filf &&
 483        test_cmp sample fild &&
 484        test_cmp sample filf &&
 485        test_cmp sample file
 486'
 487
 488test_expect_success 'checkout with an unmerged path can be ignored' '
 489        setup_conflicting_index &&
 490        echo "none of the above" >sample &&
 491        echo ourside >expect &&
 492        cat sample >fild &&
 493        cat sample >file &&
 494        cat sample >filf &&
 495        git checkout -f fild file filf &&
 496        test_cmp expect fild &&
 497        test_cmp expect filf &&
 498        test_cmp sample file
 499'
 500
 501test_expect_success 'checkout unmerged stage' '
 502        setup_conflicting_index &&
 503        echo "none of the above" >sample &&
 504        echo ourside >expect &&
 505        cat sample >fild &&
 506        cat sample >file &&
 507        cat sample >filf &&
 508        git checkout --ours . &&
 509        test_cmp expect fild &&
 510        test_cmp expect filf &&
 511        test_cmp expect file &&
 512        git checkout --theirs file &&
 513        test ztheirside = "z$(cat file)"
 514'
 515
 516test_expect_success 'checkout with --merge' '
 517        setup_conflicting_index &&
 518        echo "none of the above" >sample &&
 519        echo ourside >expect &&
 520        cat sample >fild &&
 521        cat sample >file &&
 522        cat sample >filf &&
 523        git checkout -m -- fild file filf &&
 524        (
 525                echo "<<<<<<< ours" &&
 526                echo ourside &&
 527                echo "=======" &&
 528                echo theirside &&
 529                echo ">>>>>>> theirs"
 530        ) >merged &&
 531        test_cmp expect fild &&
 532        test_cmp expect filf &&
 533        test_cmp merged file
 534'
 535
 536test_expect_success 'checkout with --merge, in diff3 -m style' '
 537        git config merge.conflictstyle diff3 &&
 538        setup_conflicting_index &&
 539        echo "none of the above" >sample &&
 540        echo ourside >expect &&
 541        cat sample >fild &&
 542        cat sample >file &&
 543        cat sample >filf &&
 544        git checkout -m -- fild file filf &&
 545        (
 546                echo "<<<<<<< ours" &&
 547                echo ourside &&
 548                echo "||||||| base" &&
 549                echo original &&
 550                echo "=======" &&
 551                echo theirside &&
 552                echo ">>>>>>> theirs"
 553        ) >merged &&
 554        test_cmp expect fild &&
 555        test_cmp expect filf &&
 556        test_cmp merged file
 557'
 558
 559test_expect_success 'checkout --conflict=merge, overriding config' '
 560        git config merge.conflictstyle diff3 &&
 561        setup_conflicting_index &&
 562        echo "none of the above" >sample &&
 563        echo ourside >expect &&
 564        cat sample >fild &&
 565        cat sample >file &&
 566        cat sample >filf &&
 567        git checkout --conflict=merge -- fild file filf &&
 568        (
 569                echo "<<<<<<< ours" &&
 570                echo ourside &&
 571                echo "=======" &&
 572                echo theirside &&
 573                echo ">>>>>>> theirs"
 574        ) >merged &&
 575        test_cmp expect fild &&
 576        test_cmp expect filf &&
 577        test_cmp merged file
 578'
 579
 580test_expect_success 'checkout --conflict=diff3' '
 581        test_unconfig merge.conflictstyle &&
 582        setup_conflicting_index &&
 583        echo "none of the above" >sample &&
 584        echo ourside >expect &&
 585        cat sample >fild &&
 586        cat sample >file &&
 587        cat sample >filf &&
 588        git checkout --conflict=diff3 -- fild file filf &&
 589        (
 590                echo "<<<<<<< ours" &&
 591                echo ourside &&
 592                echo "||||||| base" &&
 593                echo original &&
 594                echo "=======" &&
 595                echo theirside &&
 596                echo ">>>>>>> theirs"
 597        ) >merged &&
 598        test_cmp expect fild &&
 599        test_cmp expect filf &&
 600        test_cmp merged file
 601'
 602
 603test_expect_success 'failing checkout -b should not break working tree' '
 604        git reset --hard master &&
 605        git symbolic-ref HEAD refs/heads/master &&
 606        test_must_fail git checkout -b renamer side^ &&
 607        test $(git symbolic-ref HEAD) = refs/heads/master &&
 608        git diff --exit-code &&
 609        git diff --cached --exit-code
 610
 611'
 612
 613test_expect_success 'switch out of non-branch' '
 614        git reset --hard master &&
 615        git checkout master^0 &&
 616        echo modified >one &&
 617        test_must_fail git checkout renamer 2>error.log &&
 618        ! grep "^Previous HEAD" error.log
 619'
 620
 621(
 622 echo "#!$SHELL_PATH"
 623 cat <<\EOF
 624O=$1 A=$2 B=$3
 625cat "$A" >.tmp
 626exec >"$A"
 627echo '<<<<<<< filfre-theirs'
 628cat "$B"
 629echo '||||||| filfre-common'
 630cat "$O"
 631echo '======='
 632cat ".tmp"
 633echo '>>>>>>> filfre-ours'
 634rm -f .tmp
 635exit 1
 636EOF
 637) >filfre.sh
 638chmod +x filfre.sh
 639
 640test_expect_success 'custom merge driver with checkout -m' '
 641        git reset --hard &&
 642
 643        git config merge.filfre.driver "./filfre.sh %O %A %B" &&
 644        git config merge.filfre.name "Feel-free merge driver" &&
 645        git config merge.filfre.recursive binary &&
 646        echo "arm merge=filfre" >.gitattributes &&
 647
 648        git checkout -b left &&
 649        echo neutral >arm &&
 650        git add arm .gitattributes &&
 651        test_tick &&
 652        git commit -m neutral &&
 653        git branch right &&
 654
 655        echo left >arm &&
 656        test_tick &&
 657        git commit -a -m left &&
 658        git checkout right &&
 659
 660        echo right >arm &&
 661        test_tick &&
 662        git commit -a -m right &&
 663
 664        test_must_fail git merge left &&
 665        (
 666                for t in filfre-common left right
 667                do
 668                        grep $t arm || exit 1
 669                done
 670        ) &&
 671
 672        mv arm expect &&
 673        git checkout -m arm &&
 674        test_cmp expect arm
 675'
 676
 677test_done