Text Diff online: confrontare due testi con LCS/Myers + 6 casi reali
Uno strumento di text diff online risponde a una sola domanda: cosa è cambiato fra la versione A e la versione B? Incolli due blocchi di testo, lo strumento esegue un algoritmo Longest Common Subsequence e ottieni una vista affiancata o unificata di ogni inserimento, rimozione e modifica, quasi sempre in meno di un millisecondo.
Questa guida è per gli sviluppatori che fanno code review, gli SRE che confrontano slice di log, gli avvocati che fanno redline di contratti e gli autori che rivedono le bozze. Copre l’algoritmo (LCS, Myers, Patience), le due viste standard, le opzioni di ignore che risolvono il 95% dei reclami “sembra tutto cambiato”, quando passare a un JSON diff, sei casi d’uso copia-e-incolla e le insidie che l’algoritmo stesso spiega.
Vuoi confrontare subito due testi? Apri Text Diff: gira interamente nel tuo browser, niente upload.
1. Cos’è un Text Diff?
Un text diff è l’insieme minimo di inserimenti e rimozioni che trasforma un testo nell’altro, con ogni riga marcata come aggiunta, rimossa o invariata. I diff moderni aggiungono una seconda passata a livello di parola o carattere, così una modifica di un solo carattere evidenzia solo quel token invece dell’intera riga.
1.1 Perché l’uguaglianza fra caratteri (===) non basta
Inserisci una riga in cima a un file di configurazione di 200 righe e un confronto ingenuo carattere per carattere segnala ogni singolo byte dopo il punto di inserimento come diverso. Il testo non è cambiato, è cambiata la sua posizione. Un algoritmo di diff deve riconoscere che “le 199 righe successive sono ancora le stesse righe, solo spostate di una” e segnalare un singolo inserimento. Questo riconoscimento te lo dà LCS ed è il motivo per cui git, GitHub e ogni strumento di code review ne integrano uno.
1.2 Vista affiancata vs diff unificato
La vista affiancata mette le due versioni in colonne parallele e colora le celle: verde per le aggiunte, rosso per le rimozioni, giallo per le modifiche. Il diff unificato è il formato testuale più vecchio nato da GNU diff: una sola colonna, marcatori - e +, tre righe di contesto attorno a ogni hunk. Stesso confronto, due presentazioni. La Sezione 4 spiega quando usare l’una o l’altra.
1.3 Dove si usa il text diff
Code review su GitHub e GitLab. Output di git diff in locale. Patch incollate su Slack. Redline di contratti. Revisione di traduzioni. Snapshot test in CI che falliscono con output +/-. Investigazione di una timeline di log. Confronto di due file .env. Qualsiasi situazione in cui due blob di testo vanno allineati riga per riga.
Apri Text Diff e incolla due testi per vedere tutto questo in azione: ogni confronto gira localmente dentro il tuo browser.
2. L’algoritmo dietro il Text Diff (LCS + Myers + Patience)
2.1 Longest Common Subsequence
Date due sequenze di righe A e B, la Longest Common Subsequence è la lista più lunga di righe che compaiono in entrambe, nello stesso ordine, senza richiedere adiacenza. Una volta ottenuta la LCS, il diff è immediato: le righe di A che non stanno nella LCS sono rimosse, le righe di B che non stanno nella LCS sono aggiunte, le righe nella LCS restano invariate.
La LCS classica gira come una tabella di programmazione dinamica di dimensione N × M. La cella (i, j) contiene la lunghezza della LCS delle prime i righe di A e delle prime j righe di B. Riempi la tabella da sinistra a destra, dall’alto verso il basso, poi ripercorri all’indietro dalla cella in basso a destra per ricostruire lo script di edit. Tempo e spazio sono entrambi O(N×M): ottimo per due file da mille righe, lento per un log da centomila righe.
2.2 Myers (1986)
Il paper di Eugene Myers del 1986 “An O(ND) Difference Algorithm and Its Variations” riformula il problema come cammino minimo in un grafo di edit: i nodi sono posizioni (i, j) nei due input, i passi orizzontali sono rimozioni, i passi verticali sono inserimenti, i passi diagonali sono match. Il cammino minimo è lo script di edit minimo.
Myers gira in O((N+M)D), dove D è la dimensione dello script di edit. Quando i due testi sono simili (il caso tipico per un diff) D è piccolo e l’algoritmo è di fatto lineare. È il default in git diff, in GNU diff e nel renderer dei PR di GitHub. Per la stragrande maggioranza degli input web è la risposta giusta.
2.3 Patience diff (Bram Cohen, 2005)
Patience diff segue un approccio diverso: trova righe che compaiono esattamente una volta in ciascun input (le “righe di ancoraggio uniche”), le abbina e ricorre sugli intervalli fra gli ancoraggi. La matematica è più sporca (nel caso peggiore resta cattiva) ma l’output sul codice si legge molto meglio.
Perché? Myers minimizza la distanza di edit, che è matematicamente ottima ma poco leggibile quando l’allineamento ottimo attraversa parentesi graffe o righe vuote senza alcun legame. Patience si rifiuta di allineare su boilerplate comuni (ogni file ha righe }, ogni file ha righe vuote), così i confini fra funzioni restano intatti. Bram Cohen lo inventò per Bazaar; Git lo offre come git diff --patience. L’algoritmo Histogram, strettamente correlato (git diff --histogram), è leggermente più veloce con qualità di output simile.
Immagina due versioni dello stesso file in cui una funzione si è spostata. Myers può allineare la parentesi graffa di chiusura della funzione A con quella della funzione B e segnalare i corpi come completamente diversi. Patience si ancora ai nomi unici delle funzioni e riporta uno spostamento pulito. Stesso input, esperienza di revisione molto diversa.
2.4 Confronto fra algoritmi
| Proprietà | Myers (default) | Patience | Histogram |
|---|---|---|---|
| Complessità temporale | O((N+M)D) | ~O(N log N) caso comune | simile a Patience |
| Distanza di edit ottima | Sì, script minimo | No, può essere più lungo | No, può essere più lungo |
| Lettura naturale sul codice | A volte disallinea graffe e righe vuote | Eccellente, si ancora alle righe uniche | Eccellente |
| Usato da | git default, GNU diff, UI GitHub | git diff --patience, Bazaar | git diff --histogram |
| Indicato per | Velocità e correttezza sulla maggior parte degli input | Code review, diff di refactor | Come Patience, leggermente più veloce |
2.5 Cosa fa questo strumento
Text Diff usa una LCS classica con programmazione dinamica e due ottimizzazioni aggressive: trimming del prefisso e del suffisso comune e una seconda passata di LCS a livello di token per il diff intralinea a livello di parola. Un diff fra due config da duemila righe con una sola riga modificata collassa, dopo il trimming, in una tabella DP 1×1 e si rende in meno di un millisecondo. Per gli input web tipici la scelta fra Myers e DP è invisibile: entrambi finiscono prima che il browser riesca a disegnare il risultato.
3. Diff intralinea a livello di parola: perché un cambio di un carattere evidenzia tutta la riga
Cambi un identificatore in una riga e l’intera riga si accende di rosso e verde. Bug? No, design.
Il diff esegue prima la LCS a livello di riga: “la riga 14 è stata sostituita”. Poi, per ogni coppia sostituita, esegue una seconda LCS a livello di token. I token nascono spezzando sui confini di parola Unicode: sequenze di lettere e cifre restano unite, spazi e segni di punteggiatura diventano ciascuno un token a sé. La seconda LCS produce lo script di edit minimo a livello di token dentro quella riga.
Il renderer disegna la riga intera con il colore di evidenza così l’occhio la trova, poi colora solo i token cambiati con lo sfondo brillante. I token invariati attorno portano una versione attenuata dello stesso colore: presenti ma poco invadenti. L’occhio atterra sull’edit esatto.
Esempio 1: rinomina di un identificatore. function getUser(id) diventa function getUser(userId). L’intera riga è marcata come modificata. Dentro la riga solo id (barrato rosso) e userId (verde brillante) portano l’evidenza intralinea. Tutto il resto resta attenuato.
Esempio 2: cambio di latenza in un log. POST /api/orders 201 88ms diventa POST /api/orders 201 4200ms. La riga è modificata. In intralinea solo 88 e 4200 sono brillanti. Path, metodo e codice di stato restano attenuati: è quello che serve a chi legge una timeline d’incidente.
Quando troppi token cambiano, l’evidenza a livello di parola diventa rumore. Lo strumento ricade su una presentazione a coppia rimozione + aggiunta: la riga originale mostrata come rimossa, la nuova riga mostrata come aggiunta, niente colorazione intralinea. La soglia è grossomodo “più di metà dei token differisce”.
In sintesi: il diff a livello di riga ti dice quale riga è cambiata; il diff a livello di parola ti dice quali caratteri su quella riga portano il cambio. Clicca Sample dentro Text Diff per vedere entrambe le viste sullo stesso input.
4. Vista affiancata vs diff unificato: due viste, un solo diff
4.1 Vista affiancata
Due colonne: originale a sinistra, modificato a destra. Le righe che combaciano sono allineate orizzontalmente. Le righe aggiunte compaiono solo nella colonna destra con sfondo verde; le righe rimosse compaiono solo nella colonna sinistra con sfondo rosso; le coppie modificate stanno una accanto all’altra con una guida gialla e le evidenze intralinea a livello di parola.
Usa la vista affiancata quando un essere umano leggerà il diff: review di PR, didattica, demo, accompagnare un interlocutore non tecnico in una modifica contrattuale. È la vista per gli occhi.
Il rovescio: non viaggia. Non puoi incollare una resa affiancata su Slack e farla applicare a qualcuno. Non puoi farla scorrere in pipe verso patch. Per condividerla e applicarla serve la versione unificata.
4.2 Formato diff unificato
Il diff unificato è un formato testuale di cinquant’anni definito da GNU diff e standardizzato in POSIX. Un esempio completo:
--- original
+++ modified
@@ -1,3 +1,4 @@
1. The service is provided as-is.
2. Either party may terminate with 30 days notice.
+2a. Termination notice must be in writing.
3. Disputes are resolved in California courts.
Le prime due righe indicano i file sorgente. La riga @@ -L,C +L,C @@ è l’intestazione di hunk: -L,C significa “partendo dalla riga L dell’originale, sono coinvolte C righe”; +L,C dice lo stesso per la versione modificata. Dentro l’hunk, le righe che iniziano con uno spazio sono di contesto (invariate), - è rimosso, + è aggiunto.
Tre righe di contesto sopra e sotto ogni cambio è il default di GNU. Quasi tutti gli strumenti permettono di cambiarlo con -U n: diff -U0 per nessun contesto, diff -U10 per dieci righe. L’intestazione di hunk traccia il valore scelto.
In Text Diff, clicca la tab Unified per cambiare vista oppure clicca Copy unified diff per portare la patch negli appunti.
4.3 Dove il diff unificato è portabile
Il diff unificato viaggia. È la moneta universale dei cambi testuali.
| Destinazione | Accetta il diff unificato? | Come |
|---|---|---|
GNU patch | Sì | patch -p1 < diff.patch |
git apply | Sì | git apply diff.patch |
| Commento di review di PR su GitHub | Sì (in un blocco ```diff) | Si rende con i colori |
| Commento di MR su GitLab | Sì | Stesso blocco fenced |
| PR su Bitbucket / Azure DevOps | Sì | Stesso blocco fenced |
| Incolla in Slack / Discord | Parziale | Si rende come testo in un code block, senza colori |
| ”Open Patch” di VS Code | Sì | Applica la patch da Source Control |
| Corpo di issue Jira / Linear | Parziale | Funziona in un code block, niente bottone apply |
Le stesse nove righe di testo ---/+++/@@ si applicano con patch, con git apply, si rendono su tre piattaforme di PR e sopravvivono a un incolla su Slack. Nessun altro formato di diff arriva neanche vicino a questa diffusione.
4.4 Quando scegliere quale
Affiancata per la review, unificata per condivisione e applicazione. Se stai leggendo il diff tu, le colonne sono più veloci. Se qualcuno o qualcosa a valle dovrà consumarlo (un revisore, uno strumento, un comando patch) copia il formato unificato.
5. Opzioni Ignore: spazi, maiuscole, righe vuote, fine riga
La maggior parte dei reclami “sembra tutto cambiato” è rumore. Quattro toggle ne risolvono il 95%.
- Ignore case mappa
Asua. Equivalente agit diff -i. Usalo per confronti di variabili d’ambiente, audit di stile sulle parole chiave SQL, ovunque la convenzione sia maiuscole urlate contro minuscole sommesse ma il significato sia identico. - Ignore all whitespace collassa ogni spazio, tab e newline prima del confronto. Equivalente a
git diff -w. La cura per la riformattazione tab ↔ spazi, le riscritture di indentazione e i diff “siamo passati a Prettier” che distruggono il conteggio delle righe. Un diff con ignore whitespace su quei cambi tipicamente passa da 87 modifiche a 4. - Ignore trailing spaces and tabs rimuove solo lo spazio bianco a fine riga. Equivalente a
git diff -b. La cura per il rumore CRLF dopo aver copiato file fra macchine Windows e Unix: i caratteri\ra fine riga vengono filtrati e il contenuto vero si allinea. - Ignore blank lines scarta le righe vuote prima del diff. La cura per il classico “ho aggiunto un’interruzione di paragrafo e ora il paragrafo 12 sembra completamente diverso” nei diff di prosa.
Una config di 200 righe che riporta “87 modifications” tipicamente scende a “4 modifications” con Ignore all whitespace. Una copia da Windows a Unix che segnala ogni riga scende a zero con Ignore trailing spaces. Ogni toggle è indipendente e persiste fra sessioni.
CRLF vs LF. I fine riga Windows sono \r\n; Unix è \n; classico Mac è \r. Apri un file Windows in un editor Unix che non normalizza e ti resta il \r finale. Ogni riga risulterà come “il contenuto combacia ma c’è un \r alla fine”. Ignore trailing spaces silenzia questo senza perdere i cambi veri.
Un avvertimento. Le opzioni di ignore sono a doppio taglio. Attiva Ignore case e un refactor che cambia LOG.error in log.Error sembra identico. Attiva Ignore all whitespace e un bug di indentazione in Python diventa invisibile. Scegli i toggle in base alla domanda che stai facendo, poi spegnili quando hai finito.
6. Text Diff vs JSON Diff vs Git Diff: matrice di decisione
Il text diff è matching a livello di riga e parola senza alcuna comprensione della struttura. È quello che vuoi per la prosa e quello che non vuoi per il JSON.
6.1 Matrice di decisione
| Tipo di input | Text diff | JSON diff | Git diff |
|---|---|---|---|
| Prosa / Markdown / contratto | Migliore | Strumento sbagliato | Parziale (solo su file tracciati) |
| Snippet di codice (incolla singolo file) | Migliore | Strumento sbagliato | Parziale (serve un repo) |
| Codice in un repo (multi-file) | Parziale | Strumento sbagliato | Migliore |
| Risposta JSON di un’API | Strumento sbagliato (falsi positivi sull’ordine delle chiavi) | Migliore | Strumento sbagliato |
| Config YAML / TOML | Parziale (falsi positivi sull’ordine delle chiavi) | Migliore (dopo conversione) | Parziale |
| CSV riga per riga | Parziale | Strumento sbagliato | Strumento sbagliato |
| Log / heredoc | Migliore | Strumento sbagliato | Strumento sbagliato |
| File binario | Strumento sbagliato | Strumento sbagliato | git diff --binary |
6.2 Quando il text diff è lo strumento sbagliato
Tre errori classici.
JSON con chiavi riordinate. {"a":1,"b":2} e {"b":2,"a":1} sono lo stesso documento JSON. Un text diff segnala ogni riga come cambiata perché davvero sono righe diverse. Usa JSON Diff: capisce che le chiavi JSON non sono ordinate.
Config YAML riformattati. Cambi un valore, fai passare il file in un formatter e indentazione, ordine delle chiavi e quoting si spostano tutti. Il text diff segnala una riscrittura completa. Converti prima entrambi i file in JSON, poi confronta con JSON Diff.
Refactor multi-file con rinomine. Git traccia le rinomine; il text diff no. Se confronti due alberi concatenando i file in un unico blob, ogni spostamento fra file appare come rimosso + aggiunto. Usa git diff (o git diff --find-renames=80%) invece.
6.3 Quando il text diff è lo strumento giusto
Prosa. Snippet di codice incollati da qualsiasi parte. Redline di contratti. Slice di log. Revisione di traduzioni in cui stai allineando frasi in linguaggio naturale. File .env dove l’ordine conta perché le shell li leggono dall’alto in basso. Qualsiasi cosa in cui le righe stesse portano significato.
Per l’approfondimento sul filtraggio del rumore dai diff JSON (timestamp, request id, UUID generati automaticamente) leggi Come Ignorare Timestamp e ID nel Diff JSON.
7. Sei casi reali (con input copia-e-incolla)
7.1 Snippet di code review: rinomina di una funzione
Stai facendo la review di una PR. L’autore ha rinominato id in userId e aggiunto una guard clause. Incolla entrambe le versioni:
// Original
function getUser(id) {
const u = db.users.find(x => x.id === id);
return u;
}
// Modified
function getUser(userId) {
if (!userId) return null;
const u = db.users.find(x => x.id === userId);
return u;
}
Il diff mostra tre righe modificate più una riga aggiunta. L’evidenza intralinea marca ogni token id → userId; la nuova guard clause appare con sfondo verde. Opzioni di ignore spente. Prova in Text Diff e copia l’output unificato per lasciarlo come commento di review.
7.2 Redline di contratto o policy: una sola clausola inserita
Cinquanta paragrafi di contratto, una clausola inserita. Incolla la versione di ieri a sinistra e quella di oggi a destra:
1. The service is provided as-is.
2. Either party may terminate with 30 days notice.
3. Disputes are resolved in California courts.
1. The service is provided as-is.
2. Either party may terminate with 30 days notice.
2a. Termination notice must be in writing.
3. Disputes are resolved in California courts.
Il diff rende quarantanove righe invariate e una riga aggiunta (+2a. Termination notice must be in writing.). Esporta il diff unificato come tracciamento per la revisione legale.
7.3 Investigazione di una timeline di log
Sospetti una regressione di latenza. Prendi uno slice di access log da prima e durante l’incidente:
GET /api/users 200 14ms
POST /api/orders 201 88ms
GET /api/orders/42 200 21ms
GET /api/users 200 14ms
POST /api/orders 201 4200ms
GET /api/orders/42 500 21ms
L’evidenza intralinea fa emergere 88 → 4200 (un salto di latenza di 50×) e 200 → 500 (un endpoint di dettaglio ordine ha iniziato a fallire). Per un lavoro più ricco sui log (estrarre campi, raggruppare per endpoint, calcolare percentili) abbina il diff con Cheat Sheet jq se i tuoi log sono in JSON.
7.4 Revisione di traduzioni: preservare i placeholder
Hai ingaggiato una nuova agenzia di traduzione e vuoi verificare che la nuova copy combaci con la vecchia nella struttura. Incolla la vecchia traduzione a sinistra, la nuova a destra. Attiva Ignore trailing spaces / tabs perché i traduttori aggiungono spesso uno spazio vagante a fine stringa.
Il diff conferma che ogni {username}, {count} e %s resta al suo posto; cambia solo il testo in linguaggio naturale. Un placeholder mancante appare come token rimosso nel diff intralinea, intercettato prima dello ship. Se ti serve confrontare i formati stessi dei placeholder, il Cheat Sheet Regex copre \{\w+\} e simili. Prova in Text Diff.
7.5 Audit di config o .env: produzione vs staging
Confronta due file .env. Attiva Ignore blank lines così il raggruppamento a paragrafi non disallinea le sezioni. Il diff ti mostra quali chiavi differiscono in valore, quali chiavi esistono in un ambiente e non nell’altro e dove i commenti si sono disallineati. Cinque minuti che prevengono la sessione di debug “funziona in staging ma non in prod”.
7.6 Revisione di prosa o di una bozza
Il tuo editor ti ha rimandato una bozza. Incolla l’originale a sinistra e la versione editata a destra. Il diff intralinea a livello di parola ti mostra quali frasi sono state riscritte, quali sono rimaste intoccate e quali paragrafi sono stati inseriti. Accetta o rifiuta i cambi uno alla volta: niente Revisioni di Word, niente file .docx, niente formato proprietario.
8. Insidie comuni e come leggerle come sintomi
Il comportamento dell’algoritmo spiega gran parte del dolore degli utenti. Cinque reclami frequenti e cosa significano davvero.
Insidia 1: “Ogni riga è rossa dopo una copia Windows → Unix”. Sintomo: ogni riga del diff appare cambiata anche se il contenuto sembra identico. Causa: caratteri \r finali dai fine riga CRLF. Soluzione: attiva Ignore trailing spaces / tabs. Il diff scenderà ai cambi reali.
Insidia 2: “Ho incollato JSON e il 100% delle righe è diverso”. Sintomo: due oggetti JSON che dovrebbero essere equivalenti appaiono completamente cambiati. Causa: riordino delle chiavi. Il text diff tratta l’ordine delle righe come significativo; JSON no. Soluzione: usa JSON Diff per qualsiasi input JSON.
Insidia 3: “La riformattazione tab ↔ spazi ha fatto esplodere il diff”. Sintomo: 87 modifiche, tutte di indentazione. Causa: il tuo formatter ha cambiato lo spazio bianco iniziale di ogni riga. Soluzione: Ignore all whitespace collasserà il rumore e farà emergere i cambi semantici reali.
Insidia 4: “Il diff dice identico ma cmp non è d’accordo”. Sintomo: il diff non riporta differenze ma un confronto a livello di byte dice che i file differiscono. Causa: un’opzione di ignore lasciata accesa da una sessione precedente sta mascherando cambi reali. Soluzione: apri il pannello delle opzioni di ignore, spegni ogni toggle e rifai il diff.
Insidia 5: “Un edit corto appare come rimozione + aggiunta”. Sintomo: un piccolo cambio appare come riga rimossa separata e riga aggiunta separata invece che come evidenza intralinea. Causa: la proporzione di token cambiati ha superato la soglia intralinea e il renderer è ricaduto sulla presentazione a coppia. Questo è design, non un bug. Passa alla vista Unified per vedere la classica coppia -/+ che gli strumenti di patch si aspettano.
9. Privacy, performance e quando passare alla riga di comando
Ogni confronto in Text Diff gira in JavaScript dentro il tuo browser. Niente upload, niente file temporaneo, niente log server, niente analytics sul testo che incolli. Sicuro per codice proprietario, contratti interni, log privati: qualsiasi cosa tu non saresti disposto a incollare in un server di terze parti.
Limiti pratici: circa 5.000 righe o 1 MB per lato. Il live diff si disattiva oltre 200 KB combinati e passa a un pulsante Diff manuale così la digitazione non blocca la pagina. Oltre 5.000 righe l’input viene troncato e compare un avviso. I limiti esistono perché il diff gira sul main thread (niente web worker) e il passaggio a un worker più la serializzazione costerebbero più del diff stesso su input piccoli.
Quando l’input supera le capacità del browser, scendi alla riga di comando:
# Unified diff between two files
diff -u a.txt b.txt
# Same, but using git's diff engine (Patience, Histogram, color)
git diff --no-index a.txt b.txt
git diff --no-index --patience a.txt b.txt
# Streaming diff viewer for huge files (Rust, side-by-side, syntax-aware)
delta a.txt b.txt
Passa alla riga di comando per log da molti megabyte, file binari, diff di repo multi-file, qualsiasi situazione in cui vuoi colorazione syntax-aware come delta, o ovunque tu debba mandare in pipe l’output del diff verso un altro strumento.
10. Unicode, CJK e RTL: note sul text diff internazionale
Il tokenizer spezza sui confini di parola Unicode usando tre categorie: sequenze di parola (lettere \p{L} e numeri \p{N}), punteggiatura non di parola e spazio bianco. Ogni categoria produce i propri token, così hello, world! diventa hello, ,, , world, !: cinque token.
Per contenuti CJK (cinese, giapponese, coreano), ogni ideogramma o kana è un token a sé. Cambia un carattere in una frase cinese e solo quel carattere porta l’evidenza intralinea mentre il resto della riga resta attenuato. La struttura a livello di paragrafo resta basata sulle righe, quindi la riscrittura di una frase che aggiunge un’interruzione di riga appare come edit a livello di riga, non di token.
Per le lingue RTL (arabo, ebraico), il diff usa direzioni CSS logiche (ms-, me- invece di ml-, mr-). Sui locale RTL la guida laterale e le colonne delle righe si invertono naturalmente; dentro ogni cella di diff la direzione del testo segue il contenuto, così le stringhe arabe si rendono da destra a sinistra mentre i marcatori + e - restano allineati alla guida iniziale.
La normalizzazione dei fine riga riconosce \r\n (Windows), \n (Unix) e \r da solo (vecchio Mac OS fino alla versione 9). Tutti e tre si spezzano in righe separate, così un file convertito da una piattaforma all’altra non collassa in un’unica mega-riga.
11. FAQ
Come funziona un text diff online?
Un text diff spezza entrambi gli input in righe, esegue un algoritmo Longest Common Subsequence (tipicamente Myers O((N+M)D)) per trovare l’insieme minimo di inserimenti e rimozioni, poi evidenzia le righe aggiunte (verde), rimosse (rosso) e invariate (grigio). Una seconda LCS a livello di token marca le parole cambiate dentro ciascuna riga modificata. Text Diff esegue l’intero confronto localmente nel tuo browser.
Qual è la differenza tra text diff e JSON diff?
Il text diff confronta riga per riga, va bene per prosa, codice, log e contratti. JSON Diff capisce il modello dati di JSON: l’ordine delle chiavi è irrilevante, i tipi sono stretti (1 ≠ "1"), gli array possono essere allineati per chiave. Incolla JSON in un text diff e i riordini delle chiavi o lo spazio bianco emergeranno come cambi che JSON Diff ignora. Usa il text diff per contenuti non strutturati, JSON Diff per risposte API e config.
Perché il diff mostra righe intere cambiate se ho modificato una sola parola?
In realtà no: la riga è evidenziata perché qualcosa al suo interno è cambiato, ma dentro l’evidenza solo i token cambiati portano lo sfondo brillante (verde per aggiunti, rosso barrato per rimossi). Questo è il diff intralinea a livello di parola: il contesto della riga resta leggibile mentre l’occhio atterra sull’edit esatto. Quando troppi token di una riga sono cambiati perché l’evidenza a livello di parola sia utile, il diff ricade su una coppia rimozione + aggiunta separata così la struttura resta pulita.
Come ignoro spazi, maiuscole o righe vuote nel diff?
Apri il pannello delle opzioni di ignore. Ignore case rende A e a uguali. Ignore all whitespace collassa ogni spazio, tab e newline, equivalente a git diff -w. Ignore trailing spaces and tabs rispecchia git diff -b e silenzia il rumore CRLF. Ignore blank lines scarta le righe vuote così la rispaziatura dei paragrafi non disallinea più il diff. Ogni opzione è indipendente e persiste fra sessioni.
Cos’è il formato diff unificato?
Il diff unificato è il formato testuale ---/+++/@@ -L,C +L,C @@ introdotto da GNU diff alla fine degli anni ‘80 e usato da git, GitHub, GitLab e dal comando Unix patch. Ogni hunk mostra tre righe di contesto attorno al cambio, con - per i rimossi e + per gli aggiunti. Copia l’output unificato in un commento di PR, incollalo in git apply o esegui patch -p1 < diff.patch: si applica senza problemi.
Myers vs Patience: quale algoritmo di diff è migliore per il code review?
Myers è il default in git diff e in GNU diff: veloce e matematicamente minimo, ma a volte allinea righe vuote o parentesi graffe di chiusura non correlate, producendo diff che “si leggono strani”. Patience (Bram Cohen, 2005) si ancora a righe che compaiono esattamente una volta in ciascun input e ricorre fra gli ancoraggi, così i confini fra funzioni restano intatti. Usa git diff --patience (o --histogram per risultati simili, leggermente più veloce) quando fai review di refactor.
Il testo che incollo viene inviato a un server?
No. Ogni confronto in Text Diff gira localmente in JavaScript dentro il tuo browser. Il tuo testo non viene mai caricato, loggato, salvato su disco né inviato a terze parti. Solo le tue preferenze UI (modalità di vista e toggle delle opzioni di ignore) vengono salvate in localStorage così la pagina le ricorda alla visita successiva; mai il testo. Verifica con DevTools → Network: zero richieste partono quando clicchi Diff.
Quanto possono essere grandi i due input?
Il limite pratico è circa 5.000 righe o 1 MB per lato. Il live diff si disattiva oltre 200 KB combinati e passa a un pulsante Diff manuale. Oltre 5.000 righe l’input viene troncato con un avviso. Per file da molti megabyte, passa a diff -u a.txt b.txt, git diff --no-index a.txt b.txt o delta: gestiscono in streaming e arrivano ai gigabyte.