t / t2018-checkout-branch.shon commit setup_traverse_info(): stop copying oid (947208b)
   1#!/bin/sh
   2
   3test_description='checkout '
   4
   5. ./test-lib.sh
   6
   7# Arguments: <branch> <sha> [<checkout options>]
   8#
   9# Runs "git checkout" to switch to <branch>, testing that
  10#
  11#   1) we are on the specified branch, <branch>;
  12#   2) HEAD is <sha>; if <sha> is not specified, the old HEAD is used.
  13#
  14# If <checkout options> is not specified, "git checkout" is run with -b.
  15do_checkout() {
  16        exp_branch=$1 &&
  17        exp_ref="refs/heads/$exp_branch" &&
  18
  19        # if <sha> is not specified, use HEAD.
  20        exp_sha=${2:-$(git rev-parse --verify HEAD)} &&
  21
  22        # default options for git checkout: -b
  23        if [ -z "$3" ]; then
  24                opts="-b"
  25        else
  26                opts="$3"
  27        fi
  28
  29        git checkout $opts $exp_branch $exp_sha &&
  30
  31        test $exp_ref = $(git rev-parse --symbolic-full-name HEAD) &&
  32        test $exp_sha = $(git rev-parse --verify HEAD)
  33}
  34
  35test_dirty_unmergeable() {
  36        ! git diff --exit-code >/dev/null
  37}
  38
  39setup_dirty_unmergeable() {
  40        echo >>file1 change2
  41}
  42
  43test_dirty_mergeable() {
  44        ! git diff --cached --exit-code >/dev/null
  45}
  46
  47setup_dirty_mergeable() {
  48        echo >file2 file2 &&
  49        git add file2
  50}
  51
  52test_expect_success 'setup' '
  53        test_commit initial file1 &&
  54        HEAD1=$(git rev-parse --verify HEAD) &&
  55
  56        test_commit change1 file1 &&
  57        HEAD2=$(git rev-parse --verify HEAD) &&
  58
  59        git branch -m branch1
  60'
  61
  62test_expect_success 'checkout -b to a new branch, set to HEAD' '
  63        test_when_finished "
  64                git checkout branch1 &&
  65                test_might_fail git branch -D branch2" &&
  66        do_checkout branch2
  67'
  68
  69test_expect_success 'checkout -b to a merge base' '
  70        test_when_finished "
  71                git checkout branch1 &&
  72                test_might_fail git branch -D branch2" &&
  73        git checkout -b branch2 branch1...
  74'
  75
  76test_expect_success 'checkout -b to a new branch, set to an explicit ref' '
  77        test_when_finished "
  78                git checkout branch1 &&
  79                test_might_fail git branch -D branch2" &&
  80        do_checkout branch2 $HEAD1
  81'
  82
  83test_expect_success 'checkout -b to a new branch with unmergeable changes fails' '
  84        setup_dirty_unmergeable &&
  85        test_must_fail do_checkout branch2 $HEAD1 &&
  86        test_dirty_unmergeable
  87'
  88
  89test_expect_success 'checkout -f -b to a new branch with unmergeable changes discards changes' '
  90        test_when_finished "
  91                git checkout branch1 &&
  92                test_might_fail git branch -D branch2" &&
  93
  94        # still dirty and on branch1
  95        do_checkout branch2 $HEAD1 "-f -b" &&
  96        test_must_fail test_dirty_unmergeable
  97'
  98
  99test_expect_success 'checkout -b to a new branch preserves mergeable changes' '
 100        test_when_finished "
 101                git reset --hard &&
 102                git checkout branch1 &&
 103                test_might_fail git branch -D branch2" &&
 104
 105        setup_dirty_mergeable &&
 106        do_checkout branch2 $HEAD1 &&
 107        test_dirty_mergeable
 108'
 109
 110test_expect_success 'checkout -f -b to a new branch with mergeable changes discards changes' '
 111        test_when_finished git reset --hard HEAD &&
 112        setup_dirty_mergeable &&
 113        do_checkout branch2 $HEAD1 "-f -b" &&
 114        test_must_fail test_dirty_mergeable
 115'
 116
 117test_expect_success 'checkout -b to an existing branch fails' '
 118        test_when_finished git reset --hard HEAD &&
 119        test_must_fail do_checkout branch2 $HEAD2
 120'
 121
 122test_expect_success 'checkout -b to @{-1} fails with the right branch name' '
 123        git checkout branch1 &&
 124        git checkout branch2 &&
 125        echo  >expect "fatal: A branch named '\''branch1'\'' already exists." &&
 126        test_must_fail git checkout -b @{-1} 2>actual &&
 127        test_i18ncmp expect actual
 128'
 129
 130test_expect_success 'checkout -B to an existing branch resets branch to HEAD' '
 131        git checkout branch1 &&
 132
 133        do_checkout branch2 "" -B
 134'
 135
 136test_expect_success 'checkout -B to a merge base' '
 137        git checkout branch1 &&
 138
 139        git checkout -B branch2 branch1...
 140'
 141
 142test_expect_success 'checkout -B to an existing branch from detached HEAD resets branch to HEAD' '
 143        git checkout $(git rev-parse --verify HEAD) &&
 144
 145        do_checkout branch2 "" -B
 146'
 147
 148test_expect_success 'checkout -B to an existing branch with an explicit ref resets branch to that ref' '
 149        git checkout branch1 &&
 150
 151        do_checkout branch2 $HEAD1 -B
 152'
 153
 154test_expect_success 'checkout -B to an existing branch with unmergeable changes fails' '
 155        git checkout branch1 &&
 156
 157        setup_dirty_unmergeable &&
 158        test_must_fail do_checkout branch2 $HEAD1 -B &&
 159        test_dirty_unmergeable
 160'
 161
 162test_expect_success 'checkout -f -B to an existing branch with unmergeable changes discards changes' '
 163        # still dirty and on branch1
 164        do_checkout branch2 $HEAD1 "-f -B" &&
 165        test_must_fail test_dirty_unmergeable
 166'
 167
 168test_expect_success 'checkout -B to an existing branch preserves mergeable changes' '
 169        test_when_finished git reset --hard &&
 170        git checkout branch1 &&
 171
 172        setup_dirty_mergeable &&
 173        do_checkout branch2 $HEAD1 -B &&
 174        test_dirty_mergeable
 175'
 176
 177test_expect_success 'checkout -f -B to an existing branch with mergeable changes discards changes' '
 178        git checkout branch1 &&
 179
 180        setup_dirty_mergeable &&
 181        do_checkout branch2 $HEAD1 "-f -B" &&
 182        test_must_fail test_dirty_mergeable
 183'
 184
 185test_expect_success 'checkout -b <describe>' '
 186        git tag -f -m "First commit" initial initial &&
 187        git checkout -f change1 &&
 188        name=$(git describe) &&
 189        git checkout -b $name &&
 190        git diff --exit-code change1 &&
 191        echo "refs/heads/$name" >expect &&
 192        git symbolic-ref HEAD >actual &&
 193        test_cmp expect actual
 194'
 195
 196test_expect_success 'checkout -B to the current branch works' '
 197        git checkout branch1 &&
 198        git checkout -B branch1-scratch &&
 199
 200        setup_dirty_mergeable &&
 201        git checkout -B branch1-scratch initial &&
 202        test_dirty_mergeable
 203'
 204
 205test_expect_success 'checkout -b after clone --no-checkout does a checkout of HEAD' '
 206        git init src &&
 207        test_commit -C src a &&
 208        rev="$(git -C src rev-parse HEAD)" &&
 209        git clone --no-checkout src dest &&
 210        git -C dest checkout "$rev" -b branch &&
 211        test_path_is_file dest/a.t
 212'
 213
 214test_done