KhueApps
Home/DevOps/Fix Git LF/CRLF warnings with .gitattributes and autocrlf

Fix Git LF/CRLF warnings with .gitattributes and autocrlf

Last updated: October 07, 2025

What these warnings mean

Git is telling you it will convert line endings between LF (Unix) and CRLF (Windows) based on your settings or attributes:

  • warning: LF will be replaced by CRLF
  • warning: CRLF will be replaced by LF

These appear when adding or checking out files if your line-ending configuration conflicts with the file’s current endings.

Goal: store consistent endings in the repository (usually LF) and define how files are checked out on each platform. Do it with .gitattributes and, if needed, core.autocrlf.

Standardize to LF in the repo, allow CRLF only where required (e.g., .bat files). Avoid relying on core.autocrlf.

  1. Add a .gitattributes at repo root:
* text=auto eol=lf
*.bat  text eol=crlf
*.cmd  text eol=crlf
  1. Ensure Git will not override via autocrlf:
# Per-repo (preferred)
git config core.autocrlf false
# Or globally
# git config --global core.autocrlf false
  1. Renormalize tracked files so Git rewrites working tree endings per .gitattributes:
git add --renormalize .
git commit -m "Normalize line endings via .gitattributes"
  1. Verify:
git ls-files --eol | head
# Expect: i/lf w/lf for most text; i/lf w/crlf where forced

Result: Warnings disappear. The repo stores LF; Windows users get CRLF only for file types you explicitly mark.

Minimal working example

Reproduce a warning and fix it.

# 1) New repo
git init lf-crlf-demo
cd lf-crlf-demo

# 2) Create a text file with LF
echo "hello" > hello.txt

git add hello.txt  # on Windows with core.autocrlf=true you may see: LF will be replaced by CRLF

# 3) Add deterministic attributes
cat > .gitattributes <<'EOF'
* text=auto eol=lf
*.bat text eol=crlf
EOF

git add .gitattributes

# 4) Turn off autocrlf in this repo and renormalize
git config core.autocrlf false
git add --renormalize .

git commit -m "Add .gitattributes and normalize"

# 5) Check endings
git ls-files --eol

Alternative strategies

Pick one model and stick to it across your team.

  • Model A (attributes-first, recommended)

    • Repo: LF via .gitattributes (text=auto eol=lf)
    • Windows-specific CRLF: only for file types that require CRLF
    • Config: core.autocrlf=false everywhere
  • Model B (autocrlf convenience)

    • .gitattributes: minimal normalization
      * text=auto
      *.sh  text eol=lf
      *.bat text eol=crlf
      
    • Windows users: git config --global core.autocrlf true
    • macOS/Linux users: git config --global core.autocrlf input
    • Renormalize after adding attributes: git add --renormalize .

Tip: Use one model per repo to avoid churn.

Step-by-step normalization of an existing repo

  1. Communicate freeze: ask teammates to pause commits briefly.
  2. Add/adjust .gitattributes (pick a model above).
  3. Disable conflicting autocrlf in the repo:
    git config core.autocrlf false
    
  4. Clean and re-checkout (optional but thorough):
    git rm -r --cached .
    git reset --hard
    
    or simply: git add --renormalize .
  5. Commit normalization:
    git commit -m "Normalize line endings"
    
  6. Have all contributors pull and, if needed, rebase to avoid large diffs.

Verifying and inspecting line endings

  • Show index/working-tree EOL: git ls-files --eol
  • Show diffs ignoring EOL: git diff --ignore-cr-at-eol
  • Detect CR bytes in files (Unix): grep -Il $'\r' -n .
  • On Windows PowerShell, spot CRLF: Get-Content file | ForEach-Object { $_ }

Pitfalls to avoid

  • Mixing strategies: core.autocrlf=true on some machines while forcing eol=lf in attributes causes flip-flopping and warnings.
  • Forgetting .gitattributes in submodules: each submodule needs its own policy.
  • Marking binary as text: text=auto may mis-detect rare binaries. Explicitly mark binaries:
    *.png -text
    *.jpg -text
    *.pdf -text
    
  • Renormalizing on a huge branch: expect large diffs. Coordinate and merge quickly.
  • Global overrides: a user’s global core.autocrlf may override expectations. Prefer per-repo config.

Performance notes

  • Renormalization cost: git add --renormalize . scans and reindexes all tracked files. On large repos this is I/O heavy; run once, commit, and avoid churn.
  • Checkout speed: Minimizing conversions (by standardizing to LF and limiting CRLF to needed types) reduces per-file filters during checkout on all platforms.
  • CI efficiency: Set a consistent policy in the repo so CI runners don’t spend time converting endings or producing noisy diffs.
  • Binary files: Mark as -text to skip content checks and avoid unnecessary filter passes.

Small FAQ

  • Q: Can I just hide the warning? A: You can disable it by aligning config with attributes (e.g., core.autocrlf=false and use .gitattributes). Hiding without fixing leads to churn.

  • Q: What does core.autocrlf=input do? A: It converts CRLF to LF on commit (input), but does not change LF to CRLF on checkout. Good for macOS/Linux.

  • Q: Do I need core.eol? A: Rarely. Prefer .gitattributes eol=lf/crlf for per-path control. core.eol is a fallback when attributes are absent.

  • Q: How do I force CRLF for a specific file? A: Add a rule in .gitattributes, e.g., README.txt text eol=crlf, then renormalize and recommit.

  • Q: How do I recover if a commit flipped thousands of files? A: Add proper .gitattributes, renormalize, commit once, and ensure all contributors update and continue from that commit.

By defining line endings in .gitattributes and aligning core.autocrlf, you eliminate LF/CRLF warnings and keep diffs clean across platforms.

Series: Git

DevOps