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 untra
No you're not on the master branch, your on some kind of "newly invented" branch without a name that was once the master.
You simply need to switch back to the master:
git checkout master
However if you wish to fix a bug, you should work at your own branch (according to most git workflows). Thus checkout the master and branch from it:
git checkout master
git checkout -b fix-issue #give the branch a name that refers to the bug
then fix the bug and run:
git checkout master
git merge --no-ff fix-issue -m "Fixed some strange issue, here follows a description"
EDIT
As specified in your question you have an untracked file. If these file(s) are of no importance, you can remove them. If on the other hand you wish to maintain them, you can merge them into the master first.
Therefore you create a temporary branch:
git commit -m "some temporary message"
git checkout -b temporary
git checkout master
git merge --no-ff temporary
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:
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:
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.