Changes in git working directory refuse to be reverted
I have five files in my git working directory that
git status shows as modified. When I
git diff them, the whole file shows as changed. I have
core.autocrlf true but it seems to have no effect.
The real problem surfaced when I tried to pull changes from a colleague. One of the “modified” files would have been overwritten by the merge so I stashed them. To my surprise, the changes were still there.
[dev@carbon:/var/www/html/ourcustomer]$ git stash Saved working directory and index state WIP on master: ccb93db Merge remote branch 'origin/master' HEAD is now at ccb93db Merge remote branch 'origin/master' [dev@carbon:/var/www/html/ourcustomer]$ git status # On branch master # Changed but not updated: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: src/ourcustomer/SiteBundle/Resources/public/css/main.css # modified: src/ourcustomer/SiteBundle/Resources/public/js/main.js # modified: src/ourcustomer/SiteBundle/Resources/public/js/ourcompany-resize.js # modified: src/ourcustomer/SiteBundle/Resources/views/Login/languageSelector.html.twig # modified: src/ourcustomer/SiteBundle/Resources/views/layout.html.twig # no changes added to commit (use "git add" and/or "git commit -a")
After this, I tried
git reset --hard HEAD – same result. I also tried to
git checkout -- src/ourcustomer/SiteBundle/Resources/public/css/main.css, but it didn’t help either.
What could be wrong here? Is there some way to fix this or should I just delete and clone the whole repository again?
One Solution collect form web for “Changes in git working directory refuse to be reverted”
My best guess as to what is happening is that you are on a Windows machine, and that somewhere in your
.gitattributes file you have a directive that tells git to perform line ending normalizations (via
* text=auto or something similar). If this is indeed the case, then when you checkout a file its LFs are converted to CRLFs, and when you commit a file its CRLFs are converted to LFs.
If this is indeed the case, then what is most likely happening is that the repository version of the files in question somehow have CRLFs in them. When you check them out, the working copies would of course also have those CRLFs. Now here’s the rub: when doing a
git diff, etc. git compares what is in the repo/index not to what is actually in your working directory, but to what would be committed after line ending normalization is done, i.e. with the CRLFs replaced by LFs. In this case, git sees that what is in the index/repo has CRLFs, and what you would commit only has LFs, and thus there is a difference.
To see if this is the case, run the following commands:
git hash-object src/ourcustomer/SiteBundle/Resources/public/css/main.css git hash-object --no-filter src/ourcustomer/SiteBundle/Resources/public/css/main.css git ls-files -s src/ourcustomer/SiteBundle/Resources/public/css/main.css
The first command will show you the hash of what would be committed. The second command shows you the hash of what is actually in your working directory. The third command shows you the hash of what is in the index. If the first and second hashes are different, and the second and third hashes are the same, you are almost definitely in the situation I have described.
So the question is, how to get out of it? One simple way is to simply add/commit the “changes”. This will have the effect of putting LFs in the repository copy, solving the problem going forward. If everyone using the repository is on Windows, however, there is really no need for the line normalizations anyway. You can disable them by putting
* -text in your
.gitattributes file (and removing any lines below it that sets the type of a file to text). That’s the option I chose when I ran into this problem, as I’m not a fan of my version control system changing the contents of my files.