toooly-box

Confronto testi

Incolla due versioni e vedi esattamente che cosa è cambiato, riga per riga.

elaborazione locale
Confronto testi
Originale
Modificato
Differenze3 aggiunte · 2 rimosse · 3 invariate
11 nome: checkout
2−repliche: 2
3−immagine: shop/checkout:1.4.0
2+repliche: 4
3+immagine: shop/checkout:1.5.2
44 timeout: 30s
5+tentativi: 3
56 regione: eu-west-1

Che cosa vuol dire confrontare due testi?

Confrontare due testi vuol dire allinearli e segnare che cosa è stato aggiunto, che cosa tolto e che cosa è rimasto uguale, di solito riga per riga. Il risultato si chiama diff. È la stessa operazione che fa un sistema di controllo versione quando ti mostra che cosa è cambiato in un file.

Come funziona

I due testi vengono divisi in righe e accoppiati con la più lunga sottosequenza comune: la sequenza più lunga di righe, non necessariamente contigue, che compare in entrambi nello stesso ordine. Quelle sono le righe rimaste uguali, e tutto ciò che sta in mezzo è un’aggiunta o una rimozione.

È questo accoppiamento a rendere leggibile un confronto. Paragonare la riga 1 con la riga 1 e la 2 con la 2 segnerebbe come cambiata ogni riga dopo un inserimento; l’accoppiamento per sottosequenza riconosce che una riga è stata inserita e che le altre sono semplicemente scese.

I fine riga vengono normalizzati prima del confronto, così lo stesso file salvato su Windows e su Linux risulta identico invece che cambiato in ogni riga.

Che cos'è un confronto tra due testi

Un confronto tra testi, o diff, è una comparazione riga per riga di due versioni dello stesso testo, che mostra quali righe sono state aggiunte, quali tolte e quali sono rimaste uguali. È lo strumento su cui è costruito ogni sistema di controllo di versione: «git diff» e la vista affiancata di una pull request sono questo confronto con un'interfaccia intorno.

Quello che confronta sono righe, non significati. Due testi che dicono la stessa cosa con parole diverse sono completamente diversi per un diff, e una riga spostata dall'inizio alla fine del file risulta come una rimozione più un'aggiunta invece che come uno spostamento. È un limite che vale la pena conoscere prima di concludere che un documento è cambiato più di quanto sia cambiato davvero.

Leggere il risultato

Ogni riga porta il suo numero su entrambi i lati. Una riga presente in tutti e due i testi ha un numero a sinistra e uno a destra; una riga rimossa ha solo quello di sinistra, una aggiunta solo quello di destra. È così che si vede lo scorrimento: quando la riga 40 a sinistra è la riga 46 a destra, sopra sono state inserite sei righe.

Una riga modificata compare come una rimozione seguita da un’aggiunta, e il riepilogo la conta una volta per parte. È il comportamento di ogni confronto per righe, git compreso: una riga o è uguale o non lo è, e una modifica è una riga che se ne va e una che arriva.

  • Rimossa presente nell’originale, assente nella versione modificata. Segnata con un meno.
  • Aggiunta presente nella versione modificata, assente nell’originale. Segnata con un più.
  • Invariata presente in entrambi, nello stesso ordine relativo. Sono gli ancoraggi su cui si regge il confronto.

Quando ignorare maiuscole e spazi

Due opzioni cambiano che cosa conta come «stessa riga», e esistono perché quasi tutti i confronti veri sono rumorosi.

«Ignora spazi» elimina spazi iniziali e finali di ogni riga e comprime le sequenze di spazi e tabulazioni al suo interno: sparisce così il diff che compare quando un file viene reindentato, quando un formattatore passa dalle tabulazioni agli spazi, o quando l’editor toglie gli spazi finali al salvataggio. Usala quando vuoi sapere se è cambiata la logica, e disattivala dove gli spazi contano: Python, YAML, Makefile, blocchi di codice in Markdown.

