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