Text Diff

Jämför två texter sida vid sida och markera radbaserade skillnader

Prova ett exempel

Text A

Text B

Körs lokalt · Säkert att klistra in hemligheter
Körs lokalt · Säkert att klistra in hemligheter

Vad är Text Diff?

En text diff (förkortning av "difference", skillnad) är resultatet av att jämföra två textblock och identifiera vilka rader som lagts till, tagits bort eller lämnats oförändrade. Konceptet härstammar från Unix-verktyget diff, som lanserades 1974 som en del av Version 5 Unix. I dag är text diff ryggraden i versionskontrollsystem som Git, där varje incheckning lagrar en diff snarare än en fullständig kopia av varje fil.

En diff-algoritm hittar den längsta gemensamma delföljden (Longest Common Subsequence, LCS) mellan två sekvenser av rader. Rader som ingår i LCS markeras som oförändrade. Rader i originaltexten som inte ingår i LCS markeras som borttagna. Rader i den modifierade texten som inte ingår i LCS markeras som tillagda. Resultatet är en minimal uppsättning ändringar som behövs för att omvandla en text till den andra.

Diff-utdata finns i flera format. Unified diff (standardformat för git diff) prefixar borttagna rader med ett minustecken och tillagda rader med ett plustecken. Side-by-side diff arrangerar båda texterna i parallella kolumner. Det här verktyget använder radbaserad jämförelse med färgkodad utdata: grönt för tillägg, rött för borttagningar och neutralt för oförändrade rader. Oförändrade rader visas utan prefix som standard men kan döljas för att fokusera enbart på vad som ändrats.

Varför använda ett textjämförelseverktyg online?

Att jämföra text i en terminal kräver installation av diff-verktyg och hantering av kommandoradsflaggor. Ett webbläsarbaserat diff-verktyg tar bort all den friktionen.

Omedelbar jämförelse
Klistra in två textblock och se skillnaderna markerade direkt. Ingen filskapning, inga kommandon att komma ihåg, ingen utdata att tolka.
🔒
Integritetsskyddad bearbetning
All jämförelse sker i din webbläsare med JavaScript. Din text lämnar aldrig din enhet, vilket är viktigt när du jämför konfigurationsfiler, inloggningsuppgifter eller proprietär kod.
📋
Kopierbar utdata
Diff-utdatan använder standard + / - prefix som matchar unified diff-formatet. Du kan kopiera resultatet direkt in i incheckningsmeddelanden, kodgranskningskommentarer eller felrapporter.
🌐
Inget konto eller installation krävs
Fungerar på alla enheter med en webbläsare. Ingen kontoregistrering, inget tillägg, ingen skrivbordsapp. Öppna sidan och börja jämföra.

Användningsfall för Text Diff

Frontendutveckling
Jämför minifierad CSS eller HTML-utdata före och efter ett byggsteg för att fånga upp oavsiktliga ändringar i genererad uppmärkning eller stilar.
Backendteknik
Jämför API-svar mellan miljöer (staging mot produktion) för att verifiera att en driftsättning inte introducerade oväntade dataändringar.
DevOps och infrastruktur
Jämför Kubernetes-manifest, Terraform-planer eller Nginx-konfigurationer innan ändringar appliceras på ett aktivt kluster eller en server.
QA och testning
Verifiera att testutdata matchar förväntade baslinjer genom att jämföra det faktiska resultatet mot en lagrad snapshot-fil.
Datateknik
Jämför CSV-rubriker eller SQL-schemadefinitioner över databasmigreringar för att bekräfta att kolumner lagts till eller döpts om korrekt.
Lärande och kursarbete
Jämför din lösning med en referensimplementation rad för rad för att hitta var din logik avviker från det förväntade tillvägagångssättet.

Diff-utdataformat jämförda

Diff-verktyg producerar utdata i flera format. Tabellen nedan sammanfattar de vanligaste, vad som genererar dem och när varje format är användbart.

FormatVerktyg / KällaBeskrivning
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

Hur radbaserad diff fungerar: LCS-algoritmen

De flesta radbaserade diff-verktyg, inklusive det här, använder algoritmen Longest Common Subsequence (LCS). LCS hittar den största uppsättningen rader som förekommer i båda texterna i samma relativa ordning, utan att kräva att de är sammanhängande. Raderna som inte ingår i LCS är de faktiska skillnaderna.

