Try the Text Diff

Why Git Diff Shows the Same Change Differently Than Other Tools — Myers Algorithm, Patience Diff, and Semantic Diffing

The Myers diff algorithm (used by git diff) finds the minimum edit sequence with fewest edit groups — not just minimum edits — because multiple minimum-edit solutions exist and some are far more readable than others. Here's why patience diff wins for code by anchoring on unique lines first, how AST-based semantic diffing represents a renamed variable as one change instead of N lines, and why diff3 merge conflict markers (showing the common ancestor alongside both conflicting versions) make conflicts easier to resolve.

July 28, 2026 7 min read
Share: Facebook WhatsApp LinkedIn Email
Why Git Diff Shows the Same Change Differently Than Other Tools — Myers Algorithm, Patience Diff, and Semantic Diffing

The Myers diff algorithm — the algorithm that powers git diff, most code review tools, and the majority of text comparison utilities — is not actually designed to find the shortest edit sequence but to find the shortest edit sequence with the fewest "edit groups," and this distinction explains why two algorithms that both produce minimal edits can show the same changes in visibly different ways

Text diffing as a user experience problem is often underappreciated. The algorithm that computes the minimum edit distance between two texts has a mathematically defined correct answer, but the way those edits are presented — which changes are shown together, how context lines are grouped, where line breaks fall — is a set of choices that significantly affects readability and comprehension.


Edit distance and why minimum edits aren't unique

Edit distance (Levenshtein distance) measures the minimum number of single-character insertions, deletions, and substitutions needed to transform one string into another. For diff tools, the relevant operation set is typically just insertions and deletions of lines (not substitutions, which decompose into a deletion plus an insertion).

The non-uniqueness problem: for any pair of texts, there are often multiple ways to produce the minimum number of edits — but some of those ways are more readable than others:

Original: "The quick brown fox"
Modified: "The slow brown fox"

A diff algorithm could represent this as:

  1. Delete "quick", insert "slow" at the same position — readable
  2. Delete "The quick", insert "The slow", retain " brown fox" — less readable (more context disturbed)
  3. Retain "The ", delete "quick", retain " brown", delete " fox", insert " slow fox" — confusing

All three represent the minimum number of changed characters but look very different in a diff view. The Myers algorithm's preference for fewest edit groups (contiguous blocks of added/deleted lines) generally produces the most readable output for human readers.


The patience diff algorithm and why it sometimes wins

The patience diff algorithm (developed by Bram Cohen, the creator of BitTorrent, and used by Bazaar VCS) prioritises matching unique lines first before finding the minimal edit:

The key insight: in code diffs, the most structurally significant lines are often unique lines (function signatures, class declarations, distinctive control flow) rather than common boilerplate lines (blank lines, closing braces, import statements). A diff algorithm that anchors on unique lines first produces output that preserves the structural identity of the code.

Where patience diff wins over Myers: consider a file where two different functions are adjacent. Myers may produce a diff that inserts and deletes across both function boundaries simultaneously (because this is the minimum character-edit path). Patience diff anchors each function signature as a unique line, producing a cleaner diff that shows the changes within each function independently.

Git's support: git diff --patience switches to the patience algorithm; git diff --histogram uses an evolved version of patience that handles repeated elements more robustly (histogram diff is Git's recommended non-default algorithm when you want cleaner output).


Semantic vs syntactic diffing

Standard text diff compares at the line or character level without understanding the content's meaning. A single reformatted line (a 150-character line broken into three 50-character lines) appears as three insertions and one deletion — the same change as genuinely different content.

Semantic diff tools understand the language's structure and compare at the semantic level:

AST (Abstract Syntax Tree) diffing: for programming languages, comparing the parsed AST rather than the raw text. A renamed variable appears as a single renaming operation rather than N changed lines. Moving a function to a different file appears as a move rather than a deletion and insertion. Tools: GumTree (Java), difftastic (multi-language), structural diff in IntelliJ/JetBrains.

Structured data diffing: JSON diff, XML diff, and YAML diff tools compare at the structural level (as covered in the JSON diff article). Adding a field appears as one addition rather than potentially multiple raw text lines.

The trade-off: semantic diff requires parsing (and correctly handling malformed or partially-valid input), language-specific support, and is more computationally expensive. It's most valuable in code review workflows for specific languages. Text-level diff remains universal.


Inline vs side-by-side diff: UX implications

