LF is one newline byte (\n); CRLF is two (\r\n). A shell script with CRLF can fail on Linux with an invisible ^M in the interpreter path. The durable fix is repository policy, not asking every editor to guess correctly.
Put the policy in .gitattributes
* text=auto eol=lf
*.bat text eol=crlf
*.png binary
| File type | Usually choose | Reason |
|---|---|---|
| Shell, YAML, Dockerfile | LF | Linux tooling expects it |
| Windows batch files | CRLF | Windows command interpreter convention |
| Images and archives | Binary | Never newline-normalise them |
Diagnose the actual bytes
file scripts/deploy.sh
git ls-files --eol scripts/deploy.sh
The second command shows index and working-tree line endings. It is more useful than a diff that appears to change every line.
core.autocrlfis a user-level convenience setting, not a substitute for a checked-in.gitattributespolicy shared by CI and every contributor.
After adding attributes, renormalise deliberately and review the resulting diff:
git add --renormalize .
git diff --cached --stat
Do it in its own commit when possible. That keeps a real code change from being buried under a thousand newline-only changes and stops line ending churn from returning on the next Windows checkout.
