Skip to content

Commit be8ef33

Browse files
jaysoffiangitster
authored andcommitted
git-checkout.txt: improve detached HEAD documentation
The detached HEAD state is a source of much confusion for users new to git. Here we try to document it better. Reworked from http://article.gmane.org/gmane.comp.version-control.git/138440 Requested-by: Nicolas Pitre <[email protected]> Signed-off-by: Jay Soffian <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5673d69 commit be8ef33

File tree

1 file changed

+121
-23
lines changed

1 file changed

+121
-23
lines changed

Documentation/git-checkout.txt

Lines changed: 121 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -206,40 +206,138 @@ leave out at most one of `A` and `B`, in which case it defaults to `HEAD`.
206206

207207
Detached HEAD
208208
-------------
209+
HEAD normally refers to a named branch (e.g. 'master'). Meanwhile, each
210+
branch refers to a specific commit. Let's look at a repo with three
211+
commits, one of them tagged, and with branch 'master' checked out:
209212

210-
It is sometimes useful to be able to 'checkout' a commit that is
211-
not at the tip of one of your branches. The most obvious
212-
example is to check out the commit at a tagged official release
213-
point, like this:
213+
------------
214+
HEAD (refers to branch 'master')
215+
|
216+
v
217+
a---b---c branch 'master' (refers to commit 'c')
218+
^
219+
|
220+
tag 'v2.0' (refers to commit 'b')
221+
------------
222+
223+
When a commit is created in this state, the branch is updated to refer to
224+
the new commit. Specifically, 'git commit' creates a new commit 'd', whose
225+
parent is commit 'c', and then updates branch 'master' to refer to new
226+
commit 'd'. HEAD still refers to branch 'master' and so indirectly now refers
227+
to commit 'd':
214228

215229
------------
216-
$ git checkout v2.6.18
230+
$ edit; git add; git commit
231+
232+
HEAD (refers to branch 'master')
233+
|
234+
v
235+
a---b---c---d branch 'master' (refers to commit 'd')
236+
^
237+
|
238+
tag 'v2.0' (refers to commit 'b')
217239
------------
218240

219-
Earlier versions of git did not allow this and asked you to
220-
create a temporary branch using the `-b` option, but starting from
221-
version 1.5.0, the above command 'detaches' your HEAD from the
222-
current branch and directly points at the commit named by the tag
223-
(`v2.6.18` in the example above).
241+
It is sometimes useful to be able to checkout a commit that is not at
242+
the tip of any named branch, or even to create a new commit that is not
243+
referenced by a named branch. Let's look at what happens when we
244+
checkout commit 'b' (here we show two ways this may be done):
224245

225-
You can use all git commands while in this state. You can use
226-
`git reset --hard $othercommit` to further move around, for
227-
example. You can make changes and create a new commit on top of
228-
a detached HEAD. You can even create a merge by using `git
229-
merge $othercommit`.
246+
------------
247+
$ git checkout v2.0 # or
248+
$ git checkout master^^
249+
250+
HEAD (refers to commit 'b')
251+
|
252+
v
253+
a---b---c---d branch 'master' (refers to commit 'd')
254+
^
255+
|
256+
tag 'v2.0' (refers to commit 'b')
257+
------------
230258

231-
The state you are in while your HEAD is detached is not recorded
232-
by any branch (which is natural --- you are not on any branch).
233-
What this means is that you can discard your temporary commits
234-
and merges by switching back to an existing branch (e.g. `git
235-
checkout master`), and a later `git prune` or `git gc` would
236-
garbage-collect them. If you did this by mistake, you can ask
237-
the reflog for HEAD where you were, e.g.
259+
Notice that regardless of which checkout command we use, HEAD now refers
260+
directly to commit 'b'. This is known as being in detached HEAD state.
261+
It means simply that HEAD refers to a specific commit, as opposed to
262+
referring to a named branch. Let's see what happens when we create a commit:
238263

239264
------------
240-
$ git log -g -2 HEAD
265+
$ edit; git add; git commit
266+
267+
HEAD (refers to commit 'e')
268+
|
269+
v
270+
e
271+
/
272+
a---b---c---d branch 'master' (refers to commit 'd')
273+
^
274+
|
275+
tag 'v2.0' (refers to commit 'b')
241276
------------
242277

278+
There is now a new commit 'e', but it is referenced only by HEAD. We can
279+
of course add yet another commit in this state:
280+
281+
------------
282+
$ edit; git add; git commit
283+
284+
HEAD (refers to commit 'f')
285+
|
286+
v
287+
e---f
288+
/
289+
a---b---c---d branch 'master' (refers to commit 'd')
290+
^
291+
|
292+
tag 'v2.0' (refers to commit 'b')
293+
------------
294+
295+
In fact, we can perform all the normal git operations. But, let's look
296+
at what happens when we then checkout master:
297+
298+
------------
299+
$ git checkout master
300+
301+
HEAD (refers to branch 'master')
302+
e---f |
303+
/ v
304+
a---b---c---d branch 'master' (refers to commit 'd')
305+
^
306+
|
307+
tag 'v2.0' (refers to commit 'b')
308+
------------
309+
310+
It is important to realize that at this point nothing refers to commit
311+
'f'. Eventually commit 'f' (and by extension commit 'e') will be deleted
312+
by the routine git garbage collection process, unless we create a reference
313+
before that happens. If we have not yet moved away from commit 'f',
314+
any of these will create a reference to it:
315+
316+
------------
317+
$ git checkout -b foo <1>
318+
$ git branch foo <2>
319+
$ git tag foo <3>
320+
------------
321+
322+
<1> creates a new branch 'foo', which refers to commit 'f', and then
323+
updates HEAD to refer to branch 'foo'. In other words, we'll no longer
324+
be in detached HEAD state after this command.
325+
326+
<2> similarly creates a new branch 'foo', which refers to commit 'f',
327+
but leaves HEAD detached.
328+
329+
<3> creates a new tag 'foo', which refers to commit 'f',
330+
leaving HEAD detached.
331+
332+
If we have moved away from commit 'f', then we must first recover its object
333+
name (typically by using git reflog), and then we can create a reference to
334+
it. For example, to see the last two commits to which HEAD referred, we
335+
can use either of these commands:
336+
337+
------------
338+
$ git reflog -2 HEAD # or
339+
$ git log -g -2 HEAD
340+
------------
243341

244342
EXAMPLES
245343
--------

0 commit comments

Comments
 (0)