t / t2018-checkout-branch.shon commit t2018: cleanup in current test (27434bf)
   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 new branch, set to an explicit ref' '
  70        test_when_finished "
  71                git checkout branch1 &&
  72                test_might_fail git branch -D branch2" &&
  73        do_checkout branch2 $HEAD1
  74'
  75
  76test_expect_success 'checkout -b to a new branch with unmergeable changes fails' '
  77        setup_dirty_unmergeable &&
  78        test_must_fail do_checkout branch2 $HEAD1 &&
  79        test_dirty_unmergeable
  80'
  81
  82test_expect_success 'checkout -f -b to a new branch with unmergeable changes discards changes' '
  83        test_when_finished "
  84                git checkout branch1 &&
  85                test_might_fail git branch -D branch2" &&
  86
  87        # still dirty and on branch1
  88        do_checkout branch2 $HEAD1 "-f -b" &&
  89        test_must_fail test_dirty_unmergeable
  90'
  91
  92test_expect_success 'checkout -b to a new branch preserves mergeable changes' '
  93        test_when_finished "
  94                git reset --hard &&
  95                git checkout branch1 &&
  96                test_might_fail git branch -D branch2" &&
  97
  98        setup_dirty_mergeable &&
  99        do_checkout branch2 $HEAD1 &&
 100        test_dirty_mergeable
 101'
 102
 103test_expect_success 'checkout -f -b to a new branch with mergeable changes discards changes' '
 104        test_when_finished git reset --hard HEAD &&
 105        setup_dirty_mergeable &&
 106        do_checkout branch2 $HEAD1 "-f -b" &&
 107        test_must_fail test_dirty_mergeable
 108'
 109
 110test_expect_success 'checkout -b to an existing branch fails' '
 111        test_when_finished git reset --hard HEAD &&
 112        test_must_fail do_checkout branch2 $HEAD2
 113'
 114
 115test_expect_success 'checkout -b to @{-1} fails with the right branch name' '
 116        git checkout branch1 &&
 117        git checkout branch2 &&
 118        echo  >expect "fatal: A branch named '\''branch1'\'' already exists." &&
 119        test_must_fail git checkout -b @{-1} 2>actual &&
 120        test_i18ncmp expect actual
 121'
 122
 123test_expect_success 'checkout -B to an existing branch resets branch to HEAD' '
 124        git checkout branch1 &&
 125
 126        do_checkout branch2 "" -B
 127'
 128
 129test_expect_success 'checkout -B to an existing branch from detached HEAD resets branch to HEAD' '
 130        git checkout $(git rev-parse --verify HEAD) &&
 131
 132        do_checkout branch2 "" -B
 133'
 134
 135test_expect_success 'checkout -B to an existing branch with an explicit ref resets branch to that ref' '
 136        git checkout branch1 &&
 137
 138        do_checkout branch2 $HEAD1 -B
 139'
 140
 141test_expect_success 'checkout -B to an existing branch with unmergeable changes fails' '
 142        git checkout branch1 &&
 143
 144        setup_dirty_unmergeable &&
 145        test_must_fail do_checkout branch2 $HEAD1 -B &&
 146        test_dirty_unmergeable
 147'
 148
 149test_expect_success 'checkout -f -B to an existing branch with unmergeable changes discards changes' '
 150        # still dirty and on branch1
 151        do_checkout branch2 $HEAD1 "-f -B" &&
 152        test_must_fail test_dirty_unmergeable
 153'
 154
 155test_expect_success 'checkout -B to an existing branch preserves mergeable changes' '
 156        test_when_finished git reset --hard &&
 157        git checkout branch1 &&
 158
 159        setup_dirty_mergeable &&
 160        do_checkout branch2 $HEAD1 -B &&
 161        test_dirty_mergeable
 162'
 163
 164test_expect_success 'checkout -f -B to an existing branch with mergeable changes discards changes' '
 165        git checkout branch1 &&
 166
 167        setup_dirty_mergeable &&
 168        do_checkout branch2 $HEAD1 "-f -B" &&
 169        test_must_fail test_dirty_mergeable
 170'
 171
 172test_expect_success 'checkout -b <describe>' '
 173        git tag -f -m "First commit" initial initial &&
 174        git checkout -f change1 &&
 175        name=$(git describe) &&
 176        git checkout -b $name &&
 177        git diff --exit-code change1 &&
 178        echo "refs/heads/$name" >expect &&
 179        git symbolic-ref HEAD >actual &&
 180        test_cmp expect actual
 181'
 182
 183test_expect_success 'checkout -B to the current branch works' '
 184        git checkout branch1 &&
 185        git checkout -B branch1-scratch &&
 186
 187        setup_dirty_mergeable &&
 188        git checkout -B branch1-scratch initial &&
 189        test_dirty_mergeable
 190'
 191
 192test_expect_success 'checkout -b after clone --no-checkout does a checkout of HEAD' '
 193        git init src &&
 194        test_commit -C src a &&
 195        rev="$(git -C src rev-parse HEAD)" &&
 196        git clone --no-checkout src dest &&
 197        git -C dest checkout "$rev" -b branch &&
 198        test_path_is_file dest/a.t
 199'
 200
 201test_done