I am using Git alone for my local software project in Visual Studio 2010. Recently I created a new branch to do a larger refactoring of one of the dialogue windows. I did the following modifications:
- Rename Form1 to Form1a (including all depending files)
- Add new Form1
I checked this change into the branch, say form-refactoring. Interestingly, Git didn't notice that I renamed the file Form1.cs into Form1a.cs and created a brand new, totally different Form1.cs, but instead it noticed a new Form1a.cs file and found a whole lot of differences between the previous and new Form1.cs files. This will of course lead to totally garbaged diffs, but I don't care in this case as long as all files are handled correctly in the end.
Then I switched back to master to do some other small changes. Nothing conflicting. Until now, everything worked fine.
Today, I wanted to switch back to my branch form-refactoring to continue that work. But all I get is the following message:
git.exe checkout form-refactoring
Aborting
error: The following untracked working tree files would be overwritten by checkout:
Form1.Designer.cs
Please move or remove them before you can switch branches.
What is that supposed to be? The mentioned file is not untracked. Neither in the master branch, nor in the form-refactoring branch. It is part of both branches, but one is not a descendent of the other. What would happen if I delete it, is it gone for good then? I don't trust Git to bring back the correct file if I delete something now. I did not play with any file at all outside of my mentioned Git operations, so why should I play around with any file to continue using Git operations now? Git broke it, Git's supposed to handle it now!
Right now, I cannot continue with my work because I cannot switch branches. Is there an easy solution to this?
Git version is 1.7.6, TortoiseGit is 1.7.3.
The core.ignorecase config option was not set and Visual Studio had renamed the .Designer.cs file in case, switching from a capital to lower "D" (or vice versa). That was the problem in the end. It took me some file history breakup (deleting and re-adding files) to resolve this error after setting the option to true. Actually the option was set on one computer, but when cloning the repository, the setting got lost somehow. And then destiny was only waiting for VS to rename that file to catch me.
So on Windows, you always need to make sure that these two settings are correct after any init/clone operation:
git config core.ignorecase true
git config core.autocrlf false
Some tools (TGit, gitscc etc.) don't seem to do it right. It's absolutely necessary for normal operation on Windows, but Git doesn't care if they're not set correctly and just lets you stumble over them not telling you why. It's as much lying as it's helpful in this matter.
Git doesn't allow to switch branches if there is a possibility of data lose.
Generally it is a good idea to commit all your changes before switching to another branch.
If you are absolutely sure that you didn't make this change than you can reset your working tree using
git reset --hard HEAD
command. But I strongly don't recommend to do this. Use
git stash
command to stash your changes to internal storage. In this case you can always recover your data.
It seems that XXX branch (form-refactoring) contains this file but YYY doesn't. And now you are trying to move from branch YYY to XXX. Git is afraid that you just forget to add file so it doen't allow to move to another branch.
Use
git status
to determine whether this file (Form1.Designer.cs) is untracked. In this case just commit it and then you can safely move to another branch
First of all, Git is not lying to you. The file really is tracked in the branch, and really does exist in the work tree, and really is untracked.
Given that you suggest in comments elsewhere that the file doesn't show up in diffs or even git status
, it sounds like you've added it to your gitignore (maybe unintentionally via a wildcard pattern). I know you said you didn't, but if it doesn't show up in the output of git status
as an untracked file, then it's untracked and ignored. To verify this, you can list all files ignored by .gitignore:
git ls-files -i --exclude-from=.gitignore
You can also list all untracked files, ignored or not:
git clean -xdn
(You seem to say that you're very sure the file is tracked - if it really were, git show HEAD:path/to/file
would show the committed contents of the file. I suspect, however, that that will instead tell "fatal: Path 'path/to/file' does not exist in 'HEAD'".)
Another way to verify that the file is untracked and ignored is simply to rename it, then see if git status
reports it as deleted; if it doesn't, it wasn't tracked.
Assuming this does list the file in question, you should examine the file in your work tree. You can see what version of the file the other branch has using git show other-branch:path/to/file
, to compare. If you're satisfied that you don't need the version in your work tree, simply remove it. If you're worried you might need it, rename it or move it out of the directory. If you realize you do need it, you should figure out what ignore pattern is ignoring it, remove that, add it, and commit it. In any case, once you've dealt with the file, you'll be able to switch branches.
This solved the problem for me:
rm .git/fs_cache