t / t2018-checkout-branch.shon commit Merge branch 'jc/combine-diff-callback' (e78f829)
   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 an existing branch resets branch to HEAD' '
 122        git checkout branch1 &&
 123
 124        do_checkout branch2 "" -B
 125'
 126
 127test_expect_success 'checkout -B to an existing branch from detached HEAD resets branch to HEAD' '
 128        git checkout $(git rev-parse --verify HEAD) &&
 129
 130        do_checkout branch2 "" -B
 131'
 132
 133test_expect_success 'checkout -B to an existing branch with an explicit ref resets branch to that ref' '
 134        git checkout branch1 &&
 135
 136        do_checkout branch2 $HEAD1 -B
 137'
 138
 139test_expect_success 'checkout -B to an existing branch with unmergeable changes fails' '
 140        git checkout branch1 &&
 141
 142        setup_dirty_unmergeable &&
 143        test_must_fail do_checkout branch2 $HEAD1 -B &&
 144        test_dirty_unmergeable
 145'
 146
 147test_expect_success 'checkout -f -B to an existing branch with unmergeable changes discards changes' '
 148        # still dirty and on branch1
 149        do_checkout branch2 $HEAD1 "-f -B" &&
 150        test_must_fail test_dirty_unmergeable
 151'
 152
 153test_expect_success 'checkout -B to an existing branch preserves mergeable changes' '
 154        git checkout branch1 &&
 155
 156        setup_dirty_mergeable &&
 157        do_checkout branch2 $HEAD1 -B &&
 158        test_dirty_mergeable
 159'
 160
 161test_expect_success 'checkout -f -B to an existing branch with mergeable changes discards changes' '
 162        # clean up from previous test
 163        git reset --hard &&
 164
 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_done