Tools Nimbus

Why does my diff show every line changed

Tools Nimbus is a free, no-signup developer toolkit that runs entirely in your browser, so your data is never uploaded to a server. A diff that marks every line as changed almost always means invisible bytes changed, not content: CRLF versus LF line endings, a re-indent from tabs to spaces, trailing whitespace stripped on save, or a new file encoding. Paste both versions into the Tools Nimbus Diff Checker to see which.

Last updated October 2026

A line diff compares bytes, not what you see

Git, GitHub, and every line-based diff tool split both files into lines and look for the longest run of lines that are byte-for-byte identical. A line counts as unchanged only if every byte matches, including the ones your editor does not draw: the carriage return before a line break, a trailing space, a tab that renders as four spaces. Change one of those on every line and the diff has no common lines left to anchor on, so it reports the whole file as removed and re-added, even when the text reads exactly the same.

That makes the problem mechanical to debug. You are not looking for a bug in the diff tool; you are looking for the one invisible thing that changed on every line at once. In practice there are only a handful of candidates, and each leaves a recognizable fingerprint.

Symptom, cause, and fix at a glance

What you seeMost likely causeConfirm withFix
Every line changed, ^M at line endsCRLF vs LF line endingsgit diff --ignore-cr-at-eol collapses the diffAdd .gitattributes, then git add --renormalize .
Every indented line changed, others untouchedTabs converted to spaces, or indent width changedgit diff -w collapses the diffCommit the re-indent on its own; set an editorconfig
Scattered lines changed with no visible editTrailing whitespace stripped on savegit diff --ignore-space-at-eolSeparate the cleanup commit, or turn off the editor setting
Only line 1 changed, or Git says "Binary files differ"Byte-order mark added, or UTF-16 vs UTF-8 encodingfile name.txt reports the encodingRe-save as UTF-8 without BOM
old mode 100644 / new mode 100755, no line changesExecutable bit flipped, not contentThe diff header itselfgit update-index --chmod=-x or restore the mode
The whole file is one changed lineMinified JSON or a single-line fileLine count is 1 on both sidesPretty-print both versions, then diff
Every line of a paragraph changedProse was re-wrapped to a new line widthgit diff --word-diffDiff by word, or write one sentence per line

Cause 1: CRLF versus LF line endings (the usual culprit)

Windows editors traditionally end each line with two bytes, a carriage return and a line feed (\r\n, CRLF). macOS and Linux use a bare line feed (\n, LF). If a file was committed with LF and someone saves it on Windows with CRLF, every single line gains one byte, and the diff marks all of them. Git usually prints the stray carriage return as ^M at the end of each added line, which is the giveaway.

To confirm, run git diff --ignore-cr-at-eol (Git 2.16 and later). If the diff shrinks to the edit you actually made, you have your answer. git ls-files --eol goes further and shows, per file, the line endings stored in the index (i/lf) next to the ones in your working copy (w/crlf).

The durable fix is a .gitattributesfile at the repository root, so the rule travels with the repo instead of depending on each person's core.autocrlf setting:

* text=auto
*.sh text eol=lf
*.bat text eol=crlf

Then run git add --renormalize .and commit the result as a standalone "normalize line endings" commit. From then on Git stores LF in the repository and converts on checkout where a file type needs it. Line endings also quietly change hashes, which is why the same file can produce two checksums on two machines; see why a SHA-256 hash is different for that side of the problem.

Cause 2: tabs, spaces, and re-indentation

If every indented line changed but blank lines and top-level lines did not, the indentation changed. An editor converted tabs to spaces, a formatter such as Prettier or Black ran for the first time, or the indent width went from four spaces to two. The text is identical once you strip leading whitespace, which is exactly what git diff -w (ignore all whitespace) does. Use -b instead if you only want to ignore changes in the amount of whitespace while still seeing whitespace that was added where there was none.

Formatting changes are legitimate, but they bury real edits. Put them in their own commit, and add the commit hash to a .git-blame-ignore-revs file so git blame skips it. An .editorconfigfile stops the next contributor's editor from re-indenting the file again.

Cause 3: trailing whitespace stripped on save

Many editors remove spaces at the end of lines when you save. In a file that had a lot of trailing whitespace, that shows up as dozens of scattered changed lines that look untouched. Run git diff --ignore-space-at-eolto hide them. The same setting is the reason a file that ends without a final newline suddenly gains one: the last line shows as changed, often with Git's "\ No newline at end of file" marker on the old side.

Cause 4: encoding and byte-order marks

