Git status ignore line endings in identical files on Windows & Linux

Learn git status ignore line endings in identical files on windows & linux with practical examples, diagrams, and best practices. Covers linux, windows, git development techniques with visual expla...

Resolving Git Line Ending Issues: Ignoring Differences Between Windows and Linux

Hero image for Git status ignore line endings in identical files on Windows & Linux

Learn how to configure Git to ignore line ending differences, preventing 'identical files' from showing up in git status on Windows and Linux.

One of the most common frustrations for developers working in cross-platform environments (e.g., Windows and Linux) is Git reporting identical files as modified due to line ending differences. Windows typically uses Carriage Return and Line Feed (CRLF) for line endings, while Linux and macOS use only Line Feed (LF). This seemingly minor difference can lead to a cluttered git status output and unnecessary commits.

Understanding Line Endings and Git's Role

Line endings are invisible characters that mark the end of a line in a text file. Historically, different operating systems adopted different conventions:

  • CRLF (Carriage Return Line Feed): \r\n - Used by Windows.
  • LF (Line Feed): \n - Used by Unix-like systems (Linux, macOS).

Git, by default, tries to be helpful by normalizing line endings. This means it can convert CRLF to LF when committing to the repository and convert LF to CRLF when checking out files on Windows. While this is often beneficial, misconfigurations or specific project requirements can lead to persistent 'modified' files even when the content is otherwise identical.

flowchart TD
    A[Developer on Windows] --> B{Edit File (CRLF)};
    B --> C{Git Add/Commit};
    C --> D[Git Repository (LF Normalized)];
    D --> E{Git Checkout};
    E --> F[Developer on Linux];
    F --> G{Edit File (LF)};
    G --> H{Git Add/Commit};
    H --> D;
    D --> I{Git Checkout};
    I --> J[Developer on Windows (CRLF Converted)];
    J -- "Problem: Git thinks file is modified if conversion is off or inconsistent" --> B;

Git's Line Ending Normalization Workflow

Configuring Git for Cross-Platform Line Endings

The primary way to manage line endings in Git is through the core.autocrlf configuration setting. This setting tells Git how to handle line endings when committing and checking out files. There are three main values:

  1. true (Recommended for Windows users): Git converts CRLF to LF on commit, and LF to CRLF on checkout. This ensures that the repository always stores LF, but Windows users get CRLF in their working directory.
  2. input (Recommended for Linux/macOS users): Git converts CRLF to LF on commit, but does not convert LF to CRLF on checkout. This is suitable for Unix-like systems where LF is the standard.
  3. false (Not recommended for cross-platform projects): Git does no line ending conversion at all. Files are committed and checked out exactly as they are, which can lead to significant issues in mixed environments.
git config --global core.autocrlf true   # For Windows users
git config --global core.autocrlf input  # For Linux/macOS users
git config --global core.autocrlf false  # Use with caution!

Setting core.autocrlf globally

Using .gitattributes for Project-Specific Control

While core.autocrlf is a global setting, .gitattributes allows you to define line ending behavior on a per-file or per-pattern basis within your repository. This is the most robust solution for ensuring consistent line endings across a project, regardless of individual developer settings.

Common attributes for line endings include:

  • text=auto: Git will guess if a file is text or binary and handle line endings accordingly (similar to core.autocrlf). This is often the default.
  • text eol=lf: Forces Git to always store and checkout files with LF line endings. This is ideal for scripts, source code, and configuration files that should always be LF.
  • text eol=crlf: Forces Git to always store and checkout files with CRLF line endings. Less common, but useful for files specifically intended for Windows.
  • binary: Tells Git to treat the file as binary, completely ignoring line endings. Essential for images, compiled executables, etc.
# Set default behavior for all text files
* text=auto

# Force specific file types to use LF (Unix-style) line endings
*.js text eol=lf
*.json text eol=lf
*.sh text eol=lf
*.md text eol=lf

# Treat specific files as binary (no line ending conversion)
*.png binary
*.jpg binary
*.exe binary

Example .gitattributes file

Troubleshooting and Best Practices

If you're still seeing line ending issues, consider these steps:

  1. Check git config --list: Verify your local and global core.autocrlf settings.
  2. Inspect .gitattributes: Ensure it's correctly configured and committed to the repository.
  3. Normalize the repository: As mentioned above, git rm --cached -r . followed by git reset --hard can fix existing files.
  4. Educate your team: Ensure everyone understands and follows the project's line ending conventions.
  5. Use git diff --word-diff or git diff --ignore-space-at-eol: These commands can help you visualize differences without being distracted by line endings or whitespace.

1. Step 1: Set Global core.autocrlf

Configure your global Git settings based on your operating system. Windows users should use true, while Linux/macOS users should use input.

2. Step 2: Create/Update .gitattributes

Add a .gitattributes file to the root of your repository (if it doesn't exist) and define project-specific line ending rules. Commit this file to your repository.

3. Step 3: Normalize Repository (if needed)

If you had existing line ending issues, run git rm --cached -r ., then git reset --hard, followed by git add . and git commit -m "Normalize line endings" to apply the new .gitattributes rules.

4. Step 4: Verify Changes

After these steps, git status should no longer report line ending differences for files covered by your .gitattributes configuration.