Skimmark / Blog

How to diff Markdown files with git

Bobby Huang ·

Markdown is plain text, so git can diff it like code. Use git diff --word-diff notes.md to see changed words inside a paragraph. Use git diff --no-index --word-diff v1.md v2.md to compare files outside a git project.

Key takeaways

  • git diff notes.md shows unstaged changes; word diff shows changed words inside a long line.
  • Check git diff --stat before reading a large diff.
  • git log -p --word-diff -- notes.md shows one file's history with word-level changes.
  • git diff --no-index compares two files outside a git project and exits with status 1 when they differ.

Markdown is plain text, so git can diff it like code. The trouble is that prose does not behave like code. One changed word on a long line shows up as a whole deleted line and a whole added line. If an agent touched ten paragraphs, you get ten pairs of near-identical walls of text.

This guide covers the git commands that make Markdown diffs easier to read. Each one was run in a test repo, and the output shown is what git printed.

1. Start with a plain git diff

To see unstaged changes to a Markdown file, run:

git diff notes.md

Here is the output after changing one word and adding a list item:

diff --git a/notes.md b/notes.md
index 71d67c7..9ec9de7 100644
--- a/notes.md
+++ b/notes.md
@@ -1,3 +1,5 @@
 # Notes
 
-The status is draft. We ship the report on Friday after Jane Doe reviews the summary section.
+The status is final. We ship the report on Friday after Jane Doe reviews the summary section.
+
+- New item

Only one word changed in that paragraph, but git shows the whole line twice. On real documents, where a paragraph is often one very long line, this gets hard to scan fast.

2. Use word diff for prose

The fix for most Markdown diffs is word-level output:

git diff --word-diff notes.md

Same change, new view:

@@ -1,3 +1,5 @@
# Notes

The status is [-draft.-]{+final.+} We ship the report on Friday after Jane Doe reviews the summary section.

{+- New item+}

Removed words sit inside [-...-] and added words inside {+...+}. The rest of the paragraph stays as plain context. For prose, this is usually the view you want. If your terminal shows color, git diff --color-words gives the same idea with colors in place of brackets.

3. Get a quick summary with --stat

Before reading a diff, check how big it is:

git diff --stat
 notes.md | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

This is handy after an agent run. If you expected a one-line fix and --stat reports dozens of changed lines across many files, something reformatted more than it should have. Why editors reformat Markdown on save covers why editors do that.

4. Compare commits, not just your working copy

To see what the last commit changed:

git diff HEAD~1 HEAD --stat

To see the history of one Markdown file with each change inline:

git log -p -- notes.md

git log -p prints each commit message followed by its diff for that file. To read word-level changes in the last commit, omit --stat and run:

git diff --word-diff HEAD~1 HEAD

For word-level output in the file's history, run:

git log -p --word-diff -- notes.md

This is the quickest way to answer "what did the agent change in this file over the last few runs?" without opening each commit.

5. Diff two Markdown files that are not in git

You do not need a repo to use git's diff. The --no-index flag compares any two files on disk:

git diff --no-index --word-diff v1.md v2.md
diff --git a/v1.md b/v2.md
index 9ec9de7..6570093 100644
--- a/v1.md
+++ b/v2.md
@@ -1,5 +1,5 @@
# Notes

The status is [-final.-]{+approved.+} We ship the report on Friday after Jane Doe reviews the summary section.

- New item

One thing to know if you script this: git diff --no-index exits with status 1 when the files differ and 0 when they match. A script that treats any non-zero exit as an error will fail on every real change.

6. Hide line-ending noise

Some diffs show a changed line where nothing visible changed. A common cause is line endings: one tool saved the file with Windows-style CRLF endings and another with LF. In the test repo, switching one line from CRLF to LF gave this:

git diff --stat
 crlf.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Ask git to ignore carriage returns at line ends:

git diff --ignore-cr-at-eol --stat

That run printed nothing, because the difference was the line ending. This flag hides the noise in your view; it does not fix the file.

Quick reference

Goal Command
See unstaged changes git diff notes.md
Word-level changes in prose git diff --word-diff notes.md
Size of a change git diff --stat
What the last commit changed git diff HEAD~1 HEAD
One file's history with diffs git log -p -- notes.md
Two files outside a repo git diff --no-index --word-diff v1.md v2.md
Ignore CRLF vs LF noise git diff --ignore-cr-at-eol

Tips for smaller Markdown diffs

  • One sentence per line. If you control the writing style, put each sentence on its own line. A one-word change then touches one short line, and even a plain git diff stays readable. Rendered Markdown looks the same, since a single line break inside a paragraph does not start a new paragraph.
  • Check --stat first. A surprising count is a signal to look for reformatting before you read every line.
  • Use word diff by default for docs. Most prose edits are a few words inside a long paragraph.

When git is not the right tool

Git diffs show what changed between commits. They do not help much when an agent rewrites a file several times between commits, or when the file lives outside a repo and you just want to know what changed since you last read it.

Skimmark, a Markdown reader for people whose AI agents write Markdown, is in development. Its Changes View, which highlights what changed since you last looked with no git needed, is planned for v1.

Next read

Seeing what changed in a Markdown file: git, diff tools, and readers covers the wider diff workflow.

Skimmark is in development. Skimmark is the home page.

View as Markdown