This error occurs when Git's safecrlf setting detects that committing a file would change its line endings from LF (Unix-style) to CRLF (Windows-style), potentially causing issues in cross-platform projects. The fix involves configuring Git's line ending settings appropriately for your project and platform.
The "LF would be replaced by CRLF" error is Git's safety mechanism preventing accidental line ending changes when you try to add or commit files. This error appears when `core.safecrlf` is set to `true` (or `warn` in some cases) and Git detects that the operation would alter the file's line endings. **Understanding Line Endings:** - **LF (Line Feed, \n)**: Used by Unix, Linux, and macOS - **CRLF (Carriage Return + Line Feed, \r\n)**: Used by Windows - **CR (Carriage Return, \r)**: Used by old Mac systems (rare today) When you have `core.autocrlf` enabled (common on Windows), Git automatically converts line endings: - On checkout: LF in repo -> CRLF in working directory - On commit: CRLF in working directory -> LF in repo The `core.safecrlf` setting adds a safety check. When set to `true`, it prevents commits where the round-trip conversion (checkout then commit) would result in a different file than what's in the repository. This protects against data loss with binary files that happen to contain CRLF sequences. This error typically appears on Windows systems where autocrlf is enabled, and you're working with files that have mixed or LF-only line endings. It's more of a warning about potential line ending inconsistency than a critical error.
Before making changes, check your current Git configuration for line endings:
# Check global settings
git config --global core.autocrlf
git config --global core.safecrlf
# Check local (repository) settings
git config core.autocrlf
git config core.safecrlf
# See all relevant config at once
git config --list | grep -E "(autocrlf|safecrlf|eol)"Typical Windows default values:
- core.autocrlf = true - Auto-convert line endings
- core.safecrlf = true or warn - Safety check enabled
Understanding the values:
| Setting | autocrlf value | Behavior |
|---------|---------------|----------|
| Windows default | true | Convert LF to CRLF on checkout, CRLF to LF on commit |
| Linux/macOS default | input | Convert CRLF to LF on commit, no conversion on checkout |
| No conversion | false | Never convert line endings |
| Setting | safecrlf value | Behavior |
|---------|---------------|----------|
| Strict | true | Error if conversion would change file |
| Warning | warn | Warn but allow the operation |
| Disabled | false | No safety check |
If you need to proceed immediately and understand the implications, you can disable the safety check:
Temporary (for one command):
git -c core.safecrlf=false add file.txt
git -c core.safecrlf=false add .Disable globally:
git config --global core.safecrlf falseDisable for this repository only:
git config core.safecrlf falseWhen is this safe?
- When you're working with text files only
- When you understand that line endings will be normalized
- When your team has agreed on line ending handling
When to be cautious:
- If you have binary files that might contain CRLF sequences
- If you're unsure whether files should be treated as text or binary
The root cause is often the interaction between autocrlf and safecrlf. Configure autocrlf based on your platform and needs:
For Windows users (recommended):
# Convert to CRLF on checkout, to LF on commit
git config --global core.autocrlf true
git config --global core.safecrlf warnFor Linux/macOS users:
# Convert CRLF to LF on commit, no conversion on checkout
git config --global core.autocrlf input
git config --global core.safecrlf warnFor cross-platform projects (recommended approach):
# Disable autocrlf globally and use .gitattributes instead
git config --global core.autocrlf false
git config --global core.safecrlf falseThen use a .gitattributes file (see next step) for explicit control.
To completely disable line ending conversion:
git config --global core.autocrlf falseThis keeps files exactly as they are, but requires your team to be consistent about line endings.
The best practice for cross-platform projects is to use a .gitattributes file at the repository root. This ensures consistent behavior regardless of individual developer's global settings.
Create a .gitattributes file:
# Recommended .gitattributes for most projects
* text=auto
# Explicitly declare text files
*.txt text
*.md text
*.json text
*.xml text
*.yaml text
*.yml text
*.html text
*.css text
*.js text
*.ts text
*.py text
*.rb text
*.java text
*.c text
*.cpp text
*.h text
*.sh text eol=lf
*.bash text eol=lf
# Windows-specific files
*.bat text eol=crlf
*.cmd text eol=crlf
*.ps1 text eol=crlf
# Binary files (never convert)
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.pdf binary
*.zip binary
*.tar binary
*.gz binary
*.exe binary
*.dll binary
*.so binary
*.dylib binaryKey directives:
- text=auto: Let Git detect text files and normalize line endings
- text: Force file to be treated as text
- binary: Force file to be treated as binary (no conversion)
- eol=lf: Force LF line endings (for shell scripts)
- eol=crlf: Force CRLF line endings (for Windows batch files)
After adding .gitattributes, normalize existing files:
# Add the .gitattributes file first
git add .gitattributes
git commit -m "Add .gitattributes for line ending normalization"
# Renormalize all files
git add --renormalize .
git status
git commit -m "Normalize line endings"Sometimes the error occurs because a file has inconsistent line endings. Here's how to fix it:
Check a file's current line endings:
# Using file command (Unix/macOS/Git Bash)
file filename.txt
# Using cat with visible line endings
cat -A filename.txt | head -5
# ^M at end = CRLF, $ at end = LF
# Using xxd to see hex values
xxd filename.txt | head -10
# 0d 0a = CRLF, 0a = LFConvert a file's line endings:
Using dos2unix/unix2dos (if installed):
# Convert to Unix (LF)
dos2unix filename.txt
# Convert to Windows (CRLF)
unix2dos filename.txtUsing sed (Unix/macOS/Git Bash):
# Convert CRLF to LF
sed -i 's/\r$//' filename.txt
# On macOS, use:
sed -i '' 's/\r$//' filename.txtUsing PowerShell (Windows):
# Convert to LF
(Get-Content filename.txt -Raw) -replace "\r\n", "\n" | Set-Content -NoNewline filename-lf.txt
# Convert to CRLF
(Get-Content filename.txt -Raw) -replace "(?<!\r)\n", "\r\n" | Set-Content -NoNewline filename-crlf.txtUsing VS Code:
1. Open the file
2. Click on "CRLF" or "LF" in the bottom status bar
3. Select the desired line ending format
4. Save the file
After changing Git's line ending configuration, you may need to reset and re-add files for the changes to take effect:
For a single file:
# Remove from index (keeps working copy)
git rm --cached filename.txt
# Re-add with new settings
git add filename.txtFor all files in the repository:
# Save any uncommitted changes
git stash
# Remove all files from the index
git rm -r --cached .
# Re-add all files with new line ending settings
git add .
# Check what changed
git status
git diff --cached
# Commit if there are changes
git commit -m "Normalize line endings"
# Restore stashed changes
git stash popUsing renormalize (Git 2.16+):
# More elegant approach - renormalize without removing from index
git add --renormalize .
git status
git commit -m "Normalize line endings"Warning: These commands may show many files as modified if line endings are being normalized. This is expected behavior.
Sometimes Git misidentifies binary files as text and tries to convert their line endings, which can corrupt them. Here's how to fix it:
Symptoms:
- Binary files appear modified after checkout
- Image or executable files don't work after clone
- The safecrlf error appears for files you know are binary
Solution 1: Mark files as binary in .gitattributes:
# Add to .gitattributes
*.dat binary
*.bin binary
myfile.special binarySolution 2: Reset a corrupted binary file:
# Discard local changes and get fresh copy
git checkout HEAD -- filename.bin
# Or from a specific commit
git checkout abc123 -- filename.binSolution 3: Check if Git thinks a file is text or binary:
# This shows how Git classifies the file
git check-attr -a filename
# Or specifically for diff/merge attributes
git check-attr diff filename
git check-attr merge filenamePrevention: Always declare binary file types in .gitattributes at the start of a project.
Deep Dive: How Git Line Ending Conversion Works
Git's line ending handling involves several interacting settings:
1. core.autocrlf:
Controls automatic conversion:
- true: Convert LF -> CRLF on checkout, CRLF -> LF on commit (Windows mode)
- input: Convert CRLF -> LF on commit only (Unix mode)
- false: No conversion
2. core.safecrlf:
Safety check for conversions:
- true: Abort if conversion would change file irreversibly
- warn: Warn but proceed
- false: No check
3. core.eol:
Default line ending style:
- lf: Use LF for text files
- crlf: Use CRLF for text files
- native: Use platform default
4. .gitattributes text attribute:
Per-file/pattern control:
- text: Always treat as text
- text=auto: Let Git detect
- binary or -text: Never treat as text
- text eol=lf: Text with forced LF endings
- text eol=crlf: Text with forced CRLF endings
Order of Precedence:
1. .gitattributes in the repository (highest)
2. .gitattributes in parent directories
3. $GIT_DIR/info/attributes
4. Local config (git config)
5. Global config (git config --global)
6. System config (git config --system)
The "Irreversible Conversion" Problem:
The safecrlf error specifically guards against this scenario:
1. File in repo has LF endings
2. You check it out with autocrlf=true -> gets CRLF in working dir
3. You make changes
4. On commit with autocrlf=true -> converts CRLF back to LF
5. But if the original had mixed endings or was binary with LF sequences, step 4 might produce different content than step 1
safecrlf=true prevents step 4 if it detects this mismatch.
CI/CD Considerations:
Different CI/CD platforms handle line endings differently:
- GitHub Actions: Linux runners default to LF, Windows runners to CRLF
- GitLab CI: Usually Linux-based (LF)
- Azure DevOps: Depends on agent OS
For consistent behavior:
# GitHub Actions example
- name: Configure Git
run: |
git config --global core.autocrlf false
git config --global core.eol lfEditor Configuration:
Ensure your editor respects line endings:
VS Code (settings.json):
{
"files.eol": "\n", // or "\r\n" for Windows
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true
}EditorConfig (.editorconfig):
root = true
[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
trim_trailing_whitespace = true
[*.{bat,cmd}]
end_of_line = crlfTroubleshooting Persistent Issues:
If the error persists after configuration changes:
1. Clear Git's cache:
git rm -r --cached .
git reset --hard2. Check for conflicting configs:
git config --list --show-origin | grep -E "(autocrlf|safecrlf|eol)"3. Verify .gitattributes is being read:
git check-attr -a -- problematic-file.txt4. Fresh clone with explicit settings:
git clone -c core.autocrlf=false -c core.safecrlf=false <repo-url>Historical Context:
This complexity exists because:
- Git was created on Linux (LF)
- Windows uses CRLF
- macOS switched from CR (classic Mac) to LF (Unix-based)
- Cross-platform development became common
The autocrlf feature was added to help Windows developers, but it created as many problems as it solved. The modern recommendation is to use .gitattributes for explicit control and disable autocrlf globally.
warning: BOM detected in file, this may cause issues
UTF-8 Byte Order Mark (BOM) detected in file
fatal: Server does not support --shallow-exclude
Server does not support --shallow-exclude
warning: filtering out blobs larger than limit
Git partial clone filtering large blobs warning
fatal: Server does not support --shallow-since
Server does not support --shallow-since in Git
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server