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