What is detached HEAD state and how do I get out of it?

In a nutshell: You’re not on a branch right now. You’re browsing a snapshot of your Git files from a specific commit in your history. To get out of detached HEAD state and go back to master, do git checkout master.

Situation

  • You either executed git checkout [hash of a commit] or you tried to switch to an upstream branch (e.g. origin/master) instead of a local branch (e.g. master).
  • You saw an intimidating message that looked a lot like this:
$ git checkout ac63806012ea5a2fc58259b275cbc9582dc699a4
Note: checking out 'ac63806012ea5a2fc58259b275cbc9582dc699a4'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at ac63806... Add notes

Explanation

What is HEAD?

It’s a special Git term that often means “the most recent commit from the branch you’re currently on”. We’re oversimplifying things a bit, but we’ll talk about the fine print shortly. Here are some examples to illustrate how HEAD works.

  • If git status says that you’re on the master branch and git log tells you that the last commit on your current branch is abcd567, your HEAD currently points to abcd567.
  • If you then switch to a branch named feature/add-killswitch whose last commit has a hash of bond007, your HEAD will move to bond007.

In both cases, you’re on a branch. Your HEAD is “attached” to the branch, i.e. it always points to the last commit on that branch. However, Git also has a mode where you can browse specific commits - outside of the context of branches.

What happens when Git enters detached HEAD state?

When you run a command like git checkout [commit hash] your Git files are rolled back to the state they were in when that commit was made. HEAD will now point to the commit you specified. It’s like switching to another branch, except you’re switching to a specific commit in your Git history.

Your Git status will look like this when HEAD is detached:

HEAD detached at ac63806
nothing to commit, working tree clean

Some important things to note:

  • Running git checkout [commit hash] won’t affect your branches in any way. You’re just viewing your history at a certain point in time. When you return to your branch with git checkout [branch name] it will still be there in its original state.
  • Any commits you make in detached HEAD mode will get lost. Git won’t prevent you from making commits in detached HEAD mode, but your commits won’t be added to a branch. Therefore you pretty much lose track of them next time you run a checkout command. If you accidentally lose commits this way, you will have to resort to advanced Git sorcery for a chance to recover them.
  • Files that were never added to Git are unaffected by this command. Git doesn’t keep their history, so git checkout will not touch them.

What’s the main purpose of detached HEAD state?

The most useful thing you can do with it is explore an older state of a repository. Afterwards, you’ll probably want to return to the branch you came from. You can do this with git checkout -. Interesting tidbit about the dash: it’s a shortcut for “the branch or commit you were on before your last checkout command.

What else can I do in detached HEAD state?

You can start a new branch from the current commit. git checkout -b [name of your new branch] will create a new branch from your current HEAD position. You will exit detached HEAD mode when you create a new branch.