From: Jay Soffian <jaysoffian@gmail.com>
To: git@vger.kernel.org
Cc: Jay Soffian <jaysoffian@gmail.com>,
Nicolas Pitre <nico@fluxnic.net>,
Junio C Hamano <gitster@pobox.com>
Subject: [PATCH] git-checkout.txt: improve detached HEAD documentation
Date: Thu, 17 Feb 2011 14:46:06 -0500 [thread overview]
Message-ID: <1297971966-58500-1-git-send-email-jaysoffian@gmail.com> (raw)
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 <nico@fluxnic.net>
Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
---
Nicolas only asked me to contribute this a full year ago, not too
bad. :)
Documentation/git-checkout.txt | 108 +++++++++++++++++++++++++++++++---------
1 files changed, 85 insertions(+), 23 deletions(-)
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 880763d..21abd2a 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -206,40 +206,102 @@ leave out at most one of `A` and `B`, in which case it defaults to `HEAD`.
Detached HEAD
-------------
+HEAD normally refers to a named branch (e.g. "master"). Meanwhile, each
+branch refers to a specific commit-id. Let's look at a repo with three
+commits and with "master" checked out:
-It is sometimes useful to be able to 'checkout' a commit that is
-not at the tip of one of your branches. The most obvious
-example is to check out the commit at a tagged official release
-point, like this:
+------------
+ HEAD (refers to master)
+ v
+a---b---c master (refers to c)
+------------
+
+When a commit is created in this state, the branch is updated to the new
+commit-id. Let's add a commit:
------------
-$ git checkout v2.6.18
+ HEAD (refers to master)
+ v
+a---b---c---d master (refers to d)
------------
-Earlier versions of git did not allow this and asked you to
-create a temporary branch using the `-b` option, but starting from
-version 1.5.0, the above command 'detaches' your HEAD from the
-current branch and directly points at the commit named by the tag
-(`v2.6.18` in the example above).
+It is sometimes useful to be able to checkout a commit that is not at
+the tip of any named branch, or even to create a new commit that is not
+referenced by a named branch. Let's look at what happens when we
+checkout commit b:
-You can use all git commands while in this state. You can use
-`git reset --hard $othercommit` to further move around, for
-example. You can make changes and create a new commit on top of
-a detached HEAD. You can even create a merge by using `git
-merge $othercommit`.
+------------
+$ git checkout master^^
-The state you are in while your HEAD is detached is not recorded
-by any branch (which is natural --- you are not on any branch).
-What this means is that you can discard your temporary commits
-and merges by switching back to an existing branch (e.g. `git
-checkout master`), and a later `git prune` or `git gc` would
-garbage-collect them. If you did this by mistake, you can ask
-the reflog for HEAD where you were, e.g.
+ HEAD (refers to b)
+ v
+a---b---c---d master (refers to d)
+------------
+
+Notice that HEAD now refers directly to commit b. In git terminology,
+this is known as having a detached HEAD. It means simply that HEAD
+refers to a specific commit-id, as opposed to referring to a named
+branch. Let's add a commit while HEAD is detached:
------------
-$ git log -g -2 HEAD
+ HEAD (refers to e)
+ v
+ e
+ /
+a---b---c---d master (refers to d)
+------------
+
+We have created a new commit, but it is referenced only by HEAD. We can
+of course add yet another commit in this state:
+
+------------
+ HEAD (refers to f)
+ v
+ e---f
+ /
+a---b---c---d master (refers to d)
+------------
+
+In fact, we can perform all the normal git operations. But, let's look
+at what happens when we then checkout master:
+
------------
+$ git checkout master
+ e---f HEAD (refers to master)
+ / v
+a---b---c---d master (refers to d)
+------------
+
+It is important to realize that at this point nothing refers to commits
+e and f. Eventually these commits will be deleted by the routine git
+garbage collection process, unless we create a reference before that
+happens. If we have not yet moved away from commit f, any of these will
+create a reference to it:
+
+------------
+$ git checkout -b foo # (1)
+$ git branch foo # (2)
+$ git tag foo # (3)
+------------
+
+(1) creates a new branch "foo", which refers to f, and then updates HEAD
+to refer to "foo". In other words, we'll no longer be in detached HEAD
+state after (1).
+
+(2) similarly creates a new branch "foo", which refers to f, but leaves
+HEAD detached.
+
+(3) creates a new tag "foo", which refers to f, leaving HEAD detached.
+
+If we have moved away from commit f, then we must first recover its id
+(typically by using git reflog), and then we can create a reference to
+it. For example, to see the last two commits to which HEAD referred, we
+can use:
+
+------------
+$ git log -g -2 HEAD
+------------
EXAMPLES
--------
--
1.7.4.1.29.g21713
next reply other threads:[~2011-02-17 19:46 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-02-17 19:46 Jay Soffian [this message]
2011-02-17 19:48 ` [PATCH] git-checkout.txt: improve detached HEAD documentation Jay Soffian
2011-02-17 20:47 ` Nicolas Pitre
2011-02-17 21:49 ` Junio C Hamano
2011-02-18 0:14 ` Nicolas Pitre
2011-02-18 0:25 ` Junio C Hamano
2011-02-20 5:21 ` Jay Soffian
2011-02-22 5:56 ` Junio C Hamano
2011-02-22 15:19 ` Jay Soffian
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1297971966-58500-1-git-send-email-jaysoffian@gmail.com \
--to=jaysoffian@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=nico@fluxnic.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).