Setup & configAlways fixable

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.

quick fix
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

  1. Confirm line endings are the cause

    If the diff disappears when whitespace is ignored, the change is invisible characters rather than real edits.

    step 1
    git diff | cat -A | head -20      # ^M at line ends means CRLF
    git diff --ignore-all-space         # empty? then it is purely line endings
    
    Show the PowerShell (Windows) version
    PowerShell (Windows)
    git diff --ignore-all-space
    git config core.autocrlf
    
  2. Add 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 binary
    

    text=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.

  3. 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 3
    git add .gitattributes
    git commit -m "Add line-ending policy"
    
    git add --renormalize .
    git status
    git commit -m "Renormalise line endings across the repository"
    
  4. 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 input
    

    Never use core.autocrlf true on macOS or Linux - it writes CRLF into files that should have LF.

  5. Refresh your working copy

    After renormalising, re-check out the tree so every file on disk matches the new policy.

    step 5
    git 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

.gitattributes

Per-path rules for line endings, diffing, merging and export.

git config

Read and write Git settings for one repo, your user, or the whole machine.

git add

Stage changes so they go into your next commit.

git diff

Show 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

← All Git Rescue guides