t / t2020-checkout-detach.shon commit Merge branch 'master' of git://git.kernel.org/pub/scm/git/git (b50e1c0)
   1#!/bin/sh
   2
   3test_description='checkout into detached HEAD state'
   4. ./test-lib.sh
   5
   6check_detached () {
   7        test_must_fail git symbolic-ref -q HEAD >/dev/null
   8}
   9
  10check_not_detached () {
  11        git symbolic-ref -q HEAD >/dev/null
  12}
  13
  14PREV_HEAD_DESC='Previous HEAD position was'
  15check_orphan_warning() {
  16        test_i18ngrep "you are leaving $2 behind" "$1" &&
  17        test_i18ngrep ! "$PREV_HEAD_DESC" "$1"
  18}
  19check_no_orphan_warning() {
  20        test_i18ngrep ! "you are leaving .* commit.*behind" "$1" &&
  21        test_i18ngrep "$PREV_HEAD_DESC" "$1"
  22}
  23
  24reset () {
  25        git checkout master &&
  26        check_not_detached
  27}
  28
  29test_expect_success 'setup' '
  30        test_commit one &&
  31        test_commit two &&
  32        test_commit three && git tag -d three &&
  33        test_commit four && git tag -d four &&
  34        git branch branch &&
  35        git tag tag
  36'
  37
  38test_expect_success 'checkout branch does not detach' '
  39        reset &&
  40        git checkout branch &&
  41        check_not_detached
  42'
  43
  44test_expect_success 'checkout tag detaches' '
  45        reset &&
  46        git checkout tag &&
  47        check_detached
  48'
  49
  50test_expect_success 'checkout branch by full name detaches' '
  51        reset &&
  52        git checkout refs/heads/branch &&
  53        check_detached
  54'
  55
  56test_expect_success 'checkout non-ref detaches' '
  57        reset &&
  58        git checkout branch^ &&
  59        check_detached
  60'
  61
  62test_expect_success 'checkout ref^0 detaches' '
  63        reset &&
  64        git checkout branch^0 &&
  65        check_detached
  66'
  67
  68test_expect_success 'checkout --detach detaches' '
  69        reset &&
  70        git checkout --detach branch &&
  71        check_detached
  72'
  73
  74test_expect_success 'checkout --detach without branch name' '
  75        reset &&
  76        git checkout --detach &&
  77        check_detached
  78'
  79
  80test_expect_success 'checkout --detach errors out for non-commit' '
  81        reset &&
  82        test_must_fail git checkout --detach one^{tree} &&
  83        check_not_detached
  84'
  85
  86test_expect_success 'checkout --detach errors out for extra argument' '
  87        reset &&
  88        git checkout master &&
  89        test_must_fail git checkout --detach tag one.t &&
  90        check_not_detached
  91'
  92
  93test_expect_success 'checkout --detached and -b are incompatible' '
  94        reset &&
  95        test_must_fail git checkout --detach -b newbranch tag &&
  96        check_not_detached
  97'
  98
  99test_expect_success 'checkout --detach moves HEAD' '
 100        reset &&
 101        git checkout one &&
 102        git checkout --detach two &&
 103        git diff --exit-code HEAD &&
 104        git diff --exit-code two
 105'
 106
 107test_expect_success 'checkout warns on orphan commits' '
 108        reset &&
 109        git checkout --detach two &&
 110        echo content >orphan &&
 111        git add orphan &&
 112        git commit -a -m orphan1 &&
 113        echo new content >orphan &&
 114        git commit -a -m orphan2 &&
 115        orphan2=$(git rev-parse HEAD) &&
 116        git checkout master 2>stderr
 117'
 118
 119test_expect_success 'checkout warns on orphan commits: output' '
 120        check_orphan_warning stderr "2 commits"
 121'
 122
 123test_expect_success 'checkout warns orphaning 1 of 2 commits' '
 124        git checkout "$orphan2" &&
 125        git checkout HEAD^ 2>stderr
 126'
 127
 128test_expect_success 'checkout warns orphaning 1 of 2 commits: output' '
 129        check_orphan_warning stderr "1 commit"
 130'
 131
 132test_expect_success 'checkout does not warn leaving ref tip' '
 133        reset &&
 134        git checkout --detach two &&
 135        git checkout master 2>stderr
 136'
 137
 138test_expect_success 'checkout does not warn leaving ref tip' '
 139        check_no_orphan_warning stderr
 140'
 141
 142test_expect_success 'checkout does not warn leaving reachable commit' '
 143        reset &&
 144        git checkout --detach HEAD^ &&
 145        git checkout master 2>stderr
 146'
 147
 148test_expect_success 'checkout does not warn leaving reachable commit' '
 149        check_no_orphan_warning stderr
 150'
 151
 152cat >expect <<'EOF'
 153Your branch is behind 'master' by 1 commit, and can be fast-forwarded.
 154  (use "git pull" to update your local branch)
 155EOF
 156test_expect_success 'tracking count is accurate after orphan check' '
 157        reset &&
 158        git branch child master^ &&
 159        git config branch.child.remote . &&
 160        git config branch.child.merge refs/heads/master &&
 161        git checkout child^ &&
 162        git checkout child >stdout &&
 163        test_i18ncmp expect stdout
 164'
 165
 166test_expect_success 'no advice given for explicit detached head state' '
 167        # baseline
 168        test_config advice.detachedHead true &&
 169        git checkout child && git checkout HEAD^0 >expect.advice 2>&1 &&
 170        test_config advice.detachedHead false &&
 171        git checkout child && git checkout HEAD^0 >expect.no-advice 2>&1 &&
 172        test_unconfig advice.detachedHead &&
 173        # without configuration, the advice.* variables default to true
 174        git checkout child && git checkout HEAD^0 >actual 2>&1 &&
 175        test_cmp expect.advice actual &&
 176
 177        # with explicit --detach
 178        # no configuration
 179        test_unconfig advice.detachedHead &&
 180        git checkout child && git checkout --detach HEAD^0 >actual 2>&1 &&
 181        test_cmp expect.no-advice actual &&
 182
 183        # explicitly decline advice
 184        test_config advice.detachedHead false &&
 185        git checkout child && git checkout --detach HEAD^0 >actual 2>&1 &&
 186        test_cmp expect.no-advice actual
 187'
 188
 189# Detached HEAD tests for GIT_PRINT_SHA1_ELLIPSIS (new format)
 190test_expect_success 'describe_detached_head prints no SHA-1 ellipsis when not asked to' "
 191
 192        commit=$(git rev-parse --short=12 master^) &&
 193        commit2=$(git rev-parse --short=12 master~2) &&
 194        commit3=$(git rev-parse --short=12 master~3) &&
 195
 196        # The first detach operation is more chatty than the following ones.
 197        cat >1st_detach <<-EOF &&
 198        Note: checking out 'HEAD^'.
 199
 200        You are in 'detached HEAD' state. You can look around, make experimental
 201        changes and commit them, and you can discard any commits you make in this
 202        state without impacting any branches by performing another checkout.
 203
 204        If you want to create a new branch to retain commits you create, you may
 205        do so (now or later) by using -b with the checkout command again. Example:
 206
 207          git checkout -b <new-branch-name>
 208
 209        HEAD is now at \$commit three
 210        EOF
 211
 212        # The remaining ones just show info about previous and current HEADs.
 213        cat >2nd_detach <<-EOF &&
 214        Previous HEAD position was \$commit three
 215        HEAD is now at \$commit2 two
 216        EOF
 217
 218        cat >3rd_detach <<-EOF &&
 219        Previous HEAD position was \$commit2 two
 220        HEAD is now at \$commit3 one
 221        EOF
 222
 223        reset &&
 224        check_not_detached &&
 225
 226        # Various ways of *not* asking for ellipses
 227
 228        sane_unset GIT_PRINT_SHA1_ELLIPSIS &&
 229        git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 230        check_detached &&
 231        test_i18ncmp 1st_detach actual &&
 232
 233        GIT_PRINT_SHA1_ELLIPSIS="no" git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 234        check_detached &&
 235        test_i18ncmp 2nd_detach actual &&
 236
 237        GIT_PRINT_SHA1_ELLIPSIS= git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 238        check_detached &&
 239        test_i18ncmp 3rd_detach actual &&
 240
 241        sane_unset GIT_PRINT_SHA1_ELLIPSIS &&
 242
 243        # We only have four commits, but we can re-use them
 244        reset &&
 245        check_not_detached &&
 246
 247        # Make no mention of the env var at all
 248        git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 249        check_detached &&
 250        test_i18ncmp 1st_detach actual &&
 251
 252        GIT_PRINT_SHA1_ELLIPSIS='nope' &&
 253        git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 254        check_detached &&
 255        test_i18ncmp 2nd_detach actual &&
 256
 257        GIT_PRINT_SHA1_ELLIPSIS=nein &&
 258        git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 259        check_detached &&
 260        test_i18ncmp 3rd_detach actual &&
 261
 262        true
 263"
 264
 265# Detached HEAD tests for GIT_PRINT_SHA1_ELLIPSIS (old format)
 266test_expect_success 'describe_detached_head does print SHA-1 ellipsis when asked to' "
 267
 268        commit=$(git rev-parse --short=12 master^) &&
 269        commit2=$(git rev-parse --short=12 master~2) &&
 270        commit3=$(git rev-parse --short=12 master~3) &&
 271
 272        # The first detach operation is more chatty than the following ones.
 273        cat >1st_detach <<-EOF &&
 274        Note: checking out 'HEAD^'.
 275
 276        You are in 'detached HEAD' state. You can look around, make experimental
 277        changes and commit them, and you can discard any commits you make in this
 278        state without impacting any branches by performing another checkout.
 279
 280        If you want to create a new branch to retain commits you create, you may
 281        do so (now or later) by using -b with the checkout command again. Example:
 282
 283          git checkout -b <new-branch-name>
 284
 285        HEAD is now at \$commit... three
 286        EOF
 287
 288        # The remaining ones just show info about previous and current HEADs.
 289        cat >2nd_detach <<-EOF &&
 290        Previous HEAD position was \$commit... three
 291        HEAD is now at \$commit2... two
 292        EOF
 293
 294        cat >3rd_detach <<-EOF &&
 295        Previous HEAD position was \$commit2... two
 296        HEAD is now at \$commit3... one
 297        EOF
 298
 299        reset &&
 300        check_not_detached &&
 301
 302        # Various ways of asking for ellipses...
 303        # The user can just use any kind of quoting (including none).
 304
 305        GIT_PRINT_SHA1_ELLIPSIS=yes git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 306        check_detached &&
 307        test_i18ncmp 1st_detach actual &&
 308
 309        GIT_PRINT_SHA1_ELLIPSIS=Yes git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 310        check_detached &&
 311        test_i18ncmp 2nd_detach actual &&
 312
 313        GIT_PRINT_SHA1_ELLIPSIS=YES git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 314        check_detached &&
 315        test_i18ncmp 3rd_detach actual &&
 316
 317        true
 318"
 319
 320test_done