Advent Day 1: gitattributes for Text Files

December 1, 2018

This is day 1 of my Git Tips and Tricks Advent Calendar. If you want to see the whole list of tips as they're published, see the index.

A friend of mine asked to have a quick chat about a git problem that he was having and I knew before he even asked what it was going to be about: line endings.

It's always about line endings.

He'd gotten advice to set core.autocrlf; I've said it before, but it's so important that I want to reiterate: this is always the wrong advice.

The problem with the core.autocrlf configuration option is that it's set on your local repository. This setting isn't checked in anywhere, so you have to rely on everybody who works in your repository to set it, and set it to the same value. If somebody sets core.autocrlf=true and someone else sets core.autocrlf=false then you'll constantly be battling each other, flipping the line endings back and forth from Unix to Windows style each time one of you edits the file.

Instead, you should set the text option in the .gitattributes file at the base of your repository. Don't have one? Create it now. I recommend:

* text=auto

This will turn on automatic text translation for the files in your repository (at least the ones that aren't binaries); when files are checked in to the repository, they'll be normalized to Unix-stye line endings (\n). When files are checked out to the working directory on a Windows machine, they'll be converted to the native Windows-style line endings (\r\n).

If you want to force a particular type of line endings - perhaps you have Makefiles or sh scripts on Windows and these need to have Unix-style line endings to be used. In that case, you can force the files to have Unix style LF endings on all platforms:

Makefile text eol=lf
*.sh text eol=lf

If you're old school and have been using version control systems before git, you might remember that this concept of having your version control system be opinionated about line endings is rather new. And you may not like it. You may also think it's inefficient to perform this translation (it is). Or you may just like Windows-style line endings.

These are all perfectly reasonable opinions, but you still need to enforce these opinions with your .gitattributes so that everybody in your repository has the same opinions. If you want to not perform line ending translation, set up your .gitattributes with:

* -text

This will disable all text translations on your text files.

Although git is somewhat opinionated about keeping files in the repository itself with Unix-style line endings, you can configure how this is saved in your working directory, or even disable this behavior altogether. But whatever you choose to do, please do enforce that behavior with a .gitattributes.