t / t2024-checkout-dwim.shon commit checkout.h: wrap the arguments to unique_tracking_name() (17b44ae)
   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 a single remote succeeds #1' '
  80        git checkout -B master &&
  81        test_might_fail git branch -D bar &&
  82
  83        git checkout bar &&
  84        status_uno_is_clean &&
  85        test_branch bar &&
  86        test_cmp_rev remotes/repo_a/bar HEAD &&
  87        test_branch_upstream bar repo_a bar
  88'
  89
  90test_expect_success 'checkout of branch from a single remote succeeds #2' '
  91        git checkout -B master &&
  92        test_might_fail git branch -D baz &&
  93
  94        git checkout baz &&
  95        status_uno_is_clean &&
  96        test_branch baz &&
  97        test_cmp_rev remotes/other_b/baz HEAD &&
  98        test_branch_upstream baz repo_b baz
  99'
 100
 101test_expect_success '--no-guess suppresses branch auto-vivification' '
 102        git checkout -B master &&
 103        status_uno_is_clean &&
 104        test_might_fail git branch -D bar &&
 105
 106        test_must_fail git checkout --no-guess bar &&
 107        test_must_fail git rev-parse --verify refs/heads/bar &&
 108        test_branch master
 109'
 110
 111test_expect_success 'setup more remotes with unconventional refspecs' '
 112        git checkout -B master &&
 113        status_uno_is_clean &&
 114        git init repo_c &&
 115        (
 116                cd repo_c &&
 117                test_commit c_master &&
 118                git checkout -b bar &&
 119                test_commit c_bar &&
 120                git checkout -b spam &&
 121                test_commit c_spam
 122        ) &&
 123        git init repo_d &&
 124        (
 125                cd repo_d &&
 126                test_commit d_master &&
 127                git checkout -b baz &&
 128                test_commit d_baz &&
 129                git checkout -b eggs &&
 130                test_commit d_eggs
 131        ) &&
 132        git remote add repo_c repo_c &&
 133        git config remote.repo_c.fetch \
 134                "+refs/heads/*:refs/remotes/extra_dir/repo_c/extra_dir/*" &&
 135        git remote add repo_d repo_d &&
 136        git config remote.repo_d.fetch \
 137                "+refs/heads/*:refs/repo_d/*" &&
 138        git fetch --all
 139'
 140
 141test_expect_success 'checkout of branch from multiple remotes fails #2' '
 142        git checkout -B master &&
 143        status_uno_is_clean &&
 144        test_might_fail git branch -D bar &&
 145
 146        test_must_fail git checkout bar &&
 147        status_uno_is_clean &&
 148        test_must_fail git rev-parse --verify refs/heads/bar &&
 149        test_branch master
 150'
 151
 152test_expect_success 'checkout of branch from multiple remotes fails #3' '
 153        git checkout -B master &&
 154        status_uno_is_clean &&
 155        test_might_fail git branch -D baz &&
 156
 157        test_must_fail git checkout baz &&
 158        status_uno_is_clean &&
 159        test_must_fail git rev-parse --verify refs/heads/baz &&
 160        test_branch master
 161'
 162
 163test_expect_success 'checkout of branch from a single remote succeeds #3' '
 164        git checkout -B master &&
 165        status_uno_is_clean &&
 166        test_might_fail git branch -D spam &&
 167
 168        git checkout spam &&
 169        status_uno_is_clean &&
 170        test_branch spam &&
 171        test_cmp_rev refs/remotes/extra_dir/repo_c/extra_dir/spam HEAD &&
 172        test_branch_upstream spam repo_c spam
 173'
 174
 175test_expect_success 'checkout of branch from a single remote succeeds #4' '
 176        git checkout -B master &&
 177        status_uno_is_clean &&
 178        test_might_fail git branch -D eggs &&
 179
 180        git checkout eggs &&
 181        status_uno_is_clean &&
 182        test_branch eggs &&
 183        test_cmp_rev refs/repo_d/eggs HEAD &&
 184        test_branch_upstream eggs repo_d eggs
 185'
 186
 187test_expect_success 'checkout of branch with a file having the same name fails' '
 188        git checkout -B master &&
 189        status_uno_is_clean &&
 190        test_might_fail git branch -D spam &&
 191
 192        >spam &&
 193        test_must_fail git checkout spam &&
 194        status_uno_is_clean &&
 195        test_must_fail git rev-parse --verify refs/heads/spam &&
 196        test_branch master
 197'
 198
 199test_expect_success 'checkout of branch with a file in subdir having the same name fails' '
 200        git checkout -B master &&
 201        status_uno_is_clean &&
 202        test_might_fail git branch -D spam &&
 203
 204        >spam &&
 205        mkdir sub &&
 206        mv spam sub/spam &&
 207        test_must_fail git -C sub 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 <branch> -- succeeds, even if a file with the same name exists' '
 214        git checkout -B master &&
 215        status_uno_is_clean &&
 216        test_might_fail git branch -D spam &&
 217
 218        >spam &&
 219        git checkout spam -- &&
 220        status_uno_is_clean &&
 221        test_branch spam &&
 222        test_cmp_rev refs/remotes/extra_dir/repo_c/extra_dir/spam HEAD &&
 223        test_branch_upstream spam repo_c spam
 224'
 225
 226test_expect_success 'loosely defined local base branch is reported correctly' '
 227
 228        git checkout master &&
 229        status_uno_is_clean &&
 230        git branch strict &&
 231        git branch loose &&
 232        git commit --allow-empty -m "a bit more" &&
 233
 234        test_config branch.strict.remote . &&
 235        test_config branch.loose.remote . &&
 236        test_config branch.strict.merge refs/heads/master &&
 237        test_config branch.loose.merge master &&
 238
 239        git checkout strict | sed -e "s/strict/BRANCHNAME/g" >expect &&
 240        status_uno_is_clean &&
 241        git checkout loose | sed -e "s/loose/BRANCHNAME/g" >actual &&
 242        status_uno_is_clean &&
 243
 244        test_cmp expect actual
 245'
 246
 247test_done