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