«Ignora maiuscole» serve per confrontare dati più che codice: due export della stessa lista in cui un sistema ha reso maiuscole le chiavi, una colonna di indirizzi email, un insieme di tag. Lasciala disattivata per il codice sorgente, dove Valore e valore sono due identificatori diversi.

A cosa serve davvero

  • Due file di configurazione staging contro produzione, o prima contro dopo un deploy. È il confronto che trova l’unica variabile d’ambiente che nessuno voleva cambiare.
  • Due risposte API passale prima in un formattatore JSON con le chiavi ordinate, poi confrontale. Senza ordinamento, una risposta con le chiavi in ordine diverso produce un diff pieno di righe che in realtà non sono cambiate.
  • Due versioni di un documento un contratto, una policy, un testo che qualcuno ha rimandato indietro «con due piccole modifiche». Il confronto serve a scoprire quanto piccole.
  • Due elenchi export, inventari, liste di iscritti. Ordinali entrambi e il diff diventa esattamente le voci aggiunte e quelle tolte.
  • Una patch per un ticket il risultato si scarica come diff unificato, il formato ---/+++ usato da git e da patch: si allega, si incolla in una review, si applica.

Dove un confronto per righe è lo strumento sbagliato

Un diff per righe confronta righe: un solo carattere cambiato dentro un paragrafo lungo viene segnalato come l’intero paragrafo sostituito. Per la prosa scritta con un paragrafo per riga è tecnicamente corretto e praticamente inutile; lì serve un confronto per parole. Il rimedio abituale è riformattare entrambi i testi con una frase per riga prima di confrontarli.

È anche lo strumento sbagliato per dati strutturati in cui l’ordine non conta. Due oggetti JSON con gli stessi campi in ordine diverso sono lo stesso oggetto e due testi completamente diversi: ecco perché ordinare prima le chiavi non è un vezzo, è ciò che dà un senso al confronto. Lo stesso vale per le righe di un CSV e per qualsiasi export il cui ordinamento sia casuale.

E non può dirti che un blocco si è spostato. Una funzione passata dall’inizio alla fine del file appare come una grande cancellazione e un grande inserimento, perché secondo le regole dell’algoritmo è esattamente quello.

Confrontare cose che non dovresti caricare

Entrambi i testi restano nella pagina. Il confronto avviene nel browser, non viene inviato nulla a un server e lo strumento funziona anche offline: è l’unico motivo per cui ha senso incollare due versioni di un contratto, un file di configurazione con dentro una stringa di connessione, o un export con i dati dei clienti.

Quasi tutti i diff online inviano entrambi i testi a un backend per calcolare il confronto. Quella è una copia di entrambi i documenti sulla macchina di qualcun altro, e per qualsiasi cosa coperta da un accordo di riservatezza o dal GDPR è una copia che probabilmente non eri autorizzato a fare.

Domande frequenti

I miei testi vengono caricati?

No. Il confronto avviene nel browser e non viene inviato nulla, quindi puoi confrontare in sicurezza due versioni di un documento riservato. Lo strumento funziona anche offline.

Perché un carattere cambiato diventa un’intera riga cambiata?

Perché è un confronto per righe: una riga o è identica o non lo è. Per la prosa, riformatta entrambi i testi con una frase per riga prima di confrontarli, oppure usa un confronto per parole.

Perché il diff del mio JSON mostra righe che non sono cambiate?

Quasi sempre perché l’ordine delle chiavi è diverso tra le due risposte. Formattale entrambe con le chiavi ordinate e il confronto si riduce ai campi davvero cambiati.

Gestisce i fine riga di Windows e di Unix?

Sì. CRLF e LF vengono normalizzati prima del confronto, quindi lo stesso file salvato su due sistemi risulta identico invece che cambiato in ogni riga.

Posso ottenere una patch?

Sì. Il download produce un diff unificato, il formato ---/+++ usato da git e da patch: lo puoi allegare a un ticket o incollare in una review.