Text Diff

Porovnejte dva texty vedle sebe a zvýrazněte rozdíly řádek po řádku

Zkusit příklad

Text A

Text B

Běží lokálně · Bezpečné pro vkládání tajných údajů
Běží lokálně · Bezpečné pro vkládání tajných údajů

Co je text diff?

Text diff (zkratka anglického slova „difference”, tedy rozdíl) je výsledek porovnání dvou bloků textu za účelem identifikace přidaných, odebraných nebo nezměněných řádků. Koncept pochází z unixového nástroje diff, který byl poprvé vydán v roce 1974 jako součást Version 5 Unix. Dnes je text diff základem verzovacích systémů jako Git, kde každý commit ukládá diff namísto úplné kopie každého souboru.

Diff algoritmus hledá Nejdelší společnou podposloupnost (LCS) mezi dvěma sekvencemi řádků. Řádky obsažené v LCS jsou označeny jako nezměněné. Řádky v původním textu, které v LCS chybí, jsou označeny jako odebrané. Řádky v upraveném textu, které v LCS chybí, jsou označeny jako přidané. Výsledkem je minimální sada změn potřebných k transformaci jednoho textu na druhý.

Výstup diff nástroje existuje v několika formátech. Unified diff (výchozí formát pro git diff) označuje odebrané řádky znaménkem minus a přidané řádky znaménkem plus. Side-by-side diff zobrazuje oba texty ve vedlejších sloupcích. Tento nástroj používá porovnání řádek po řádku s barevně odlišeným výstupem: zelená pro přidané, červená pro odebrané a neutrální pro nezměněné řádky. Nezměněné řádky se zobrazují bez předpony, lze je však skrýt, aby bylo vidět pouze to, co se změnilo.

Proč používat online diff nástroj?

Porovnávání textů v terminálu vyžaduje instalaci diff nástrojů a znalost přepínačů příkazové řádky. Diff nástroj v prohlížeči tuto překážku zcela odstraňuje.

Okamžité porovnání
Vložte dva textové bloky a ihned si zobrazte zvýrazněné rozdíly. Žádné vytváření souborů, žádné příkazy k zapamatování, žádný výstup k analýze.
🔒
Zpracování s ohledem na soukromí
Veškeré porovnání probíhá ve vašem prohlížeči pomocí JavaScriptu. Váš text nikdy neopustí vaše zařízení, což je důležité při porovnávání konfiguračních souborů, přihlašovacích údajů nebo proprietárního kódu.
📋
Výstup připravený ke kopírování
Výstup diff nástroje používá standardní předpony + / -, které odpovídají unified diff formátu. Výsledek můžete přímo zkopírovat do zpráv commitů, komentářů ke code review nebo hlášení chyb.
🌐
Bez přihlášení ani instalace
Funguje na jakémkoli zařízení s prohlížečem. Žádné vytváření účtu, žádné rozšíření, žádná desktopová aplikace. Otevřete stránku a začněte porovnávat.

Případy použití text diff nástroje

Frontend vývoj
Porovnejte minifikovaný CSS nebo HTML výstup před sestavením a po něm, abyste odhalili nechtěné změny ve vygenerovaném značení nebo stylech.
Backend inženýrství
Porovnejte odpovědi API napříč prostředími (staging vs. produkce) a ověřte, zda nasazení nezavedlo neočekávané změny dat.
DevOps a infrastruktura
Porovnejte Kubernetes manifesty, Terraform plány nebo konfigurační soubory Nginx před aplikováním změn na živý cluster nebo server.
QA a testování
Ověřte, zda výstup testu odpovídá očekávaným výchozím hodnotám, porovnáním skutečného výsledku s uloženým snapshotem.
Datové inženýrství
Porovnejte hlavičky CSV nebo definice SQL schémat napříč databázovými migracemi a potvrďte, zda byly sloupce správně přidány nebo přejmenovány.
Výuka a studium
Porovnejte své řešení s referenční implementací řádek po řádku a zjistěte, kde se vaše logika odchyluje od očekávaného přístupu.

Porovnání formátů výstupu diff

Diff nástroje produkují výstup v několika formátech. Níže uvedená tabulka shrnuje nejčastěji používané formáty, co je generuje a kdy je který užitečný.

FormátNástroj / ZdrojPopis
Unified diffdiff -u / git diffPrefixes lines with + / - / space; includes @@ hunk headers
Side-by-sidediff -y / sdiffTwo columns, changed lines aligned horizontally
Context diffdiff -cShows changed lines with surrounding context, marked with ! / + / -
HTML diffPython difflibColor-coded HTML table with inline change highlights
JSON PatchRFC 6902Array of add/remove/replace operations on a JSON document

