See the smallest line edits, then take the patch with you
Compare two short texts by complete line, inspect a deterministic minimum edit script and download a unified patch with accurate ranges, selected context and explicit missing-final-newline markers.
Unified diff patch
A standard --- / +++ patch with @@ ranges, selected context and explicit missing-final-newline markers.
The complete line edit script
| Unchanged | 1 | 1 | alpha |
| Removed | 2 | beta | |
| Added | 2 | beta revised | |
| Unchanged | 3 | 3 | line 03 |
| Unchanged | 4 | 4 | line 04 |
| Unchanged | 5 | 5 | line 05 |
| Unchanged | 6 | 6 | line 06 |
| Unchanged | 7 | 7 | line 07 |
| Unchanged | 8 | 8 | line 08 |
| Unchanged | 9 | 9 | line 09 |
| Unchanged | 10 | 10 | line 10 |
| Unchanged | 11 | 11 | line 11 |
| Removed | 12 | delta | |
| Added | 12 | epsilon |
How it works
The edit model
Each document becomes an ordered sequence of logical lines. CRLF, old-style CR and LF separators are treated as the same boundary, but the presence of the last newline is retained. That distinction is why adding a final newline can be represented even when the visible characters on the line do not change.
A longest-common-subsequence matrix finds the largest ordered set of complete lines shared by both sides. Everything outside that shared sequence is a deletion from the original or an insertion into the revision. Choosing a longest common subsequence minimises the total number of those edit operations.
Repeated identical lines can allow several equally short answers. The tool breaks such ties in one documented direction—delete before insert—so the same inputs always generate the same patch.
The worked comparison
Original:
alpha
beta
gamma
delta
Revised:
alpha
beta revised
gamma
epsilon
alpha and gamma are the two unchanged lines. The other two originals are
removed and their revisions are added, producing 2 lines added, 2 lines
removed, 2 unchanged, and—at three context lines—1 hunk:
--- a/document.txt
+++ b/document.txt
@@ -1,4 +1,4 @@
alpha
-beta
+beta revised
gamma
-delta
+epsilon
The source code block deliberately uses the same two-line header and range
grammar as the artifact. A count of one is written as just its start; other
counts use start,count. An insertion into an empty file therefore begins with
an old range of 0,0.
Context changes packaging, not the answer
With three context lines, the unchanged gamma sits between both replacements
and they share one hunk. With zero context, that unchanged line is omitted and
the two replacement regions become two compact hunks. The edit table still
lists the complete sequence either way.
GNU Diffutils defaults to three lines because context helps a patching program locate an edit after nearby lines shift. Zero-context output is valid and useful for a compact review, but it carries less evidence about where a later consumer should apply it.
This is a two-way textual comparison, not a semantic merge. Use the Markdown table of contents maker to generate a document, then compare that result here when you want to inspect every inserted anchor and navigation line.
How it is done
- Normalise CRLF and lone CR line endings to LF, while recording whether each document's final logical line has a terminating newline.
- Build a longest-common-subsequence matrix over complete line text plus its termination state, choosing deletion before insertion when several minimum scripts tie.
- Expand every changed edit by the requested number of unchanged context lines and merge ranges that touch or overlap into unified diff hunks.
- Write cleaned --- and +++ labels, exact @@ start,count ranges and space, minus or plus line prefixes into a downloadable patch.
What it assumes
- Comparison is line-based and exact after newline normalisation; whitespace, case and Unicode-normalisation differences are not ignored.
- Each side is limited to 2,000 characters, keeping the quadratic longest-common-subsequence matrix bounded in the browser.
- More than one minimum edit script can exist. Deletion-first ties make this output repeatable but not uniquely mathematically privileged.
- A syntactically formed patch can still fail against a third file whose surrounding content has changed; this tool does not apply or merge patches.
Common questions
Why is one changed line shown as one removal and one addition?
Unified diff has context, removed and added line records, not a separate replace record. A replacement therefore removes the old complete line and adds the new one.
What do context lines change?
They change how much unchanged material surrounds an edit and whether nearby regions merge into one hunk. They do not change the underlying additions, removals or minimum edit script.
Does a final newline difference count?
Yes. A text file ending in `same` is not byte-equivalent to one ending in `same` plus a newline, so the patch emits the conventional explicit marker for the incomplete line.
Can the patch reveal a local directory path?
The label is reduced to its final path component and control characters are removed. The headers use only `a/label` and `b/label`, with no machine path or timestamp.