082147a875c2999210fd1870b12167c6f6fda909
   1#!/bin/sh
   2
   3test_description='checkout <branch>
   4
   5Ensures that checkout on an unborn branch does what the user expects'
   6
   7. ./test-lib.sh
   8
   9# Is the current branch "refs/heads/$1"?
  10test_branch () {
  11        printf "%s\n" "refs/heads/$1" >expect.HEAD &&
  12        git symbolic-ref HEAD >actual.HEAD &&
  13        test_cmp expect.HEAD actual.HEAD
  14}
  15
  16# Is branch "refs/heads/$1" set to pull from "$2/$3"?
  17test_branch_upstream () {
  18        printf "%s\n" "$2" "refs/heads/$3" >expect.upstream &&
  19        {
  20                git config "branch.$1.remote" &&
  21                git config "branch.$1.merge"
  22        } >actual.upstream &&
  23        test_cmp expect.upstream actual.upstream
  24}
  25
  26status_uno_is_clean () {
  27        >status.expect &&
  28        git status -uno --porcelain >status.actual &&
  29        test_cmp status.expect status.actual
  30}
  31
  32test_expect_success 'setup' '
  33        test_commit my_master &&
  34        git init repo_a &&
  35        (
  36                cd repo_a &&
  37                test_commit a_master &&
  38                git checkout -b foo &&
  39                test_commit a_foo &&
  40                git checkout -b bar &&
  41                test_commit a_bar
  42        ) &&
  43        git init repo_b &&
  44        (
  45                cd repo_b &&
  46                test_commit b_master &&
  47                git checkout -b foo &&
  48                test_commit b_foo &&
  49                git checkout -b baz &&
  50                test_commit b_baz
  51        ) &&
  52        git remote add repo_a repo_a &&
  53        git remote add repo_b repo_b &&
  54        git config remote.repo_b.fetch \
  55                "+refs/heads/*:refs/remotes/other_b/*" &&
  56        git fetch --all
  57'
  58
  59test_expect_success 'checkout of non-existing branch fails' '
  60        git checkout -B master &&
  61        test_might_fail git branch -D xyzzy &&
  62
  63        test_must_fail git checkout xyzzy &&
  64        status_uno_is_clean &&
  65        test_must_fail git rev-parse --verify refs/heads/xyzzy &&
  66        test_branch master
  67'
  68
  69test_expect_success 'checkout of branch from multiple remotes fails #1' '
  70        git checkout -B master &&
  71        test_might_fail git branch -D foo &&
  72
  73        test_must_fail git checkout foo &&
  74        status_uno_is_clean &&
  75        test_must_fail git rev-parse --verify refs/heads/foo &&
  76        test_branch master
  77'
  78
  79test_expect_success 'checkout of branch from multiple remotes fails with advice' '
  80        git checkout -B master &&
  81        test_might_fail git branch -D foo &&
  82        test_must_fail git checkout foo 2>stderr &&
  83        test_branch master &&
  84        status_uno_is_clean &&
  85        test_i18ngrep "^hint: " stderr &&
  86        test_must_fail git -c advice.checkoutAmbiguousRemoteBranchName=false \
  87                checkout foo 2>stderr &&
  88        test_branch master &&
  89        status_uno_is_clean &&
  90        test_i18ngrep ! "^hint: " stderr
  91'
  92
  93test_expect_success 'checkout of branch from a single remote succeeds #1' '
  94        git checkout -B master &&
  95        test_might_fail git branch -D bar &&
  96
  97        git checkout bar &&
  98        status_uno_is_clean &&
  99        test_branch bar &&
 100        test_cmp_rev remotes/repo_a/bar HEAD &&
 101        test_branch_upstream bar repo_a bar
 102'
 103
 104test_expect_success 'checkout of branch from a single remote succeeds #2' '
 105        git checkout -B master &&
 106        test_might_fail git branch -D baz &&
 107
 108        git checkout baz &&
 109        status_uno_is_clean &&
 110        test_branch baz &&
 111        test_cmp_rev remotes/other_b/baz HEAD &&
 112        test_branch_upstream baz repo_b baz
 113'
 114
 115test_expect_success '--no-guess suppresses branch auto-vivification' '
 116        git checkout -B master &&
 117        status_uno_is_clean &&
 118        test_might_fail git branch -D bar &&
 119
 120        test_must_fail git checkout --no-guess bar &&
 121        test_must_fail git rev-parse --verify refs/heads/bar &&
 122        test_branch master
 123'
 124
 125test_expect_success 'setup more remotes with unconventional refspecs' '
 126        git checkout -B master &&
 127        status_uno_is_clean &&
 128        git init repo_c &&
 129        (
 130                cd repo_c &&
 131                test_commit c_master &&
 132                git checkout -b bar &&
 133                test_commit c_bar &&
 134                git checkout -b spam &&
 135                test_commit c_spam
 136        ) &&
 137        git init repo_d &&
 138        (
 139                cd repo_d &&
 140                test_commit d_master &&
 141                git checkout -b baz &&
 142                test_commit d_baz &&
 143                git checkout -b eggs &&
 144                test_commit d_eggs
 145        ) &&
 146        git remote add repo_c repo_c &&
 147        git config remote.repo_c.fetch \
 148                "+refs/heads/*:refs/remotes/extra_dir/repo_c/extra_dir/*" &&
 149        git remote add repo_d repo_d &&
 150        git config remote.repo_d.fetch \
 151                "+refs/heads/*:refs/repo_d/*" &&
 152        git fetch --all
 153'
 154
 155test_expect_success 'checkout of branch from multiple remotes fails #2' '
 156        git checkout -B master &&
 157        status_uno_is_clean &&
 158        test_might_fail git branch -D bar &&
 159
 160        test_must_fail git checkout bar &&
 161        status_uno_is_clean &&
 162        test_must_fail git rev-parse --verify refs/heads/bar &&
 163        test_branch master
 164'
 165
 166test_expect_success 'checkout of branch from multiple remotes fails #3' '
 167        git checkout -B master &&
 168        status_uno_is_clean &&
 169        test_might_fail git branch -D baz &&
 170
 171        test_must_fail git checkout baz &&
 172        status_uno_is_clean &&
 173        test_must_fail git rev-parse --verify refs/heads/baz &&
 174        test_branch master
 175'
 176
 177test_expect_success 'checkout of branch from a single remote succeeds #3' '
 178        git checkout -B master &&
 179        status_uno_is_clean &&
 180        test_might_fail git branch -D spam &&
 181
 182        git checkout spam &&
 183        status_uno_is_clean &&
 184        test_branch spam &&
 185        test_cmp_rev refs/remotes/extra_dir/repo_c/extra_dir/spam HEAD &&
 186        test_branch_upstream spam repo_c spam
 187'
 188
 189test_expect_success 'checkout of branch from a single remote succeeds #4' '
 190        git checkout -B master &&
 191        status_uno_is_clean &&
 192        test_might_fail git branch -D eggs &&
 193
 194        git checkout eggs &&
 195        status_uno_is_clean &&
 196        test_branch eggs &&
 197        test_cmp_rev refs/repo_d/eggs HEAD &&
 198        test_branch_upstream eggs repo_d eggs
 199'
 200
 201test_expect_success 'checkout of branch with a file having the same name fails' '
 202        git checkout -B master &&
 203        status_uno_is_clean &&
 204        test_might_fail git branch -D spam &&
 205
 206        >spam &&
 207        test_must_fail git checkout spam &&
 208        status_uno_is_clean &&
 209        test_must_fail git rev-parse --verify refs/heads/spam &&
 210        test_branch master
 211'
 212
 213test_expect_success 'checkout of branch with a file in subdir having the same name fails' '
 214        git checkout -B master &&
 215        status_uno_is_clean &&
 216        test_might_fail git branch -D spam &&
 217
 218        >spam &&
 219        mkdir sub &&
 220        mv spam sub/spam &&
 221        test_must_fail git -C sub checkout spam &&
 222        status_uno_is_clean &&
 223        test_must_fail git rev-parse --verify refs/heads/spam &&
 224        test_branch master
 225'
 226
 227test_expect_success 'checkout <branch> -- succeeds, even if a file with the same name exists' '
 228        git checkout -B master &&
 229        status_uno_is_clean &&
 230        test_might_fail git branch -D spam &&
 231
 232        >spam &&
 233        git checkout spam -- &&
 234        status_uno_is_clean &&
 235        test_branch spam &&
 236        test_cmp_rev refs/remotes/extra_dir/repo_c/extra_dir/spam HEAD &&
 237        test_branch_upstream spam repo_c spam
 238'
 239
 240test_expect_success 'loosely defined local base branch is reported correctly' '
 241
 242        git checkout master &&
 243        status_uno_is_clean &&
 244        git branch strict &&
 245        git branch loose &&
 246        git commit --allow-empty -m "a bit more" &&
 247
 248        test_config branch.strict.remote . &&
 249        test_config branch.loose.remote . &&
 250        test_config branch.strict.merge refs/heads/master &&
 251        test_config branch.loose.merge master &&
 252
 253        git checkout strict | sed -e "s/strict/BRANCHNAME/g" >expect &&
 254        status_uno_is_clean &&
 255        git checkout loose | sed -e "s/loose/BRANCHNAME/g" >actual &&
 256        status_uno_is_clean &&
 257
 258        test_cmp expect actual
 259'
 260
 261test_done