Coding Agents & Terminal · recorded 2026-08-29 · applies to 1 tool(s) ✓ Verified

Problem: One-line change shows the whole file as modified (line-ending chaos: LF/CRLF) —— Trove problem library

Verified 2026-08-29git line-ending chaos — add .gitattributes (* text=auto eol=lf) at repo root and `git add --renormalize .` once and for all.

Quick fix

# One-liner: add .gitattributes at the repo root and renormalize (one-time permanent fix)
printf '* text=auto eol=lf
' > .gitattributes && git add .gitattributes && git add --renormalize . && git commit -m "normalize line endings"

Afterwards git ls-files --eol should show i/lf w/lf.

What you will run into

Changing one line makes git diff mark the entire file as modified (every line red+/green-); git add prints warning: LF will be replaced by CRLF (or the reverse CRLF will be replaced by LF); the same repo checked out on Windows and Linux/WSL looks "the same" but the diff never cleans up;

scripts cloned on Windows fail with ` `-related execution errors. Line-ending policy isn't unified.

Why this happens

Windows text defaults to CRLF (\r\n), Linux/macOS to LF (\n). git's core.autocrlf controls conversion, and what ends up in the repo depends on each person's config at first commit:

ConfigBehaviorBest for
autocrlf=falseNo conversion; CRLF goes into the repo as-isOld Windows default — the pitfall source for cross-platform repos
autocrlf=trueLF on commit, CRLF on checkoutWindows recommended
autocrlf=inputLF on commit, no conversion on checkoutLinux recommended

With everyone configured differently, CRLF/LF gets mixed into the repo — that's the source of "whoever commits, steps on the landmine". warning: LF will be replaced by CRLF itself is harmless, but its appearance means the line-ending policy isn't unified.

Line-ending conversion happens in two directions. core.autocrlf controls "convert CRLF to LF on commit, and convert back on checkout according to the config".

The conversion only rewrites bytes in the text stream; it does not detect file types. That is why binary files can be mangled under autocrlf=true — .gitattributes -text is the escape hatch.

What ends up in the repo depends on each committer's own config: someone with autocrlf=false commits CRLF as-is, someone with autocrlf=true converts to LF — the repo ends up with mixed bytes, and git diff shows whole-line changes.

Deterministic takeaway: the LF will be replaced by CRLF warning means conversion happened on checkout — the config is in effect but the policy is not unified.

Cross-platform repos should write the policy into the repo itself via .gitattributes (* text=auto plus explicit declarations like *.sh text eol=lf), not rely on per-machine local config — config is per-machine, attributes travel with the repo.

Step by step

1. When the symptom is harmless (just a warning, diff is clean) — Required

Make the whole team's core.autocrlf consistent (Windows true, Linux/mac input); the warning disappears.

2. Diff all-red / already mixed into the repo (recommended, permanent) — Required

Add .gitattributes at the repo root:

* text=auto eol=lf

Then renormalize (converting every CRLF already in history to LF):

git add .gitattributes
git add --renormalize .
git commit -m "normalize line endings"

3. Manage only specific types — Required

Write *.sh text eol=lf, *.bat text eol=crlf etc. in .gitattributes, leave the rest alone.

4. Avoid repeating it — Required

For new repos, commit .gitattributes (* text=auto) at the root before adding content; don't use autocrlf=false as the default for cross-platform repos (that stores CRLF into the repo).

How to confirm it works

Repo format is unified (measured output shape):

git ls-files --eol → all i/lf w/lf, no warnings
git diff → only real changes shown (adding 1 line reports 1 insertion, measured)

Other environments

EnvironmentNotes
Windowsautocrlf=true (LF on commit, CRLF on checkout)
Linux/macautocrlf=input
Already mixed into repo.gitattributes + git add --renormalize . (measured fix)
Specific files*.sh text eol=lf, *.bat text eol=crlf
New reposCommit .gitattributes before adding content

Symptom

  • You change one line, but git diff marks the entire file as modified (every line red+/green-);
  • git add prints warning: in the working copy of 'xxx', LF will be replaced by CRLF the next time Git touches it (or the reverse CRLF will be replaced by LF);
  • The same repo checked out on Windows and Linux/WSL looks identical but diff never gets clean;
  • Scripts (.sh/.py) cloned on Windows fail with \r-related execution errors (CRLF leaked into the script).

Key traits: plain-text files; the message mentions line endings; repos collaborated on across Windows/Linux hit it most.

Cause

Windows text defaults to CRLF (\r\n), Linux/macOS to LF (\n). core.autocrlf controls conversion, and what actually gets stored depends on each committer's config:

  • autocrlf=false (old git default on Windows, many outdated tutorials): no conversion at commit — CRLF gets stored directly in the repo, and any LF working copy diffs as all-lines-changed;
  • autocrlf=true (recommended on Windows): commit converts to LF, checkout to CRLF;
  • autocrlf=input (recommended on Linux): commit converts to LF, checkout stays LF.

When teammates use different settings (Windows false + Linux input/false), CRLF and LF end up mixed in the repo — whoever commits next hits the mess. The warning itself is harmless (git is just telling you it will convert), but its appearance means the line-ending policy isn't unified.

Solution

  1. Warning only, diff clean: unify core.autocrlf across the team (Windows true, Linux/mac input); the warning disappears.
  2. Diff all-red / already mixed (recommended, one-time fix): add a root .gitattributes:
   * text=auto eol=lf

then renormalize (convert all stored CRLF to LF):

   git add .gitattributes
   git add --renormalize .
   git commit -m "normalize line endings"

Afterwards git ls-files --eol should show i/lf w/lf (both index and worktree LF).

  1. Per-type control: .gitattributes entries like *.sh text eol=lf, *.bat text eol=crlf, leave the rest untouched.
  2. Prevention: commit .gitattributes (* text=auto) at repo root BEFORE adding content; don't use autocrlf=false as the default for cross-platform repos (it stores CRLF in the repo).
Verification Evidence
  • Local repro (2026-08-29, WSL Ubuntu, git 2.53.0):
  • Repro 1 (diff all-red): committed a CRLF file with autocrlf=false (git ls-files --eol shows i/crlf w/crlf) → changed worktree to LF → git diff shows 2 lines as 3 deletions + 2 additions (every line changed);
  • Repro 2 (warning forward): with autocrlf=true, adding an LF file → warning: in the working copy of 'lf.txt', LF will be replaced by CRLF the next time Git touches it;
  • Repro 3 (warning reverse): with autocrlf=input, adding a CRLF file → warning: ... CRLF will be replaced by LF ...;
  • Fix: root .gitattributes (* text=auto eol=lf) + git add --renormalize . → all stored files become i/lf w/lf, no warnings;
  • After fix, diff shows only the real change (1 insertion for 1 added line).

Evidence details kept locally (2026-08-29)

Applicable tools (1)

This problem is linked from the tool pages below — reachable from either side.

git

Source & evidence

Recorded Verified ✓ VerifiedApplies to 1 tool(s)
Entries contain locally measured or reviewable-source solutions; unmeasured items are explicitly labeled.

Source: https://github.com/nhkiiim/TIL/issues/6

← Coding Agents & Terminal domain | Problem Catalog Experience | Facing another issue? Go to the Helpdesk