In Linux, lines end with LF (Line Feed,
\n), while in Windows, CRLF (Carriage Return + Line Feed,
\r\n). When developers using different operating systems contribute to the same Git project, line endings must be handled correctly, or
merge may break unexpectedly. Git provides several solutions to this problem, including configuration options and file attributes.
input in Windows. Leave Linux/macOS unchanged.
git config --global core.autocrlf input
.gitattributes under the project root, and add the following line:
* text=auto eol=lf
I suggest using LF in all OSes. Modern editors are capable of recoganizing and handling line endings across platforms. Even Notepad in Windows 10 can display text files with LFs correctly. Usually we have an
.editorconfig file in the project, so that various editors with plugin installed will behave the same when handling line endings, as well as charset and indent.
root = true
This consistency also lies in Git itself. When you enable Git to handle line endings for you, either by
.gitattributes, Git always stores LFs in the repository.
core.autocrlf has three options:
falseThe default value, meaning Git will not touch the files when checking in or out of the repository. Check-in means committing files to the repository; check-out means writing to the working directory.
trueGit will convert LF to CRLF when checking out of the repository, and convert them back to LF when checking in.
inputGit checks out the files as-is, and converts CRLF to LF when checking in.
core.autocrlf is set to
input, Git will give you a warning when adding text files with CRLF endings:
warning: CRLF will be replaced by LF in test.txt.
Only text files will be processed by Git, but sometimes Git may mistakenly treat binary files as text files and corrupt the data by replacing CRLF with LF. So Git provides a
core.safecrlf option that checks if it can convert LF back to CRLF and produce the exact same file content. If it is not the case, Git rejects this operation with an error:
fatal: LF would be replaced by CRLF in test.bin
This setting also causes problem when you have a mixture of LF and CRLF in one file, because Git will detect that it cannot reproduce the original file when checking out. In this case, line endings need to be fixed manually.
There are two caveats in the
core.autocrlf approach. First, it is a configuration that needs to be set manually by every developer, either globally or locally. Second, it may corrupt binary files. So newer version of Git provides the attribute mechanism, that saves configurations into a file named
.gitattributes, and just like
.editorconfig, this file should be checked into the repository so that all developers may share the same config. Git attributes also support path wildcards, so users can specify which files should be processed as text files. For instance:
# Auto detect file types, if no further configs are given. Set end-of-line to LF.
binary is a macro for
-text -diff, meaning Git will not process this file as text files or generate diffs in
git diff. Git attributes take precedence over the
core.autocrlf config, and will fall back to it when file does not match the wildcards.
Another related config is
core.eol, which only takes effect if a file has the
text attribute. Consider it as the default value for
.gitattributes, but obviouly it should not be used since it is also a config that needs to be set manually.
More details on Git attributes can be found in the official document.
For existing projects, there is a command that normalizes line endings for all files.
git add --renormalize .