10

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.

ygoe
  • 18,655
  • 23
  • 113
  • 210
  • Do you happen to have a pattern that matches Form1.Designer.cs in your .gitignore or any other ignore configurations? – James Jan 12 '12 at 17:49
  • That file has a green checkmark in Explorer and it has a history as well. So I assume it's not ignored. Also, there are other such Form.Designer.cs files in my project that don't cause any trouble. And this isn't the first Git repository I created with VS2010, until today even a few efforts in branching worked well. – ygoe Jan 12 '12 at 18:12
  • Please double check your ignore filters to see if they changed for that repo or branch. You can still see status and history on a file if it was added before the ignore filter. Anything that uses git status will still report it (like your explorer checkmarks) This can cause the error you're indicating if there really are changes to the file because Git will now ignore that when running the Git status. However Git will still know it changed when trying to do a checkout and give you that error. – James Jan 12 '12 at 20:58
  • Double-checked. No problems found. I have found a workaround hack for now to access my data again. I have cloned the repo into another directory, then switched to the branch in there (it actually worked) and used BeyondCompare to manually(!) switch my original repo and working directory by copying some (not all) files in .git and all differences in the working directory. Until now, git status works reasonable in my hacked version... - (Just in case you're worried: I did make a backup of it all before trying any tip from this page.) – ygoe Jan 12 '12 at 21:21

5 Answers5

27

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.

ygoe
  • 18,655
  • 23
  • 113
  • 210
1

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.

Oleksandr Pryimak
  • 1,561
  • 9
  • 11
  • I have no uncommited change right now. I committed everything before switching to the master branch and I also have committed everything right now, but I cannot switch anywhere. The commit action says I have no uncommitted changes. Does your answer still apply? – ygoe Jan 12 '12 at 17:27
  • @LonelyPixel your comment is confusing. git says that there are some changes. Anyway git stash does nothing on a clean working directory. So it is safe to experiment. – Oleksandr Pryimak Jan 12 '12 at 17:30
  • How is it confusing? Stash says: Stash success - No local changes to save. – ygoe Jan 12 '12 at 17:33
  • So git stash says there is no local changes, git status says that there is no local changes, but git checkout screams about some untracked (why did you say that it is not untracked??)? I think it is untracked in master branch but NOT untracked in form-refactoring branch. – Oleksandr Pryimak Jan 12 '12 at 17:40
  • That file existed in the master branch for a long time. I then created the branch form-refactoring. In that branch, I renamed that file and created a new one with the same name, then committed. But it doesn't seem to matter to Git, it just thinks I have modified that file. So it's always there, in both branches. I just want to get it back. I said it is not untracked, because it is part of both branches, but Git said it would be untracked, which it not true. Is my repository already broken? – ygoe Jan 12 '12 at 17:44
  • @LonelyPixel I think that this file always have been untracked (it is easy to forget to add a new file to commit). I don't think that git can lie. – Oleksandr Pryimak Jan 12 '12 at 17:47
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/6661/discussion-between-alexandr-priymak-and-lonelypixel) – Oleksandr Pryimak Jan 12 '12 at 17:47
  • 'git reset --hard HEAD' does nothing I could see. Also, the new checkout still does not work afterwards. Is there a bug in Git? – ygoe Jan 12 '12 at 18:22
1

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.

Cascabel
  • 479,068
  • 72
  • 370
  • 318
  • 'git ls-files -i --exclude-from=.gitignore' doesn't show anything. Using the real relative path to .gitignore shows "fatal: cannot use ..\.gitignore as an exclude file". 'git show HEAD:path/to/file' shows me the expected content of that file. So it really is checked in. Renaming the file, 'git status' reports the deleted and a new untracked file. Git will also show me the same file from the other branch, but since those files are generated by the VS designer, I can't compare them with my eye. - So can I now safely claim that Git is indeed lying to me? – ygoe Jan 13 '12 at 12:28
  • Well, then it does sound like something has managed to get out of sync or corrupted somehow, if a clone of the repo, with the working tree identical to the original one, works normally. It's a little hard to believe, since this is a fairly well-tested core part of Git, but if you're confident it's a spurious error, you could report it to the Git mailing list. – Cascabel Jan 13 '12 at 15:31
  • It is still kind of broken. :( I could commit to my new repo, and switch back to the master branch, but merging fails for the very same reason. Git believes one of the files it manages is untracked and would be overwritten. Whatever that means. I have reported it to the mailing list, but there's no reply yet. Crashing a repository doesn't seem to be too interesting. – ygoe Jan 13 '12 at 17:17
  • @LonelyPixel: These things take time! The Git folks are good people. (And your problem is difficult, since you don't really know how to recreate it in a new repository.) – Cascabel Jan 13 '12 at 17:26
0

This solved the problem for me:

rm .git/fs_cache
SherylHohman
  • 16,580
  • 17
  • 88
  • 94
Robert Childan
  • 983
  • 1
  • 12
  • 22
-2

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

Oleksandr Pryimak
  • 1,561
  • 9
  • 11
  • As I commented on the other answer, there are no uncommitted changes and that file is really not untracked. I cannot do anything to clean up my working directory any more. – ygoe Jan 12 '12 at 17:48