UTILYARD
guides

How to Read a Diff

What the symbols in a unified diff mean, how to read git diff output, and what the hunk header tells you.

What is a diff?

A diff (short for difference) is a representation of what changed between two versions of a file — or two text inputs. It shows exactly which lines were added, removed, or left unchanged, without including the entire file.

The unified diff format is the standard used by Git, most code review tools (GitHub, GitLab, Gerrit), and the Unix diff command. Once you know how to read it, you can understand any code change, patch file, or pull request at a glance.

A complete example

diff --git a/src/utils.js b/src/utils.js
index 4b2f1a3..8e9d7c1 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -12,7 +12,9 @@ function formatDate(date) {
   const month = date.getMonth() + 1
   const day = date.getDate()
-  return month + '/' + day + '/' + date.getFullYear()
+  const year = date.getFullYear()
+  const pad = n => String(n).padStart(2, '0')
+  return pad(month) + '/' + pad(day) + '/' + year
 }

 module.exports = { formatDate }

Reading the header

diff --git a/src/utils.js b/src/utils.js

The file being compared. a/ is the "before" version, b/ is the "after" version. For a new file, a/ doesn't exist; for a deleted file, b/ doesn't exist.

--- a/src/utils.js
+++ b/src/utils.js

--- marks the old file, +++ marks the new file. These lines tell you which file each subsequent - and + line comes from.

The hunk header

@@ -12,7 +12,9 @@ function formatDate(date) {

This is called the hunk header. It tells you where in the file the change occurs:

-12,7 — in the old file, this hunk starts at line 12 and spans 7 lines

+12,9 — in the new file, this hunk starts at line 12 and spans 9 lines (2 more because we added 2 lines)

function formatDate(date) { — the surrounding context function, shown for orientation (Git infers this from the nearest function/class declaration)

Line markers

(space)
Context line Unchanged — shown for surrounding context. Default is 3 lines of context on each side.
-
Removed line Present in the old file, absent from the new file. In GitHub's UI, shown with a red background.
+
Added line Absent from the old file, present in the new file. In GitHub's UI, shown with a green background.

A "modification" to a line always appears as a removal followed by an addition — diffs don't have a "modified" concept, only added and removed lines.

Common git diff commands

# Changes in your working tree (unstaged)
git diff

# Staged changes (what will be committed)
git diff --staged

# Changes in a specific commit
git show <commit-hash>

# Changes between two commits
git diff main..feature-branch

# Changes to a specific file only
git diff HEAD -- src/utils.js

# Word-level diff (highlights changed words, not lines)
git diff --word-diff
Try it: Diff Checker
Paste two texts to compare them and see the differences highlighted line by line.
Open tool →

Frequently asked questions

What does 'no newline at end of file' mean in a diff?
Most text editors and tools expect files to end with a newline character. If a file doesn't, git diff shows "\ No newline at end of file" after the last line. It's usually harmless but can cause noise in diffs — many linters and editors will add the trailing newline automatically.
What is a patch file?
A patch file is a diff saved to a file — typically with a .patch extension. You can create one with git diff > my-change.patch and apply it later with git apply my-change.patch or the Unix patch command. Patch files were the original way to share code changes before distributed version control systems (like Git) made branches and PRs the norm.
How do I make git show only the changed words, not full lines?
Use git diff --word-diff. Instead of showing entire added/removed lines, it highlights the specific words that changed inline. This is especially useful for prose or documentation changes where line rewrapping obscures what actually changed.