2

While trying to pull code from a different machine I got a detached HEAD message(with no branch connected) with red color in command window.

I would like to analyze what I did to make it detached.

  1. What is meant by 'detached HEAD'?
  2. How can one purposefully make the current branch in git detached from its HEAD?
  3. And once detached, how to attach it?

EDIT:---------------------------------------------------------------------------

Mistake I made was: git checkout origin/test //checking out remote branch

4
  • Are you using some git gui tool? Or the bash only?
    – sergej
    Commented Jul 10, 2018 at 13:38
  • @sergej, No, Just Visual studio. and command prompt. Detach happened mostly because of checkout command in command prompt. But did not use commit ids. Just branch names. going from answers recieved, remote branch checkout created it Commented Jul 10, 2018 at 16:14
  • Possible duplicate of Why did my Git repo enter a detached HEAD state?
    – phd
    Commented Jul 10, 2018 at 20:06
  • stackoverflow.com/a/5772882/7976758
    – phd
    Commented Jul 10, 2018 at 20:06

6 Answers 6

3
  1. What is meant by 'detached HEAD'?

"detached HEAD" means : if you add a new git commit while detached, it will not be tracked by any named branch.

HEAD is actually described by a file on your disk : .git/HEAD
If you look at the content of this file, you can see two formats :

# this means : attached HEAD, "master" is the current active branch
$ cat .git/HEAD 
ref: refs/heads/master

# this means : detached HEAD, current active commit is 140a4c
$ cat .git/HEAD
140a4ceae12c237f9f23321aa5e29d8d14852f6f
  1. How can one purposefully make the current branch in git detached from its HEAD?

If you run git checkout <something> and <something> is anything else than a local branch name (any of : a raw commit id, a tag name or the name of a remote branch), you will be in a "detached HEAD" state.

# this will lead to an attached HEAD :
git checkout master
git checkout develop
git checkout bob/s/feature

# this will lead to a detached HEAD :
git checkout 140a4ce         # raw commit
git checkout 1.1.2           # tag
git checkout origin/develop  # remote branch
  1. And once detached, how to attach it?

Depending on what you want :

  • use git log --decorate -1 or gitk or gitg or any git viewer which will show you the names of branches pointing at your current HEAD commit ;
    if one of these branches is the one you want to work on, just run git checkout <this branch>

  • if you know you want to work on a new branch :

    # create a new branch on your current commit :
    $ git branch new_branch
    
    # checkout this branch to use it as your active branch :
    $ git checkout new_branch
    

    note : git branch new_branch && git checkout new_branch is exactly equivalent to :

    # same action in one single command :
    $ git checkout -b new_branch
    
2
  • For option3 this worked(to create a new branch from it): git checkout -b <branch> as @Mark Adelsberger, pointed out Commented Jul 10, 2018 at 16:12
  • @BlueClouds : indeed, I edited my answer to include that
    – LeGEC
    Commented Jul 11, 2018 at 10:04
2

With the "git checkout" command, you determine which revision of your project you want to work on. Git then places all of that revision's files in your working copy folder.

Normally, you use a branch name to communicate with "git checkout":

git checkout development

However, you can also provide the SHA1 hash of a specific commit instead:

git checkout 56a4e5c08
Note: checking out '56a4e5c08'.

You are in 'detached HEAD' state...

This exact state - when a specific commit is checked out instead of a branch - is what's called a "detached HEAD".

The problem with a detached HEAD:

The HEAD pointer in Git determines your current working revision (and thereby the files that are placed in your project's working directory). Normally, when checking out a proper branch name, Git automatically moves the HEAD pointer along when you create a new commit. You are automatically on the newest commit of the chosen branch.

When you instead choose to check out a commit hash, Git won't do this for you. The consequence is that when you make changes and commit them, these changes do NOT belong to any branch. This means they can easily get lost once you check out a different revision or branch: not being recorded in the context of a branch, you lack the possibility to access that state easily (unless you have a brilliant memory and can remember the commit hash of that new commit...).

How can one purposefully make the current branch in git detached from its HEAD?

There are a handful of situations where detached HEAD states are common: For example, if you checkout a "remote branch" without tracking it first, you can end up with a detached HEAD.

And once detached, how to attach it? You only need to checkout the branch you were on, e.g.

git checkout master
2

"Normally", the HEAD points to a branch and the branch points to a commit:

commit1 <-- commit2 <-- commit3
                           ^
                           |
                         master
                           ^
                           |
                          HEAD (attached)

# state after 'git checkout master'

In detached head state, the HEAD points to a commit which is not a tip of a branch:

commit1 <-- commit2 <-- commit3
               ^           ^
               |           |
               |         master
               |
               |
              HEAD (detached)

# state after 'git checkout <commit2 SHA>'

I'd recommend reading Pro Git book section Reset Demystified.

.. reset and checkout commands ... are two of the most confusing parts of Git when you first encounter them. They do so many things that it seems hopeless to actually understand them and employ them properly.

1

Short answer :

1) 'detached' means 'not pointing on any specific branch'

2) git checkout <any commit-id> (to detach HEAD on purpose)

3) git checkout <any branch> (to reattach HEAD)

1
  1. It's detached from a branch and now points to a commit. A non-detached HEAD points to a branch.

  2. git checkout foo, where foo is a revision, leads to a detached HEAD. The revision does not include a local branch without refs/heads/ and heads/. So, git checkout refs/heads/master, git checkout origin/master, git checkout HEAD^, git checkout stash@{0}, git checkout 6184fd3d148b8e330ae4ebbb05c51b88b4b1e0f2 all result in a detached HEAD, while git checkout master doesn't. git checkout HEAD doesn't either.

  3. If you need to work on with the detached HEAD's commit, you can create a branch to track it, by git checkout -b <branch>. If the current detached HEAD can be dropped, you can simply switch to another local branch or to another detached HEAD.

1

HEAD is a ref (a pointer to a commit) which determines what you have checked out. Many commands' default to working on the commit pointed to by HEAD. When you make a new commit, its parent (or in the case of merges, first parent) will be the commit pointed to by HEAD (unless you do something relatively obscure).

That said, HEAD is a symbolic ref, meaning it can point to a branch instead of pointing directly to a commit. It is considered normal for HEAD to point to a branch. When this is the case, instead of moving HEAD when you add commits, git moves the branch that HEAD points to - and HEAD, being pointed at that branch, implicitly moves along as well.

But you can make HEAD point directly to a commit, and that is called "detached head state", meaning the HEAD ref is not attached to any branch.

You can do this in a number of ways. Others have pointed out you could check out a commit using its ID (hash value). You could also check out a specific commit using an expression like master^. You could check out any ref that isn't a branch - such as a remote tracking ref, or a tag. You could say git checkout --detach.

You can get out of detached HEAD state just by checking out a branch (without the --detach option).

However, if you made any commits while in detached head state, they may be unreachable. In that case, if you don't want to lose them, you'll want to either incorporate them into some branch, create a new branch, or otherwise point some ref at them (e.g. by tagging them).

Not the answer you're looking for? Browse other questions tagged or ask your own question.