Why does git detached HEAD even exist?
Our team recently moved to git, migrating from svn and hg. So when they checkout the tip of a tree, depending on the GUIs, they had a tendency to checkout a particular commit or local branch rather than a new tracking branch, without the understanding of how git really works.
So my question is why does detached HEAD even exist?
Why can’t it be defaulted to always checking out a new branch? (with my limited understanding of git)
Education/Training definitely helped but there is always someone new to git…
How do you guys manage it?
By the way, I know how to fix them. I’ve read through a lot of posts on this site.
This is more for knowledge sharing and how you prevent or manage.
After reading the detailed explanations provided below, I now realized that my question should have been “Why does git give a detached HEAD when checking out a new remote branch?”. Regardless, the answer will give you a very good understanding!
4 Solutions collect form web for “Why does git detached HEAD even exist?”
[…] why does detached HEAD even exist?
Why can’t it be defaulted to always checking out a new branch?
Let me try with the following metaphor. If you think of your Git repository as a photo album that chronicles the history of your repository…
- You can think of branches as bookmarks; they mark points of interest in your history, snapshots you’re likely to go back to, at some stage… if only out of nostalgia 🙂
- You can think of the
HEADreference as one of your fingers, keeping the book open at a particular page.
Now, imagine if you were allowed to open the book only where there is already a bookmark. That would be very restrictive and unwieldy: you would have to create and use many bookmarks just in order to visit certain pages of your history:
Instead, Git allows you to flick through the book and open it on any page you fancy. Then, if you notice a particular snapshot that you’ve taken interest in, you can always create a new bookmark (branch) for it.
In a nutshell, that’s why detached-HEAD state is useful. It allows you to check out any commit, even one which no branch currently points to. If you decide that you’d like to base brand new work on the commit in question, then it would make sense to create a new branch that points to that commit; but, otherwise, creating a new branch would be overkill.
Why does git give a detached HEAD when checking out a new remote branch?
I’m guessing you probably run
git checkout <remote-branch>
and are suprised that it detaches the
HEAD. You need to be aware that Git distinguishes between
- remote-tracking branches, which are local to your repository, but are only meant to reflect what a branch living in a remote repository looked like the last time you communicated with the server; you cannot work on such branches; and
- (purely) local branches, which can work on.
If you simply run
git checkout <remote-branch>
no local branch for you to play with will be created, and you will end up in detached-
HEAD state. You may want to run
git checkout -b <new-local-branch> <remote-branch>
instead. That will create and check out a new local branch pointing at the same commit as the remote branch. No detached
Simply put, a detached HEAD is your HEAD reference at somewhere other than the tip of your current branch.
In layman’s terms, HEAD points to the latest commit in your repository; a detached HEAD points to somewhere that is not at the latest commit in your repository.
It exists because going back to previous commits is very handy – notably when running
git bisect, as Git has to go back in history to your earliest “good” check-in. It’s also good to be able to check out an arbitrary commit to run a smoke test on it (in case
git bisect is too Byzantine), or check out a specific release version.
Defaulting to creation of a branch is extremely confusing behavior, as there’s not much reason to create branches if you’re working on your own repository, or if everyone’s collaborative and commits to the same branch all the time (although this can lead to some heartache).
The main things to remember:
To get out of a detached HEAD state, check out the current branch (
git checkout master). This will move your HEAD pointer to the tip of
master, for example.
To create a new branch, use
git checkout -b <branch-name>. The
-bflag on checkout indicates that you wish to create a new branch.
To update your local repository with changes from the server, use
git pull. This will retrieve any remote changes, and advance your local branches’ tips to match that of the remote server.
Because they are confused with the term “checkout”. They have different meaning in the two version control system.
For your particular question, the simplest message to them is , “git pull” = “svn checkout”. So instead of doing checkout and think that they are trying to get the latest version from the server, they should use ‘pull’
There is another common form of the checkout command that the other answers don’t mention.
Form 1 – This will checkout an already existing local branch
git checkout LOCAL_BRANCH
Form 2 – Forcing detached HEAD
git checkout REFERENCE
Here, reference can be a remote branch reference, a tag, a sha, etc. A very common mistake is to type
git checkout origin/some_branch and not realizing that will deference origin/some_branch to a SHA, and then put you in detached head.
Form 3 – Simple form of checking out a remote branch
git checkout REMOTE_BRANCH
If REMOTE_BRANCH isn’t a local branch, but it is a valid branch on origin, then Git will create a local branch and setup tracking. so
git checkout some_branch if “origin/some_branch” exists will work.
Finally, you can checkout an arbitrary SHA/Ref and create a branch with
git checkout -b LOCAL_BRANCH REF. If REF happens to be an a remote branch reference Git will automatically setup tracking for you (in this case you must explicitly put origin/ in the ref name). So
git checkout -b my_some_branch origin/somebranch will create and checkoug my_some_branch and also enable tracking for it.