190

I'm developing a deployment script for my git project and I just started using tags. I've added a new tag called v2.0:

git tag -a v2.0 -m "Launching version 2.0"

And I've pushed this tag to the remote repository

git push --tags

When I try to execute the deployment script and check out the v2.0 tag I get this message:

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

Is that normal? The repository is in limbo because if I do:

git branch

I get this output:

* (no branch)
  master

Sorry if this is obvious but I couldn't figure it out.

3
  • When you say, "execute the deployment script and checking out the v2.0" does your code look like, "git checkout v2.0"? I'm trying to revamp my release script and when I run "git checkout v2.0" from my production machine I get, "error: pathspec 'v2.0' did not match any file(s) known to git." Even though I've run, "git push origin --tags" on my local machine before doing the "git checkout v2.0" on production. I've also tried running, "git pull --tags" and "git fetch --tags" on production prior to calling "git checkout v2.0" and that doesn't work either... I'm still getting the error. Any Ideas?
    – John Erck
    Commented Oct 26, 2012 at 18:43
  • 4
    I was about to delete the above comment but then figured keeping it up might help somebody else. I was getting the error because I had a TYPO in my tag name when I was running, "git checkout v2.0". However, the typo related error is the exact same error you'll get if you run, "git checkout v2.0" WITHOUT a typo BEFORE running, "git fetch --tags". So, ultimately, my problem was solved by running, "git fetch --tags" PRIOR to running, "git checkout v2.0" without any typos. Phew!
    – John Erck
    Commented Oct 26, 2012 at 20:34
  • Nice, yeah you need to do fetch --tags before (or git fetch that will pull all from remote) so git can checkout the tag. Sorry I just saw your comment today.
    – Khriz
    Commented Nov 28, 2012 at 11:23

2 Answers 2

475

Okay, first a few terms slightly oversimplified.

In git, a tag (like many other things) is what's called a treeish. It's a way of referring to a point in in the history of the project. Treeishes can be a tag, a commit, a date specifier, an ordinal specifier or many other things.

Now a branch is just like a tag but is movable. When you are "on" a branch and make a commit, the branch is moved to the new commit you made indicating it's current position.

Your HEAD is pointer to a branch which is considered "current". Usually when you clone a repository, HEAD will point to master which in turn will point to a commit. When you then do something like git checkout experimental, you switch the HEAD to point to the experimental branch which might point to a different commit.

Now the explanation.

When you do a git checkout v2.0, you are switching to a commit that is not pointed to by a branch. The HEAD is now "detached" and not pointing to a branch. If you decide to make a commit now (as you may), there's no branch pointer to update to track this commit. Switching back to another commit will make you lose this new commit you've made. That's what the message is telling you.

Usually, what you can do is to say git checkout -b v2.0-fixes v2.0. This will create a new branch pointer at the commit pointed to by the treeish v2.0 (a tag in this case) and then shift your HEAD to point to that. Now, if you make commits, it will be possible to track them (using the v2.0-fixes branch) and you can work like you usually would. There's nothing "wrong" with what you've done especially if you just want to take a look at the v2.0 code. If however, you want to make any alterations there which you want to track, you'll need a branch.

You should spend some time understanding the whole DAG model of git. It's surprisingly simple and makes all the commands quite clear.

11
  • Ok thanks, I don't need to do any changes in the code so I think it's ok. I don't need to create a branch. Thanks a lot!
    – Khriz
    Commented Apr 7, 2011 at 14:33
  • 1
    I was lost the first time I looked over this answer but after I read the Git branching documentation: http://git-scm.com/book/en/Git-Branching-What-a-Branch-Is it was a lot clearer. Commented May 30, 2013 at 19:50
  • 4
    Awesome answer, but may I add regarding: "Switching back to another commit will make you lose this new commit you've made."—you can still find the commit in git reflog, which is a great command to know about! Unless garbage collection has happened, it's seemingly "impossible" to lose a commit. Commented Aug 28, 2013 at 16:23
  • Unreferenced commits can be lost by a garbage collection operation. Commented Aug 29, 2013 at 3:32
  • 1
    The url is wrong because they changed layout of the page.
    – jcubic
    Commented Aug 15, 2014 at 11:23
15

Yes, it is normal. This is because you checkout a single commit, that doesnt have a head. Especially it is (sooner or later) not a head of any branch.

But there is usually no problem with that state. You may create a new branch from the tag, if this makes you feel safer :)

2
  • 1
    Ok, I will keep it that way... safety is overrated anyway ;)
    – Khriz
    Commented Apr 7, 2011 at 14:34
  • As you commented in Noufals answer (its the better one, I must say ;)): As long as you dont change anything, there is nothing you have to be worried about. However, if you assume, that you may change something, you can simply create a branch, because they are cheap in git and you can delete it (and recreate later and so on).
    – KingCrunch
    Commented Apr 7, 2011 at 14:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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