t / t2020-checkout-detach.shon commit Merge branch 'ds/midx-expire-repack' (8ce8a63)
   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: switching to '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 switching back to a branch.
 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 -c with the switch command. Example:
 206
 207          git switch -c <new-branch-name>
 208
 209        Or undo this operation with:
 210
 211          git switch -
 212
 213        Turn off this advice by setting config variable advice.detachedHead to false
 214
 215        HEAD is now at \$commit three
 216        EOF
 217
 218        # The remaining ones just show info about previous and current HEADs.
 219        cat >2nd_detach <<-EOF &&
 220        Previous HEAD position was \$commit three
 221        HEAD is now at \$commit2 two
 222        EOF
 223
 224        cat >3rd_detach <<-EOF &&
 225        Previous HEAD position was \$commit2 two
 226        HEAD is now at \$commit3 one
 227        EOF
 228
 229        reset &&
 230        check_not_detached &&
 231
 232        # Various ways of *not* asking for ellipses
 233
 234        sane_unset GIT_PRINT_SHA1_ELLIPSIS &&
 235        git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 236        check_detached &&
 237        test_i18ncmp 1st_detach actual &&
 238
 239        GIT_PRINT_SHA1_ELLIPSIS="no" git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 240        check_detached &&
 241        test_i18ncmp 2nd_detach actual &&
 242
 243        GIT_PRINT_SHA1_ELLIPSIS= git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 244        check_detached &&
 245        test_i18ncmp 3rd_detach actual &&
 246
 247        sane_unset GIT_PRINT_SHA1_ELLIPSIS &&
 248
 249        # We only have four commits, but we can re-use them
 250        reset &&
 251        check_not_detached &&
 252
 253        # Make no mention of the env var at all
 254        git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 255        check_detached &&
 256        test_i18ncmp 1st_detach actual &&
 257
 258        GIT_PRINT_SHA1_ELLIPSIS='nope' &&
 259        git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 260        check_detached &&
 261        test_i18ncmp 2nd_detach actual &&
 262
 263        GIT_PRINT_SHA1_ELLIPSIS=nein &&
 264        git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 265        check_detached &&
 266        test_i18ncmp 3rd_detach actual &&
 267
 268        true
 269"
 270
 271# Detached HEAD tests for GIT_PRINT_SHA1_ELLIPSIS (old format)
 272test_expect_success 'describe_detached_head does print SHA-1 ellipsis when asked to' "
 273
 274        commit=$(git rev-parse --short=12 master^) &&
 275        commit2=$(git rev-parse --short=12 master~2) &&
 276        commit3=$(git rev-parse --short=12 master~3) &&
 277
 278        # The first detach operation is more chatty than the following ones.
 279        cat >1st_detach <<-EOF &&
 280        Note: switching to 'HEAD^'.
 281
 282        You are in 'detached HEAD' state. You can look around, make experimental
 283        changes and commit them, and you can discard any commits you make in this
 284        state without impacting any branches by switching back to a branch.
 285
 286        If you want to create a new branch to retain commits you create, you may
 287        do so (now or later) by using -c with the switch command. Example:
 288
 289          git switch -c <new-branch-name>
 290
 291        Or undo this operation with:
 292
 293          git switch -
 294
 295        Turn off this advice by setting config variable advice.detachedHead to false
 296
 297        HEAD is now at \$commit... three
 298        EOF
 299
 300        # The remaining ones just show info about previous and current HEADs.
 301        cat >2nd_detach <<-EOF &&
 302        Previous HEAD position was \$commit... three
 303        HEAD is now at \$commit2... two
 304        EOF
 305
 306        cat >3rd_detach <<-EOF &&
 307        Previous HEAD position was \$commit2... two
 308        HEAD is now at \$commit3... one
 309        EOF
 310
 311        reset &&
 312        check_not_detached &&
 313
 314        # Various ways of asking for ellipses...
 315        # The user can just use any kind of quoting (including none).
 316
 317        GIT_PRINT_SHA1_ELLIPSIS=yes git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 318        check_detached &&
 319        test_i18ncmp 1st_detach actual &&
 320
 321        GIT_PRINT_SHA1_ELLIPSIS=Yes git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 322        check_detached &&
 323        test_i18ncmp 2nd_detach actual &&
 324
 325        GIT_PRINT_SHA1_ELLIPSIS=YES git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 326        check_detached &&
 327        test_i18ncmp 3rd_detach actual &&
 328
 329        true
 330"
 331
 332test_done