t / t2024-checkout-dwim.shon commit t4208: abstract away SHA-1-specific constants (0b2c4af)
   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
  26test_expect_success 'setup' '
  27        test_commit my_master &&
  28        git init repo_a &&
  29        (
  30                cd repo_a &&
  31                test_commit a_master &&
  32                git checkout -b foo &&
  33                test_commit a_foo &&
  34                git checkout -b bar &&
  35                test_commit a_bar
  36        ) &&
  37        git init repo_b &&
  38        (
  39                cd repo_b &&
  40                test_commit b_master &&
  41                git checkout -b foo &&
  42                test_commit b_foo &&
  43                git checkout -b baz &&
  44                test_commit b_baz
  45        ) &&
  46        git remote add repo_a repo_a &&
  47        git remote add repo_b repo_b &&
  48        git config remote.repo_b.fetch \
  49                "+refs/heads/*:refs/remotes/other_b/*" &&
  50        git fetch --all
  51'
  52
  53test_expect_success 'checkout of non-existing branch fails' '
  54        git checkout -B master &&
  55        test_might_fail git branch -D xyzzy &&
  56
  57        test_must_fail git checkout xyzzy &&
  58        test_must_fail git rev-parse --verify refs/heads/xyzzy &&
  59        test_branch master
  60'
  61
  62test_expect_success 'checkout of branch from multiple remotes fails #1' '
  63        git checkout -B master &&
  64        test_might_fail git branch -D foo &&
  65
  66        test_must_fail git checkout foo &&
  67        test_must_fail git rev-parse --verify refs/heads/foo &&
  68        test_branch master
  69'
  70
  71test_expect_success 'checkout of branch from a single remote succeeds #1' '
  72        git checkout -B master &&
  73        test_might_fail git branch -D bar &&
  74
  75        git checkout bar &&
  76        test_branch bar &&
  77        test_cmp_rev remotes/repo_a/bar HEAD &&
  78        test_branch_upstream bar repo_a bar
  79'
  80
  81test_expect_success 'checkout of branch from a single remote succeeds #2' '
  82        git checkout -B master &&
  83        test_might_fail git branch -D baz &&
  84
  85        git checkout baz &&
  86        test_branch baz &&
  87        test_cmp_rev remotes/other_b/baz HEAD &&
  88        test_branch_upstream baz repo_b baz
  89'
  90
  91test_expect_success '--no-guess suppresses branch auto-vivification' '
  92        git checkout -B master &&
  93        test_might_fail git branch -D bar &&
  94
  95        test_must_fail git checkout --no-guess bar &&
  96        test_must_fail git rev-parse --verify refs/heads/bar &&
  97        test_branch master
  98'
  99
 100test_expect_success 'setup more remotes with unconventional refspecs' '
 101        git checkout -B master &&
 102        git init repo_c &&
 103        (
 104                cd repo_c &&
 105                test_commit c_master &&
 106                git checkout -b bar &&
 107                test_commit c_bar &&
 108                git checkout -b spam &&
 109                test_commit c_spam
 110        ) &&
 111        git init repo_d &&
 112        (
 113                cd repo_d &&
 114                test_commit d_master &&
 115                git checkout -b baz &&
 116                test_commit d_baz &&
 117                git checkout -b eggs &&
 118                test_commit d_eggs
 119        ) &&
 120        git remote add repo_c repo_c &&
 121        git config remote.repo_c.fetch \
 122                "+refs/heads/*:refs/remotes/extra_dir/repo_c/extra_dir/*" &&
 123        git remote add repo_d repo_d &&
 124        git config remote.repo_d.fetch \
 125                "+refs/heads/*:refs/repo_d/*" &&
 126        git fetch --all
 127'
 128
 129test_expect_success 'checkout of branch from multiple remotes fails #2' '
 130        git checkout -B master &&
 131        test_might_fail git branch -D bar &&
 132
 133        test_must_fail git checkout bar &&
 134        test_must_fail git rev-parse --verify refs/heads/bar &&
 135        test_branch master
 136'
 137
 138test_expect_success 'checkout of branch from multiple remotes fails #3' '
 139        git checkout -B master &&
 140        test_might_fail git branch -D baz &&
 141
 142        test_must_fail git checkout baz &&
 143        test_must_fail git rev-parse --verify refs/heads/baz &&
 144        test_branch master
 145'
 146
 147test_expect_success 'checkout of branch from a single remote succeeds #3' '
 148        git checkout -B master &&
 149        test_might_fail git branch -D spam &&
 150
 151        git checkout spam &&
 152        test_branch spam &&
 153        test_cmp_rev refs/remotes/extra_dir/repo_c/extra_dir/spam HEAD &&
 154        test_branch_upstream spam repo_c spam
 155'
 156
 157test_expect_success 'checkout of branch from a single remote succeeds #4' '
 158        git checkout -B master &&
 159        test_might_fail git branch -D eggs &&
 160
 161        git checkout eggs &&
 162        test_branch eggs &&
 163        test_cmp_rev refs/repo_d/eggs HEAD &&
 164        test_branch_upstream eggs repo_d eggs
 165'
 166
 167test_expect_success 'checkout of branch with a file having the same name fails' '
 168        git checkout -B master &&
 169        test_might_fail git branch -D spam &&
 170
 171        >spam &&
 172        test_must_fail git checkout spam &&
 173        test_must_fail git rev-parse --verify refs/heads/spam &&
 174        test_branch master
 175'
 176
 177test_expect_success 'checkout of branch with a file in subdir having the same name fails' '
 178        git checkout -B master &&
 179        test_might_fail git branch -D spam &&
 180
 181        >spam &&
 182        mkdir sub &&
 183        mv spam sub/spam &&
 184        test_must_fail git -C sub checkout spam &&
 185        test_must_fail git rev-parse --verify refs/heads/spam &&
 186        test_branch master
 187'
 188
 189test_expect_success 'checkout <branch> -- succeeds, even if a file with the same name exists' '
 190        git checkout -B master &&
 191        test_might_fail git branch -D spam &&
 192
 193        >spam &&
 194        git checkout spam -- &&
 195        test_branch spam &&
 196        test_cmp_rev refs/remotes/extra_dir/repo_c/extra_dir/spam HEAD &&
 197        test_branch_upstream spam repo_c spam
 198'
 199
 200test_expect_success 'loosely defined local base branch is reported correctly' '
 201
 202        git checkout master &&
 203        git branch strict &&
 204        git branch loose &&
 205        git commit --allow-empty -m "a bit more" &&
 206
 207        test_config branch.strict.remote . &&
 208        test_config branch.loose.remote . &&
 209        test_config branch.strict.merge refs/heads/master &&
 210        test_config branch.loose.merge master &&
 211
 212        git checkout strict | sed -e "s/strict/BRANCHNAME/g" >expect &&
 213        git checkout loose | sed -e "s/loose/BRANCHNAME/g" >actual &&
 214
 215        test_cmp expect actual
 216'
 217
 218test_done