3

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?

Kaivosukeltaja
  • 15,541
  • 4
  • 40
  • 70
  • 1
    This can be interesting: http://stackoverflow.com/questions/11005688/git-status-shows-modifications-even-with-autocrlf-false – Lajos Veres Oct 30 '13 at 15:12
  • Try to delete the files, and then run `git reset --hard HEAD`. Do they still appear as modified? – Pedro Rodrigues Oct 30 '13 at 18:20
  • @PedroRodrigues: Yes, they do. Before reset they appear as deleted, after resetting they turn back to modified. – Kaivosukeltaja Oct 31 '13 at 10:11
  • @Kaivosukeltaja: a few questions: 1) are the differences only on the EOF characters? Does `git diff -w` outputs nothing? 2) Have you made any configurations in you .gitconfig or .gitattributes that influence EOF? 3) Removing the index `rm .git/index` and the offending files, and then `git reset --hard HEAD` still won't help? – Pedro Rodrigues Oct 31 '13 at 10:42
  • Also try `git diff -b` to see if you only have whitespace changes. – Mark Leighton Fisher Mar 28 '14 at 20:48

1 Answers1

1

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 status, 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.

David Deutsch
  • 17,443
  • 4
  • 47
  • 54