Jak funguje line diff: algoritmus LCS

Většina line-diff nástrojů, včetně tohoto, používá algoritmus Nejdelší společné podposloupnosti (LCS). LCS nalezne největší sadu řádků, které se v obou textech vyskytují ve stejném relativním pořadí, aniž by musely být sousední. Řádky, které nejsou v LCS, jsou skutečnými rozdíly.

Standardní algoritmus LCS využívá dynamické programování a běží v čase O(m × n), kde m a n jsou počty řádků obou textů. Pro velké soubory optimalizované varianty jako Myersův diff algoritmus (používaný Gitem) tuto složitost snižují na O(n + d²), kde d je počet rozdílů, čímž je výpočet rychlý v případě, kdy je většina řádků sdílená.

1. Sestavení DP tabulky
Vytvořte matici (m+1) × (n+1). Pro každý pár řádků uložte délku dosud nejdelší nalezené společné podposloupnosti. Shodné řádky prodlouží diagonální hodnotu o 1.
2. Zpětné sledování
Procházejte od pravého dolního rohu matice zpět k (0,0). Diagonální pohyby na shodných řádcích vytvářejí záznamy „nezměněno”. Horizontální nebo vertikální pohyby vytvářejí záznamy „přidáno” nebo „odebráno”.
3. Vykreslení výstupu
Každý záznam namapujte na zobrazovaný řádek: nezměněné řádky nemají předponu, přidané řádky mají +, odebrané řádky mají -. Pro vizuální přehlednost použijte barevné kódování.

Příklady kódu

Implementace porovnání textu řádek po řádku v JavaScriptu, Pythonu, Go a na příkazové řádce. Každý příklad produkuje výstup ve stylu unified diff.

JavaScript
// Line-by-line diff using the LCS algorithm
function diffLines(a, b) {
  const linesA = a.split('\n')
  const linesB = b.split('\n')

  // Build LCS table
  const m = linesA.length, n = linesB.length
  const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0))
  for (let i = 1; i <= m; i++)
    for (let j = 1; j <= n; j++)
      dp[i][j] = linesA[i-1] === linesB[j-1]
        ? dp[i-1][j-1] + 1
        : Math.max(dp[i-1][j], dp[i][j-1])

  // Backtrack to produce diff
  const result = []
  let i = m, j = n
  while (i > 0 || j > 0) {
    if (i > 0 && j > 0 && linesA[i-1] === linesB[j-1]) {
      result.unshift({ type: 'equal', text: linesA[i-1] }); i--; j--
    } else if (j > 0 && (i === 0 || dp[i][j-1] >= dp[i-1][j])) {
      result.unshift({ type: 'add', text: linesB[j-1] }); j--
    } else {
      result.unshift({ type: 'remove', text: linesA[i-1] }); i--
    }
  }
  return result
}

const diff = diffLines("alpha\nbeta\ngamma", "alpha\nbeta changed\ngamma\ndelta")
// → [
//   { type: 'equal',  text: 'alpha' },
//   { type: 'remove', text: 'beta' },
//   { type: 'add',    text: 'beta changed' },
//   { type: 'equal',  text: 'gamma' },
//   { type: 'add',    text: 'delta' }
// ]
Python
import difflib

text_a = """alpha
beta
gamma""".splitlines()

text_b = """alpha
beta changed
gamma
delta""".splitlines()

# Unified diff (same format as git diff)
for line in difflib.unified_diff(text_a, text_b, fromfile='a.txt', tofile='b.txt', lineterm=''):
    print(line)
# --- a.txt
# +++ b.txt
# @@ -1,3 +1,4 @@
#  alpha
# -beta
# +beta changed
#  gamma
# +delta

# HTML side-by-side diff
d = difflib.HtmlDiff()
html = d.make_file(text_a, text_b, fromdesc='Original', todesc='Modified')
Go
package main

import (
	"fmt"
	"strings"
)

