6

I don't think it's a line ending difference issue - p4merge does not think anything has changed in the file, even when set to recognize line ending and white space differences.

My issue is that sometimes the following happens:

  • At first git status shows no uncommitted changes.
  • Then I checkout another branch
  • Now git status lists some files as changed.
  • git diff on any of those "changed files" shows every line of the file as changed. The changed version appears the same as the original version.

Why is this happening? Why does git think the files have changed, when they appear to not have done that? Why does just checking out another branch cause this?

My first thought was line endings, but I don't know why p4merge would not detect those. Second idea was file mode changes. I don't know how to find out if that's the case. git config --list shows core.filemode is set to false. git config --global --list and git config --system --list don't show any setting for core.filemode (I tell this here since I'm not sure how different config levels override each other). core.autocrlf is set to true.

Multiple developers commit to the same repository I'm pulling changes from, all on Windows machines. I'm guessing someone somewhere has some setting in a position that's causing this, but I don't know if it's me locally or someone else, or what setting it could be.

The files listed as changed don't appear to be random - if I delete my local repository, clone it again from the remote (which defaults to master branch being checked out), and checkout that same branch again, git status lists the exact same files as changed, every time. The files are sometimes something recently edited, sometimes files that have not been touched in years. They are also not only binary files (that core.autocrlf=true is known to corrupt at times), but text files as well.

Doing commands git rm --cached -r . followed with git reset --hard gets rid of the changes, but it's occurring so often it's getting bothersome. I'm also curious what could be causing this.

Same repository is also causing line ending problems. I think this is a separate issue, so I'll probably end up making another question for it, but I mention it here briefly in case it's related after all. Checking out another branch or pulling changes from remote repository sometimes causes files appear as changed, and git diff on those files only outputs warning: LF will be replaced by CRLF in [file]. The file will have its original line endings in your working directory.

Edit: The .gitattributes file of the repository has only the line * text=auto and nothing else in it.

Output of git config --list (ommitted settings with things like colors, file paths to editor, remote, difftool, user name and email and such):

core.symlinks=false
core.autocrlf=true3
pack.packsizelimit=2g
rebase.autosquash=true
merge.summary=true
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false (yes this is there twice, just noticed)
core.ignorecase=true
core.hidedotfiles=dotgitOnly
riksteri
  • 83
  • 1
  • 2
  • 7
  • What does `git config core.autocrlf` returns in your cloned repo? Is there any `.gitattributes` with `core.eol` directives in them? – VonC Dec 12 '14 at 06:43
  • 1
    Are you working on Windows as well as the other developers? It sounds like ^M or some other Windows centric characters are making it into the files. – Jeff Panici Dec 12 '14 at 06:44
  • @VonC `git config core.autocrlf` outputs `true`. `.gitattributes` does not have anything about `core.eol` in it. @Jeff Yes, I am working on Windows, just like every other developer. It now occurs to me though that the repository has several years of history in it, and developers have come and gone. I do not know if at some point in the past someone worked on some other platform (all Windows at least the past year, though, and this issue started only several months ago). – riksteri Dec 12 '14 at 07:26
  • Can you try to clone again, but before the clone: `git config --global core.autocrlf false`. And see if the issue persists. – VonC Dec 12 '14 at 07:29
  • Could it be whitespace (tabs/spaces)? Try a Git history viewer that allows you to turn off whitespace when showing the diff view. – nwinkler Dec 12 '14 at 07:29
  • @VonC I can try that next time the issue occurs. Right now it's not happening, probably will need to wait until someone else pushes something causing the issue again. Even if it makes the problem go away, I still don't think I could leave the `core.autocrlf` setting to `false`. I'd like to understand why this is happening. – riksteri Dec 12 '14 at 07:57
  • 1
    It is happening because core.autocrlf is set to true. I have been advocating to leaving it to false for years now. http://stackoverflow.com/a/2354278/6309. – VonC Dec 12 '14 at 08:11
  • @JeffPanici Seemslike you're on the right track, `git diff --word-diff-regex=.` does show that ^M has been removed from the end of each line. – riksteri Dec 12 '14 at 08:55
  • @riksteri which is precisely what I recommend setting core.autocrlf to false all along! – VonC Dec 12 '14 at 09:02

1 Answers1

10

To show such "invisible" changes in details use:

git diff --word-diff-regex=.

This will mark all changed characters, even whitespace.

Most probably it will show a change in line endings. If you are working on Windows and turned on core.autocrlf, git might expect the other kind of line ending and show the "wrong" line ending as diff.

Telling git to not care about line endings by turning off core.autocrlf should fix your issue.

michas
  • 25,361
  • 15
  • 76
  • 121
  • This does show that apparently ^M character has been removed from each line. Thanks for this! Not solved what's causing this yet, but seems like a lot closer to a solution now. – riksteri Dec 12 '14 at 08:52
  • You told git to always store files with native (i.e. windows) line endings. However the file contains unix line endings. Therefore git assumes you removed the "^M" character, which exactly is the difference between both line endings. – michas Dec 12 '14 at 08:59
  • So is this caused by some developers having `core.autocrlf` set on and others off, so unexpected line endings get committed to the database? If everyone had it at the same setting all the time would this still be a problem, regardless of the chosen setting being on or off? Also, I understand this can be fixed by adding appropriate settings to `.gitattributes`, to prevent us having to set `core.autocrlf` to suitable setting for each and every developer. Is that correct? – riksteri Dec 12 '14 at 09:55
  • @riksteri I'd say "it depends" - for some files you actually want to have specific line endings (say \n for .sh files, \r\n for bat files), for others you have to decide on a policy. If you choose a specific policy and enforce it, then it is correct to say that this is caused by lack of .gitattributes. However your needs impact on what is the best setting. – eis Dec 12 '14 at 11:47
  • As a note, I expect this answer to be correct, and will mark it as such as soon as I see the fix working in action. I expect it to take until next week before I get the chance to apply and test the fix. – riksteri Dec 12 '14 at 11:51
  • 1
    I had similar problems; the conclusion I came to was that the best way is to stop git from doing any "magic" line ending normalization by turning it off in .gitattributes (so that it is controlled by the repo, and is not dependent on whatever settings individual developers may have in their .gitconfig.) See my answer to my own post: http://stackoverflow.com/questions/24577629/git-line-endings-after-normalization – Philip Daniels Dec 12 '14 at 12:12
  • @riksteri - did this answer turn out to be the correct answer? – Eljay Aug 28 '17 at 14:21