Normalize Line Endings: Where the ^M in Your Git Diff Comes From
Text from Windows or an older Mac carries CRLF or bare CR endings, which show up as ^M and doubled blank lines in Git diffs, Linux scripts, and online editors. Converting them all to LF is invisible on screen but makes the diff clean.
Open the tool:Normalize Line Endings
When line endings need normalising
The same code edited on Windows and run on Linux can show every file as wholly changed in a Git diff, when the only difference is CRLF versus LF at the end of each line. When part of a team is on Windows and part on macOS, that noise appears daily and real changes become impossible to review.
Another case is a script that fails: a shell script copied from a web page or a chat window carries a CR at the end of each line, so the interpreter complains or a stray invisible character ends up in the command. Normalising to LF usually fixes it immediately, and configs, CSVs, and subtitle files hit the same problem.
- Git diffs showing whole-file changes with ^M markers
- Shell scripts copied from Windows failing to run
- Normalising CSVs, configs, and subtitles before upload
How to normalise without surprises
CRLF (Windows, carriage return then line feed) and a lone CR (older Mac) are both rewritten as LF, and no other character changes. The result looks exactly the same in the text area, because all three endings render as a newline there and the difference is invisible to the eye.
To confirm the change, paste the result into an editor that displays invisible characters, or commit it and check whether the diff still shows ^M. Note that only the endings are replaced: blank lines, trailing spaces, and indentation are preserved exactly, so pair this with a whitespace cleanup if those need work.
- The result looks identical, so verify with invisible characters or Git
- Only line endings change, not blank lines or indentation
- Run a trailing-whitespace pass afterwards if needed
Where it stops, and what to use instead
It does not change the file encoding (UTF-8, GBK, UTF-16 all stay as they are) and does not touch a BOM. If the encoding itself is wrong, normalised line endings will still produce garbled text, and that is a separate problem needing an encoding converter.
Pasting file by file is not realistic for a whole repository. The right fix there is a gitattributes rule with text=auto, or dos2unix and a batch conversion in your editor. A browser page suits one file or one block of text, not a long-term policy for a repository.
- Does not change encoding or strip a BOM
- Repositories need gitattributes or dos2unix
- Browser tools suit one-off single-file work
FAQ
The result looks identical to the original. Did anything actually change?
Yes. Both kinds of line ending render as a newline in a text area, so the difference is invisible here. Paste the result into an editor that shows invisible characters, or check the Git diff for remaining ^M marks.
Does it also remove blank lines or trailing spaces?
No. Only the line-ending characters are replaced; blank lines, trailing spaces, and indentation are preserved exactly. Pair it with the trim-lines tool, or remove blank lines separately, if you want those cleaned too.
What is the actual difference between CRLF and LF?
CRLF is two characters, a carriage return and a line feed, and is common in Windows Notepad. LF is a single line feed, used on Linux and macOS. They look the same in an editor but differ byte for byte, which is what trips up Git and scripts.
Related tool:Normalize Line Endings