// Minimal LCS-based line diff
func diffLines(a, b string) {
	la := strings.Split(a, "\n")
	lb := strings.Split(b, "\n")
	m, n := len(la), len(lb)

	dp := make([][]int, m+1)
	for i := range dp {
		dp[i] = make([]int, n+1)
	}
	for i := 1; i <= m; i++ {
		for j := 1; j <= n; j++ {
			if la[i-1] == lb[j-1] {
				dp[i][j] = dp[i-1][j-1] + 1
			} else if dp[i-1][j] >= dp[i][j-1] {
				dp[i][j] = dp[i-1][j]
			} else {
				dp[i][j] = dp[i][j-1]
			}
		}
	}

	var result []string
	i, j := m, n
	for i > 0 || j > 0 {
		if i > 0 && j > 0 && la[i-1] == lb[j-1] {
			result = append([]string{" " + la[i-1]}, result...)
			i--; j--
		} else if j > 0 && (i == 0 || dp[i][j-1] >= dp[i-1][j]) {
			result = append([]string{"+" + lb[j-1]}, result...)
			j--
		} else {
			result = append([]string{"-" + la[i-1]}, result...)
			i--
		}
	}

	for _, line := range result {
		fmt.Println(line)
	}
}

// Output:
//  alpha
// -beta
// +beta changed
//  gamma
// +delta
CLI (diff / git)
# Compare two files with unified diff (3 lines of context)
diff -u original.txt modified.txt

# Git diff between working tree and last commit
git diff HEAD -- file.txt

# Git diff between two branches
git diff main..feature -- src/

# Side-by-side diff in the terminal
diff -y --width=120 original.txt modified.txt

# Color-coded diff (requires colordiff)
diff -u original.txt modified.txt | colordiff

Nejčastěji kladené otázky

Jaký je rozdíl mezi line diff a character diff?
Line diff porovnává text řádek po řádku: pokud se na řádku změní jakýkoli znak, celý řádek je označen jako odebraný a nová verze jako přidaná. Character diff (nebo word diff) pracuje na jemnější úrovni granularity a označuje konkrétní znaky nebo slova, která se na řádku změnila. Line diff je standardní pro code review; character diff je užitečnější při editaci prózy.
Jak funguje git diff interně?
Git ve výchozím nastavení používá Myersův diff algoritmus, který hledá nejkratší editační skript (minimální počet vložení a smazání) mezi dvěma soubory. Git ukládá výsledek ve formátu unified diff s hlavičkami @@ označujícími čísla řádků. Když spustíte git diff, Git porovnává pracovní strom s indexem (staging area), nikoli s posledním commitem, pokud explicitně nepředáte HEAD.
Mohu porovnávat binární soubory pomocí text diff nástroje?
Ne. Text diff nástroje rozdělují vstup na základě znaků nového řádku a porovnávají řetězce. Binární soubory obsahují libovolné sekvence bajtů, které produkují nesmyslná dělení na řádky. Pro porovnání binárních souborů použijte hex diff nástroj nebo porovnání kontrolních součtů na úrovni souborů (sha256sum na obou souborech).
Jsou moje data odesílána na server při použití tohoto nástroje?
Ne. Tento nástroj běží výhradně ve vašem prohlížeči. Výpočet diff používá JavaScript implementaci LCS, která se spouští na straně klienta. Se svým textovým obsahem nejsou prováděny žádné síťové požadavky. Ověřit to můžete otevřením záložky Síť v nástrojích pro vývojáře prohlížeče během používání nástroje.
Co je unified diff formát?
Unified diff je výstupní formát používaný příkazy diff -u a git diff. Zobrazuje změněné řádky s předponami - (odebrané) a + (přidané), před nimiž jsou hlavičky @@, které specifikují rozsahy čísel řádků v obou souborech. Kontextové řádky (nezměněné) mají předponu mezery. Unified diff je nejrozšířenější formát pro patche, pull requesty a nástroje pro code review.
Jak porovnám velké soubory s mnoha rozdíly?
Pro soubory s tisíci řádků nástroj v prohlížeči funguje, ale může se zpomalit, protože algoritmus LCS škáluje kvadraticky. Pro velmi velké diff operace jsou nástroje příkazové řádky jako diff nebo git diff rychlejší, protože využívají optimalizované C implementace a mohou výstup streamovat. Nezměněné řádky lze také skrýt (vypněte možnost „Zobrazit nezměněné řádky” v tomto nástroji) a soustředit se pouze na změny.
Co je three-way merge diff?
Three-way merge porovnává dvě upravené verze souboru s jejich společným předkem (základem). Git to využívá při git merge a git rebase. Identifikuje změny provedené v každé větvi vůči základu a spojuje je. Pokud obě větve upraví stejný řádek, Git hlásí konflikt při slučování. Three-way merge vyžaduje tři vstupy, zatímco standardní diff potřebuje pouze dva.