Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HEAD detached at origin/master

Tags:

git

I've just checked out an old project to fix a bug. git reports:

HEAD detached at origin/master 

git status reports I have an untracked file:

<project name>.xcworkspace/xcshareddata/ 

I'd like to get on and fix the bug but I'm not sure quite what's going on. If I try git checkout master I get:

error: The following untracked working tree files would be overwritten by checkout: <project name>.xcworkspace/xcshareddata/ 

Can I just delete this file? Am I on the master branch? If not, how do I get to it?

like image 688
Snowcrash Avatar asked Aug 10 '14 19:08

Snowcrash


People also ask

How do I solve the detached head at origin master?

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. Now, to get them onto master: Do a git reflog or even just git log and note your commits.

What is head detached at origin master?

What does detached HEAD mean? In Git, HEAD refers to the currently checked-out branch's latest commit. However, in a detached HEAD state, the HEAD does not point to any branch, but a specific commit or the remote repository.

How do I resolve a detached head in git?

If you want to keep changes made with a detached HEAD, just create a new branch and switch to it. You can create it right after arriving at a detached HEAD or after creating one or more commits. The result is the same. The only restriction is that you should do it before returning to your normal branch.

How do you reattach a detached head?

You must understand that any of your branches will not be affected if you ever get into a detached state . Now, the best way to reattach the HEAD is to create a new branch. We can do it as simple as git checkout -b <branch-name> . This will commit the changes from your temporary branch into the branch you need them.


1 Answers

As CommuSoft says, you're not on master. You're in "detached HEAD" mode. You get that any time you explicitly check out something that is not a (local) branch name:

$ git checkout origin/master    # detach to "remote branch" 

or if there's a tag v1.7:

$ git checkout v1.7             # detach to tag 

and you can even explicitly detach when using a local branch name:

$ git checkout --detach master  # forcibly detach 

A "detached HEAD" means you're not on a branch. Being "on a branch" means you're not using the detached HEAD mode. Yes, that's pretty circular; see this question and its answers for more details.

As for the:

error: The following untracked working tree files would be overwritten ...

When you get git checkout to move from one commit to another, it does two main things:

  1. choose whether to be in "detached HEAD" mode, and
  2. rearrange the work tree to match the moved-to commit.

Step 2 is where the problem is occurring. You're on the commit identified by origin/master, and in that commit, there is no record of the files git is currently complaining about. You've asked to switch to the commit identified by master, which is obviously a different commit.1 Git sees that in the commit identified by master, there are some (maybe just one) files with the same names, that are different from the files or directories that are in your work-tree right now.

In order to switch from the current commit to the new one, git checkout must remove the existing files-or-directories and replace them with the ones in the new commit—the one you're asking to switch to. If those files or directories were tracked in the current commit, git would be happy to remove and replace them as needed, as git can always get them back for you: just switch back to that old commit, and there they are. But they're not in the current, to-be-switched-away-from, commit. So git tells you: "Hey, if I make this switch you asked for, I can't guarantee that I'll be able to restore these files and/or directories."

It's now up to you, not git, to figure out what to do with these files and/or directories. Based on the error message, it's a directory,2 and switching to master will cause that directory to be removed and replaced with something else (possibly a different directory with some file(s) in it, possibly just a file). Do you:

  • want to save it/them?
  • if so, do you want to save it/them in a commit, or just move them out of the way?
  • or do you just want to blow them away?

To save them, either commit them, or move them out of the way (e.g., rename them to a path that's not part of the work-tree, or to a different untracked name that's "safer", whatever that would be).

To simply blow them away, remove them manually or use git checkout -f (force) to make git do it.

Since you're not on a branch now (are in "detached HEAD" mode), if you want to commit them permanently to the repository, you can use something like the method CommuSoft added while I was writing this up. (You can create the new branch at any time, before or after doing a "git commit".)

You can also use git stash. Git's stash is deceptively complex little script: it makes commits that are not on any branch at all, that can later be transplanted to a branch. Using it is quite simple and easy: you just run git stash save and all pending tracked changes are saved and cleaned up, or run git stash save -u and all pending tracked changes and untracked files are saved and cleaned up. They are now all safely squirreled away in the repository, under a commit, even though it's not a commit-on-a-branch.

There is no single right answer for what to do here.


1Obviously different, because if you were already on the commit you're asking git to move to, then either the file would be in the commit and hence tracked, or it would be not-in-the-commit and hence you would not be asking git to clobber it.

2This is a little odd. If I make a directory that will be clobbered by my git checkout, and I make it as an empty directory, git just goes ahead and clobbers it. Here the difference between master^ and master is that moving forward from master^ to master creates file mxgroup.py (so stepping back removes it):

$ git checkout -q master^  # file goes away, now let's mkdir... $ mkdir mxgroup.py; git checkout -q master $ file mxgroup.py mxgroup.py: Python script, ASCII text executable 

However, if I have a non-empty directory, I get a different error message:

$ git checkout -q master^  # file goes away; mkdir and make file $ mkdir mxgroup.py; touch mxgroup.py/file; git checkout -q master error: Updating the following directories would lose untracked files in it:     mxgroup.py  Aborting 

But this is with git version 2.0.2; perhaps older gits are not as clever.

like image 149
torek Avatar answered Oct 19 '22 23:10

torek