Recently, our team at work stumbled upon a strange behavior in their Git projects: there were files with Windows CRLF line endings checked into the git repository. If you know git, you’re aware of the line ending settings and that line endings basically should never be an issue. Well, turns out: it is, and it is quite often.
How it should work
While investigating the issue, I found the excellent Mind the End of Your Line article over at adaptivepatchwork.com, which explains how line endings should be handled in the first place. It also helped me find the cause of the issue, so props to them!
The most important bit in this case is the core.autocrlf
setting. As every git setting, it can be specified per-repository or globally (per OS user). On Windows, it seems to be recommended setting it to true
, causing git to use Windows CRLF in the workspace and auto-converting line endings to LF when committing to git’s object database. Going with the input
setting also shouldn’t cause too much trouble: in this case, git checks line endings out into the workspace as they are in the object database without changing them, but still makes sure to replace any Windows CRLF line endings with linux LF when committing to git’s object database.
The only core.autocrlf
setting to avoid at all cost, at least on windows, is false
. This would cause git to commit line endings into its object database exactly as they appear in the workspace (the only setting letting Windows’ CRLF into git’s object database).
Our setup
We are mostly dealing with java projects, but our repositories contain a bunch of shell scripts for automation, testing and stuff like that. Our development machines are Windows workstations while test and production servers are linux/unix. We use Eclipse along with its egit plugin for development.
The symptom
I once had to merge a huge feature branch. After resolving merge conflicts and committing my changes, I noticed that pushing the merge took longer than usual. Also, the git repository had nearly doubled in size. It turned out that my merge just changed every single text file’s line endings to Windows CRLF in the repository.
I fixed it by resetting everything to linux LF line endings. However, after a couple of months, we noticed that Windows line endings were slowly crawling back into the repository – apparently cumulating through multiple developers’ commits and merges over time.
Pinpointing the problem
This turned out to be a nightmare. It took an awful lot of time to reproduce the problem, let alone find a logical explanation to why this kept happening.
Whenever I ran git config core.autocrlf
in a repository, it always yielded the expected input
, so I didn’t suspect the autocrlf option and didn’t care that git config --global core.autocrlf
wasn’t set. I ended up creating a test git repo and running a bunch of merges with intentional conflicts before I was able to pinpoint the exact constellation causing the problem:
As it turns out, it is a combination of the git spec, the windows git command-line and Eclipse’s egit plugin causing the issue.
- The git documentation states that settings are either found in the current repository’s
./.git/config
file or the global%HOME%.gitconfig
, the latter being the fallback if they’re not found in the former. It also specifies that the default value for thecore.autocrlf
setting isfalse
– remember? the worst setting there could be on Windows if line endings matter… - The Windows git client (from git-scm.com) does ask for the
core.autocrlf
setting during setup to make sure you have it set, but it doesn’t seem to store it in the documented global location (%HOME%.gitconfig
). Instead, it seems to store it somewhere else (I haven’t found where though) and uses this location as ultimate fallback during command-line git invocations when the setting isn’t found in the usual locations. As long as you only ever use the command-line git, you’re fine, however… - Eclipse’s egit plugin doesn’t use the command-line git client directly but comes with its own implementation, which does honor the documented locations and settings. However, as the “magical ultimate fallback” used by the Windows git command-line client seems to be undocumented, Eclipse couldn’t possibly know about it. So from Eclipse’s point of view: No
core.autcrlf
in the repository, nocore.autocrlf
in%HOME%.gitconfig
: use the default value:false
. If you then happen to commit merges, or even worse, if you previously cloned a repository withcore.autocrlf
set totrue
, your Eclipse will end up committing everything with Windows line endings while your command-line git behaves perfectly fine.
I checked with some colleagues from other teams and they also had the global core.autocrlf
setting unset – and incidentally, their Eclipse was behaving strangely in the git synchronize view. After they set the global setting, everything was fine. So it looks like manual action is needed to make it work correctly.
Oh, and to make things even worse: I currently suspect something to overwrite my %HOME%.gitconfig
, removing the core.autocrlf
setting as it magically disappeared somewhere in the last weeks. I’m not quite sure what it is tough…
In conclusion, TL;DR
If you use Eclipse and Git on Windows, make sure you have the core.autocrlf
option globally set to true
AT ALL TIMES!
To check for the option:
git config --global core.autocrlf
(this should yield true
).
To set it:
git config --global core.autocrlf true
May this post help other poor souls like me! 😉
– Cheers!
When I set core.autocrlf true i get the absolute opposite of what you say. When I “git add” a file I get the warning:
warning: LF will be replaced by CRLF in x/x/x/application.properties.
The file will have its original line endings in your working directory.
Obviously this is NOT what we want.
LikeLike
Thanks a lot it works
LikeLike
The windows git client is storing the config in C:\ProgramData\Git which is the windows equivalent of /etc
LikeLike
Thank you for this excellent post, you saved me a lot of time!
LikeLike
Oy,
I had a strange issue with git where,
my local file got carriage return
The remote file got carriage return
On my git staging view, I had carriage return in both version
But when I push the file, they’re all gone
I was able to fix it by using command line to git add/commit
BUT thanks a lot to this post, I’ve also tried to add the autocrlf at project level, and it fix the Eclipse commit issue !
I dont know if its the same issue as all the other settigns already had it, but this helped me to figure out it was something about git config 🙂
LikeLike