Standard-LCS-algoritmen använder dynamisk programmering och körs i O(m x n) tid, där m och n är radantalet i de två texterna. För stora filer reducerar optimerade varianter som Myers' diff-algoritm (används av Git) detta till O(n + d^2) där d är antalet skillnader, vilket gör den snabb när de flesta rader är gemensamma.

1. Bygg DP-tabellen
Skapa en (m+1) x (n+1)-matris. För varje radpar lagras längden på den längsta gemensamma delföljden som setts hittills. Lika rader utökar diagonalvärdet med 1.
2. Spåra bakåt
Gå från matrisens nedre högra hörn tillbaka till (0,0). Diagonala rörelser på lika rader ger poster markerade "oförändrad". Horisontella eller vertikala rörelser ger poster markerade "tillagd" eller "borttagen".
3. Rendera utdata
Mappa varje post till en visningsrad: oförändrade rader får inget prefix, tillagda rader får +, borttagna rader får -. Applicera färgkodning för visuell tydlighet.

Kodexempel

Implementationer av radbaserad textjämförelse i JavaScript, Python, Go och på kommandoraden. Varje exempel producerar unified-stilad diff-utdata.

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

Vanliga frågor

Vad är skillnaden mellan en radbaserad diff och en teckenbaserad diff?
En radbaserad diff jämför text rad för rad: om ett tecken på en rad ändras markeras hela raden som borttagen och den nya versionen markeras som tillagd. En teckenbaserad diff (eller ordbaserad diff) arbetar på en finare detaljnivå och markerar de specifika tecken eller ord som ändrats inom en rad. Radbaserad diff är standard för kodgranskning; teckenbaserad diff är mer användbar för redigering av löptext.
Hur fungerar git diff internt?
Git använder Myers' diff-algoritm som standard, som hittar det kortaste redigeringsskriptet (det minsta antalet infogningar och borttagningar) mellan två filer. Git lagrar resultatet i unified diff-format med @@-hunk-rubriker som anger radnummer. När du kör git diff jämför Git arbetsträdet mot indexet (staging area), inte den senaste incheckningen, såvida du inte anger HEAD explicit.
Kan jag jämföra binära filer med ett textbaserat diff-verktyg?
Nej. Textbaserade diff-verktyg delar upp indata vid radbrytningar och jämför strängar. Binära filer innehåller godtyckliga bytesekvenser som ger meningslösa radindelningar. För binär jämförelse använder du ett hex diff-verktyg eller en kontrollsummejämförelse på filnivå (sha256sum på båda filerna).
Skickas mina data till en server när jag använder det här verktyget?
Nej. Det här verktyget körs helt i din webbläsare. Diff-beräkningen använder en JavaScript LCS-implementation som körs på klientsidan. Inga nätverksförfrågningar görs med ditt textinnehåll. Du kan verifiera detta genom att öppna webbläsarens nätverksflik medan du använder verktyget.
Vad är unified diff-formatet?
Unified diff är utdataformatet som används av diff -u och git diff. Det visar ändrade rader med - (borttagen) och + (tillagd) prefix, föregångna av @@-rubriker som anger radnummerintervall i båda filerna. Kontextrader (oförändrade) har ett blankstegsprefix. Unified diff är det vanligaste formatet för patchar, pull requests och kodgranskningsverktyg.
Hur jämför jag stora filer med många skillnader?
För filer med tusentals rader fungerar ett webbläsarbaserat verktyg men kan bli långsamt eftersom LCS-algoritmen skalas kvadratiskt. För mycket stora diffs är kommandoradsverktyg som diff eller git diff snabbare eftersom de använder optimerade C-implementationer och kan strömma utdata. Du kan också filtrera bort oförändrade rader (stäng av "Visa oförändrade rader" i det här verktyget) för att fokusera enbart på ändringar.
Vad är en trevägsfusion (three-way merge diff)?
En trevägsfusion jämför två modifierade versioner av en fil mot deras gemensamma förfader (basen). Git använder detta under git merge och git rebase. Den identifierar ändringar gjorda i varje gren i förhållande till basen och kombinerar dem. När båda grenarna modifierar samma rad rapporterar Git en sammanslagningskonflikt. En trevägsfusion kräver tre indata, medan en standard diff bara behöver två.