Unified diff format (the --- / +++ format used by git diff and most CLI tools) shows changes in a single stream with context lines:

@@ -3,7 +3,7 @@
 import os
 import sys
-from typing import List, Dict
+from typing import List, Dict, Optional
 
 class Config:
     pass

Side-by-side diff shows the old version on the left and new version on the right, aligning changed lines horizontally. Better for:

  • Understanding what a specific line changed to
  • Seeing complex modifications where the old and new versions are meaningfully different rather than additive
  • Reviewing changes where positional context matters (table structure changes, aligned code)

Word-level highlighting within line diffs: most modern diff tools (GitHub, GitLab, Gerrit) additionally highlight the specific words or characters that changed within a modified line — combining the line-level diff with inline character-level diff to show exactly which part of a line changed.


Three-way merge and conflict presentation

Three-way merge computes the diff between a common ancestor and two diverged versions, then attempts to automatically merge non-conflicting changes and present conflicting changes for manual resolution:

Standard conflict markers:

<<<<<<< HEAD
The original version from the current branch
=======
The incoming version from the merged branch
>>>>>>> feature-branch

diff3 conflict markers (enabled with git checkout --conflict=diff3 or git config merge.conflictstyle diff3) add a third section showing the common ancestor:

<<<<<<< HEAD
Current branch version
||||||| merged common ancestors
Original ancestor version
=======
Incoming branch version
>>>>>>> feature-branch

Why diff3 markers help: seeing the ancestor version alongside both conflicting versions makes it clearer what each branch changed relative to the shared starting point — often making the correct merge more obvious than comparing only the two conflicting versions.


How to use the Text Diff tool on sadiqbd.com

  1. For document comparison: paste two versions of a document (contract draft, report revision, specification) to see all changes highlighted — choose side-by-side view for modified paragraphs to understand what each section changed to, unified view for an overview of total change volume
  2. For code review outside a VCS: diff source code snippets to review changes when a full git diff isn't available (patch files, shared code in documentation, email-shared code)
  3. For content audit: compare current website copy against an archived or reference version to find what changed — particularly useful for regulatory or compliance-sensitive content where unintended changes need detection

Frequently Asked Questions

Why does git diff sometimes show a change I made as a deletion plus insertion rather than a modification, even when I clearly just edited a single line? Because diff algorithms operate on lines as atomic units — a "modification" in human terms is represented as delete-the-old-line plus insert-the-new-line in the diff algorithm's output. What you're seeing is correct diff output. The word-level highlighting in tools like GitHub's diff view makes modifications look like modifications by adding a second layer of character-level diff within each changed line — but the underlying line-level diff sees it as replace. This is also why reformatting code (changing indentation, line breaks) with no semantic change produces a large diff — every reformatted line appears as a deletion and insertion, even though the content is unchanged. Tools like git diff --ignore-space-change and git diff --ignore-all-space suppress whitespace-only changes from the diff output.

Is the Text Diff tool free? Yes — completely free, no sign-up required.

Try the Text Diff tool free at sadiqbd.com — compare any two texts and see exactly what changed, with word-level highlighting.

Share: Facebook WhatsApp LinkedIn Email

Text Diff

Free, instant results — no sign-up required.

Open Text Diff →
Similar Tools
Word & Character Counter String Repeater Text to Slug ROT13 Encoder Lorem Ipsum Generator Find & Replace Morse Code Translator Sort Lines
Text Diff in Practice: Legal Redlining, Code Review, and How AI Writing Assistants Show Changes
Text Tools
Text Diff in Practice: Legal Redlining, Code Review, and How AI Writing Assistants Show Changes
How Plagiarism Detection Actually Works: From Exact-Match Shingling to Semantic Similarity, and Why Each Has Limits
Text Tools
How Plagiarism Detection Actually Works: From Exact-Match Shingling to Semantic Similarity, and Why Each Has Limits
Why Text Diff Tools Work at Line Level (Not Character Level): Edit Distance, Granularity, and the Unified Diff Format
Text Tools
Why Text Diff Tools Work at Line Level (Not Character Level): Edit Distance, Granularity, and the Unified Diff Format
Why Git Merge Conflicts Occur Exactly Where They Do — Three-Way Merge, diff3, and Semantic Conflicts
Text Tools
Why Git Merge Conflicts Occur Exactly Where They Do — Three-Way Merge, diff3, and Semantic Conflicts