'I can't checkout a specific branch, "detached HEAD state"
Me and my friend has a repo which he created. He then created a branch called "lexer" for us to work on.
The problem is that while he can switch forth and back between master and lexer it does not work at all for me.
Eventually I just started over (rm -rf repo
and then cloned the repo) but it's still impossible to checkout the lexer branch?
On a freshly cloned repo:
git branch
gives:
$ git branch
* master
git checkout lexer
gives:
$ git checkout lexer
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
I CAN checkout origin/lexer but I end up in a detached HEAD state?
$ git checkout origin/lexer master
Note: checking out 'origin/lexer'.
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.
It is possible for me to push to the lexer branch by doing
git push origin HEAD:lexer
but well, I really would like to sort this mess out. It's so weird that it works for him but not for me? He says that he hasn't got any local changes from the git repo either...
Anyone have any clue?
Solution 1:[1]
I'm going to venture a guess that you have a directory named lexer
at the top level. Since git checkout
is used both to switch branches and to reset files in the tree, it's probably detecting that you don't have a branch called lexer
but you do have a path and selects the second mode.
It works for your friend because he already has a lexer
branch.
Easiest workaround is probably to create the branch using git branch
instead.
git branch --track lexer origin/lexer
should do that for you. You can then use git checkout
to switch to it.
Another option might be to use the --
flag to git checkout. I haven't tried it but I think it should work:
git checkout lexer --
When you add --
, the word before it is always considered a branch/commit/tree and the word after a path.
Solution 2:[2]
Your probably want this:
git checkout -t origin/lexer
From git manual:
As a convenience, --track without -b implies branch creation...
and
-t, --track... When creating a new branch, set up "upstream" configuration... If no -b option is given, the name of the new branch will be derived from the remote-tracking branch
Solution 3:[3]
TLDR: This could just be a syntax issue. Instead of
git checkout origin/mybranch
Try:
git checkout mybranch
The steps git takes, given the following command:
git checkout origin/mybranch
- git looks for a branch called 'origin/mybranch' in the local repo.
- Not finding it, it will then look for a branch called 'origin/mybranch' in the available remotes.
- Not finding that either, it tries treating that as a commit tag, and finds the tag 'origin/mybranch' against a specific commit. It checks out that commit for you, in a detached state.
But that wasn't what you wanted! You wanted the branch called 'mybranch'. If there's only one remote with such a branch (and nothing locally to confuse matters) then git will assume you meant this usage, filling in <remote>
for you:
git checkout -b <branch> --track <remote>/<branch>
If it can't find a branch with the matching name, it defaults to this:
git checkout [--detach] <commit>
Which is where the detached HEAD message comes in.
See the git checkout docs, and pay careful note of <branch>
vs <remote>
.
Solution 4:[4]
You can't checkout lexer
because you don't have the branch in your local repository (and surely a folder with the same name) . You only have the remote branch 'origin/lexer'.
First you have to create the local branch :
git checkout -b lexer origin/lexer
A good explaination on the subject: https://git-scm.com/book/en/v2/Git-Branching-Remote-Branches#Tracking-Branches
Solution 5:[5]
You get into a detached HEAD state because origin/lexer
is a remote tracking branch, and thus read only. You want to just checkout lexer
, and do your work on that. Then, when you push, origin/lexer
will be brought up to date.
Edit: Rereading your question, I see that you have tried to checkout lexer, but end up staying on master. It is strange that git checkout
is failing silently. Try git checkout -t origin/lexer
.
Solution 6:[6]
Another wild guess: you are having a tag with identical name so
git checkout lexer
actually checks out the tag, not the branch
Solution 7:[7]
When you do: git checkout origin/lexer master
you simply change your HEAD
to point to the latest commit in our remote
branch. It's a read only branch.
If you wish to understand what HEAD is read this :
How to move HEAD back to a previous location? (Detached head)
In your case you simply need to do the following:
Update your repository with the latest code with all branches and tags
# Update your local repository with all the remote branches
# --prune = remove all deleted data locally which was removed on the remote
git fetch --all --prune
Now you should have the latest branches locally.
Delete the old local branch
!!! IMPORTANT:
If you made modification and did not push them don't delete the local branch
git branch -D lexer
Checkout the desired branch
# don't use the remote simply the branch name
git checkout lexer
Now you have local branch with the name lexer checked out from your remote branch
Solution 8:[8]
what I found that if that a branch doesn't exists or we made some mistake in branch name like feature/ or origin/ etc then I got detached head. check branch name properly then can do checkout branchname
Solution 9:[9]
I just replace the command
$ git checkout v4.9.0
with
$ *git checkout -b v4.9.0
and it is working for me.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow