Fix line-ending problems that show every file as modified
git status says every file changed but I didn't touch them — how do I fix line endings?
Short answer
Windows writes CRLF and Unix writes LF, and without a policy Git records whichever your editor produced. Commit a .gitattributes with `* text=auto`, then renormalise the repository once — this fixes it for everyone, unlike the per-machine core.autocrlf setting.
printf "* text=auto\n" > .gitattributes
git add --renormalize .
git commit -m "Normalise line endings"
Set a repo-wide policy and renormalise every tracked file
Does this match your situation?
- git status shows files as modified with no visible change.
- git diff shows every single line as changed.
- 'warning: LF will be replaced by CRLF' on every add.
- Shell scripts fail with 'bad interpreter' or '\r: command not found'.
Step-by-step fix
Confirm line endings are the cause
If the diff disappears when whitespace is ignored, the change is invisible characters rather than real edits.
step 1git diff | cat -A | head -20 # ^M at line ends means CRLF git diff --ignore-all-space # empty? then it is purely line endingsShow the PowerShell (Windows) version
PowerShell (Windows)git diff --ignore-all-space git config core.autocrlfAdd a .gitattributes policy
Because .gitattributes is committed, it applies identically for everyone who clones — which is exactly why it beats core.autocrlf, a per-machine setting that different teammates inevitably have set differently.
step 2# .gitattributes * text=auto *.sh text eol=lf *.bash text eol=lf *.bat text eol=crlf *.cmd text eol=crlf *.ps1 text eol=crlf *.png binary *.jpg binary *.fbx binary *.wav binarytext=auto stores LF in the repository and checks out whatever is native to each machine. eol= pins files that must have a specific ending regardless of platform.
Renormalise everything already committed
The new rules only affect future writes until you rewrite the existing entries. This produces one large commit that touches many files and is best done when nobody has work in flight.
step 3git add .gitattributes git commit -m "Add line-ending policy" git add --renormalize . git status git commit -m "Renormalise line endings across the repository"Set a sensible local default too
A belt-and-braces default for repositories that have no .gitattributes of their own.
step 4# Windows git config --global core.autocrlf true # macOS / Linux git config --global core.autocrlf inputNever use core.autocrlf true on macOS or Linux - it writes CRLF into files that should have LF.
Refresh your working copy
After renormalising, re-check out the tree so every file on disk matches the new policy.
step 5git rm --cached -r . git reset --hard
Why this works
Git stores file contents byte for byte, so a carriage return is as much a change as a letter. Windows tools write CRLF and Unix tools write LF, which means the same logical edit produces different bytes on different machines and Git honestly reports every line as changed. `text=auto` resolves this by normalising to LF inside the repository and converting on checkout, so the stored form is consistent no matter who committed it. Putting the rule in .gitattributes rather than local config is what makes it a team-wide guarantee instead of a per-machine hope.
How to stop it happening again
- Add .gitattributes with `* text=auto` to every new repository on day one.
- Pin shell scripts to eol=lf and Windows batch files to eol=crlf.
- Configure your editor to respect .editorconfig alongside it.
Commands used in this guide
.gitattributesPer-path rules for line endings, diffing, merging and export.
git configRead and write Git settings for one repo, your user, or the whole machine.
git addStage changes so they go into your next commit.
git diffShow exactly what changed - between your files, the index, commits or branches.
Still stuck?
Search the full command reference and every other rescue guide — there are 56 of them, covering everything from detached HEAD to force-push disasters.
Browse all guides →Frequently asked questions
Why does Git show every file as modified after I clone on Windows?
Your files were committed with LF endings and your setup is writing CRLF (or vice versa), so every line differs at the byte level. A .gitattributes with `* text=auto` plus a one-off git add --renormalize . fixes it permanently for the whole team.
Should I use core.autocrlf or .gitattributes?
.gitattributes. It's committed, so every contributor gets identical behaviour automatically. core.autocrlf is a per-machine setting, which means one teammate with a different value reintroduces the churn.
What does 'warning: LF will be replaced by CRLF' mean?
Git is telling you it will convert line endings when writing the file to your working directory, because core.autocrlf is true. It's informational, not an error - and it disappears once a .gitattributes policy makes the behaviour explicit.
Related rescue guides
I renamed a file's case and Git won't notice — how do I fix it?
Windows and macOS filesystems treat Player.cs and player.cs as the same file, so a case-only rename is invisible to Git. Use git mv -f to force it, or rename via a temporary name, then commit — otherwise the wrong case ships to your Linux CI and the build breaks.
Read the fix →Always fixableGit says files changed but only the mode differs — how do I ignore that?
Git tracks the executable bit, so a file going from 100644 to 100755 counts as a change. Set core.fileMode false to ignore mode differences, or fix the bit properly with git update-index --chmod when it genuinely matters.
Read the fix →Always fixableWhy is .gitignore not working for files that are already tracked?
.gitignore only applies to untracked files. Once a file has been committed, Git keeps tracking it no matter what the ignore rules say. Remove it from the index with git rm --cached <file> — that stops tracking while leaving the file on your disk.
Read the fix →Always fixableGit says I have merge conflicts — how do I fix them?
Git pauses and marks the clashing sections with <<<<<<<, ======= and >>>>>>>. Edit each file to the version you actually want, delete the markers, git add the file, then git merge --continue. If it gets overwhelming, git merge --abort returns you to exactly where you started.
Read the fix →