This is essentially a follow-up to the question asked here about the difference between * text=auto and * text=auto eol=lf in a .gitattributes config: What is the difference between "* text=auto" and "* text=auto eol=lf"?
I think I understand how Git works, but I'd like confirmation because the docs are confusing.
The docs for the text attribute state:
This attribute enables and controls end-of-line normalization. When a text file is normalized, its line endings are converted to LF in the repository. To control what line ending style is used in the working directory, use the eol attribute for a single file and the core.eol configuration variable for all text files. Note that setting core.autocrlf to true or input overrides core.eol (see the definitions of those options in git-config[1]).
So it sounds like Git enforces LF by default if you use * text=auto, making * text=auto eol=lf redundant.
However, the second bolded part of the quote is what's confusing me: Does Git ever respect core.autocrlf or core.eol? I tested this on a Windows machine using PowerShell and Git 2.16.1:
- Run
git config --global core.autocrlf falseandgit config --global core.eol crlf. The latter is not what you'd usually want, but it's useful for this experiment to see if Git even picks it up at all. - Create a text file using Notepad with multiple lines of content. The file should have
CRLFline endings. - Initialize a Git repo in the same directory.
- Add the file to Git's index.
- Run
git ls-files --eoland observe that the file hasCRLFin both the index and working tree. - Add a
.gitattributesfile with* text = auto. Commit it. - Run
git add --renormalize .to renormalize the previously committed file. - Run
git status. Observe that the file has been staged for commit. - After committing the file, run
git ls-files --eolto observe that the file now usesLFin the index.
So despite me setting core.eol=crlf and turning off core.autocrlf, Git still enforced LF for line endings.
Question: Are the docs misleading? Will text=auto always enforce LF?
I think I figured it out:
core.autocrlfandcore.eolonly impact line endings in the working tree, not in Git's index (which will always useLFwhen normalization is enabled) or the remote copy of your code. Hence the output ofgit ls-files --eol.The
eolattribute in.gitattributesimpliestext, which means it enforcesLFin the index and whatever value you've set foreolin the working directory. Example:eol=crlfimpliesindex = LFandworking tree = CRLF.So the docs are slightly misleading in that
text=autodoes NOT rely oncore.autocrlforcore.eol—it always enforcesLFline endings for the index. Line endings in the working tree are left as-is unless you configurecore.autocrlf,core.eol, or use theeolattribute.