emacs
text editing
carriage return
control characters
file formatting

What are these M's that keep showing up in my files in emacs?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If you see ^M markers in Emacs, you are usually seeing carriage return bytes from Windows-style line endings. This is a newline format mismatch, not random file corruption. The long-term fix is to align Emacs buffer encoding, Git normalization rules, and team repository policies.

What ^M Means

Different systems represent line endings differently:

  • Unix-style uses LF
  • Windows-style uses CRLF

When a file containing CRLF is displayed in contexts expecting LF, Emacs may show the CR byte as ^M.

This indicator points to formatting mismatch. Your text is generally intact, but the newline bytes differ from expected style.

Check Current Buffer Line Ending in Emacs

Before converting anything, inspect the buffer coding system.

emacs-lisp
(message "buffer coding: %s" buffer-file-coding-system)

Interactive methods:

  1. run M-x describe-coding-system
  2. inspect buffer-file-coding-system
  3. look for variants with DOS line endings

This confirms whether the file currently uses CRLF or LF.

Convert Current File to Unix Line Endings

To remove visible ^M markers for Unix-style projects, set Unix file coding and save.

emacs-lisp
(set-buffer-file-coding-system 'utf-8-unix)
(save-buffer)

Interactive equivalent:

  • M-x set-buffer-file-coding-system
  • select unix
  • save the buffer

This converts line endings in that file from CRLF to LF.

Set Better Emacs Defaults

If your projects mostly use LF, set default coding in your Emacs configuration.

emacs-lisp
(setq-default buffer-file-coding-system 'utf-8-unix)

This helps new files start in LF format and reduces recurring newline churn.

Still, editor defaults alone are not enough for teams. Repository-level policy should enforce line endings consistently across platforms.

Use Git Attributes to Prevent Recurrence

Add .gitattributes rules so line ending normalization is explicit.

text
1* text=auto
2*.py text eol=lf
3*.sh text eol=lf
4*.md text eol=lf
5*.bat text eol=crlf

Then normalize existing tracked files once:

bash
git add --renormalize .
git status

This keeps cross-platform contributions consistent and prevents repeated ^M reintroduction.

Mixed-Platform Strategy

Some repositories need both LF and CRLF:

  • scripts for Unix environments should use LF
  • batch files for Windows often need CRLF

The correct strategy is explicit per-file-type rules, not forcing one global format blindly.

When onboarding new contributors, document line-ending expectations in CONTRIBUTING.md along with editor recommendations.

External Conversion Tools

Sometimes batch conversion is easier outside Emacs, especially for one-time cleanup.

bash
dos2unix path/to/file.txt

Alternative command:

bash
sed -i '' $'s/\r$//' path/to/file.txt

After conversion, review diffs carefully and keep newline-only changes in dedicated commits.

Troubleshooting Persistent Reappearance

If ^M keeps coming back, check in this order:

  1. repository .gitattributes is present and committed
  2. local Git settings are not conflicting
  3. generators or scripts are not rewriting files as CRLF
  4. CI or formatting tools are not reapplying platform defaults

This process usually identifies the source quickly.

CI and Automation Guardrails

To stop recurring issues, include line-ending checks in CI for critical file types.

bash
1# example check for CR bytes in shell scripts
2if grep -U $'\r' scripts/*.sh >/dev/null; then
3  echo "CRLF detected in shell scripts"
4  exit 1
5fi

Automation prevents format regressions from reaching main branches.

Common Pitfalls

A common pitfall is manually deleting visible ^M characters in the editor without fixing file encoding and repository policy.

Another pitfall is applying global LF conversion to files that legitimately require CRLF, such as Windows batch scripts.

A third pitfall is mixing functional edits with large normalization changes, which makes code review difficult.

Teams also overlook auto-generated files and build tools that keep reintroducing unwanted line endings.

Summary

  • ^M in Emacs usually indicates CRLF line endings shown in an LF-oriented workflow.
  • Convert file coding in Emacs to Unix style when LF is desired.
  • Enforce repository policy with .gitattributes for durable cross-platform consistency.
  • Allow explicit CRLF exceptions for file types that require it.
  • Add CI checks and isolated normalization commits to prevent repeat churn.

Course illustration
Course illustration

All Rights Reserved.