A UTF-8 byte-order mark is three invisible bytes (EF BB BF) at the very start of a file. Adding or removing one changes only the first line, which is a useful tell when a diff flags line 1 and nothing else. A full encoding change is louder: a file re-saved from UTF-16 to UTF-8 has different bytes for every character, and Git often treats UTF-16 as binary and prints only "Binary files differ". Run file name.txt on macOS or Linux to see the encoding and whether it has CRLF terminators. Standardize on UTF-8 without a BOM, or tell Git about a file that must stay UTF-16 with the working-tree-encoding attribute.

Cause 5: the file is one long line

A line diff cannot show you a small change inside one huge line. Minified JSON, a compressed CSS bundle, or a lockfile written on one line will always show as "the whole file changed" because the whole file is one line. Pretty-print both versions first with the JSON Formatter (sort or keep keys the same on both sides), then compare the formatted output. The same logic applies to prose: if a paragraph was re-wrapped to a new width, every line shifts. git diff --word-diff compares by word instead of by line and shows only the words that actually changed.

Find the cause in one paste

Open the Diff Checker and paste the old version on the left and the new one on the right. Then read the result as a decision tree:

  1. Zero changes, while Git insists every line changed: the difference is line endings. Browsers normalize CRLF to LF in any text box you paste into, so a pure line-ending change vanishes here, which is itself the diagnosis.
  2. Many changes that disappear when you tick Ignore whitespace: the difference is indentation or trailing whitespace (causes 2 and 3).
  3. Only the first line changed: suspect a byte-order mark (cause 4).
  4. Changes remain with whitespace ignored: the content really did change, or a long line or re-wrap is hiding a small edit (cause 5).

The comparison runs entirely in your browser, so source code and config files never leave your device. It compares up to 1,500 lines per side, which covers most single files you would review by hand. If you are choosing a diff tool more generally, the honest comparison with Diffchecker covers what each one does better.

How to keep it from happening again

  • Commit a .gitattributes with * text=autoso line endings no longer depend on each machine's settings.
  • Commit an .editorconfig that pins indent style, indent size, final newline, and trailing-whitespace behaviour.
  • Run formatters in a dedicated commit, and list that commit in .git-blame-ignore-revs.
  • Review with whitespace hidden (git diff -w, or Hide whitespace on GitHub), but fix the cause rather than relying on the flag, because the bytes in the commit are still different.

More troubleshooting guides live in the guides index.

Frequently asked questions

Why does git diff show the whole file changed when I only edited one line?+

Because something invisible changed on every line. The usual cause is line endings: your editor or Git saved the file with CRLF (Windows) where it previously had LF (macOS, Linux), so every line gained a carriage return byte. Run git diff --ignore-cr-at-eol; if the diff collapses to your one real edit, line endings are the cause. Fix it permanently with a .gitattributes file and git add --renormalize.

How do I make git diff ignore line endings and whitespace?+

Use --ignore-cr-at-eol to ignore a carriage return at the end of each line, --ignore-space-at-eol to ignore any trailing whitespace, -b to ignore changes in the amount of whitespace, and -w to ignore all whitespace. These flags only change what the diff displays. The bytes in the commit are still different, so fix the cause too or the next person sees the same noise.

What does ^M mean in a git diff?+

^M is how Git and many terminals display a carriage return character (byte 0x0D). Seeing it at the end of lines means those lines end in CRLF while the other version ends in LF. It is the clearest single sign that a whole-file diff is a line-ending change rather than a content change.

Why does my diff show a change but the two lines look identical?+

The lines differ in characters you cannot see: trailing spaces, a tab where there were spaces, a non-breaking space, a zero-width character, or a byte-order mark on the first line. Paste both versions into a diff checker with ignore-whitespace off, then on. If the change disappears with it on, the difference was whitespace.

Why does GitHub show every line changed in my pull request?+

The same causes apply, most often a line-ending or indentation change committed from a different editor. In the Files changed tab, open the settings gear and choose Hide whitespace, or add ?w=1 to the pull request URL. If the diff shrinks, ask for the formatting change to go in its own commit so reviewers can see the real edit.

Is it safe to paste private code into an online diff checker?+

Only if the tool compares the text locally. The Tools Nimbus Diff Checker runs entirely in your browser, so neither version is uploaded, stored, or sent to a server. Avoid diff sites that save your comparison to their servers or share it by link when the text is source code, contracts, or configuration with secrets.

Try these browser-based tools mentioned in this guide. Everything runs locally, so your data never leaves your device.