Perché usare diff / patch quando è più semplice usare solo cp


19
diff -u file1.txt file2.txt > patchfile

crea un file patch che consiste in istruzioni per patchconvertire file1.txt in modo che sia esattamente come file2.txt

Non è possibile farlo utilizzando cpinvece il comando? Posso immaginare che ciò sia utile quando il file è troppo grande e deve essere trasferito su una rete in cui questo approccio potrebbe risparmiare larghezza di banda. Esiste un altro modo per utilizzare diff / patch che sarebbe vantaggioso in altri scenari?

Risposte:


31

I diff possono essere più complicati del semplice confronto tra un file e un altro. È possibile confrontare intere gerarchie di directory. Considera l'esempio che desidero correggere un bug in GCC. La mia modifica aggiunge una o due righe in 4 o 5 file ed elimina una manciata di righe in questi e altri file. Se voglio comunicare queste modifiche a qualcuno, potenzialmente per l'inclusione in GCC le mie opzioni sono

  • Copia l'intero albero dei sorgenti
  • Copia solo i file che sono stati modificati
  • Fornisci solo le modifiche che ho apportato

Copiare l'intero albero dei sorgenti non ha senso, ma per quanto riguarda le altre due opzioni, che sono al centro della tua domanda. Ora considera che anche qualcun altro ha lavorato sullo stesso file come me e che entrambi diamo le nostre modifiche a qualcuno. Come farà questa persona a sapere cosa abbiamo fatto e se le modifiche sono compatibili (parti diverse del file) o sono in conflitto (stesse righe del file)? Li diffonderà! Il diff può dirgli in che modo i file differiscono l'uno dall'altro e dal file sorgente non modificato. Se il diff è ciò che è necessario, ha semplicemente più senso inviare il diff in primo luogo. Un diff può contenere anche modifiche da più di un file, quindi mentre ho modificato 9 file in totale, posso fornire un singolo file diff per descrivere tali cambiamenti.

I diff possono anche essere usati per fornire la cronologia. E se un cambiamento tre mesi fa causasse un bug che ho scoperto solo oggi. Se riesco a restringere il campo quando è stato introdotto il bug e posso isolarlo in una specifica modifica, posso usare il diff per "annullare" o ripristinare la modifica. Questo non è qualcosa che potrei fare facilmente se solo copiassi dei file.

Tutto ciò si lega al controllo della versione di origine in cui i programmi possono registrare la cronologia dei file come una serie di differenze dal momento in cui è stata creata fino ad oggi. I diff forniscono la cronologia (posso ricreare il file com'era in un determinato giorno), posso vedere a chi dare la colpa per aver infranto qualcosa (il diff ha un proprietario) e posso facilmente inviare modifiche ai progetti a monte dando loro differenze specifiche ( forse sono interessati a un solo cambiamento quando ne ho fatti molti).

In sintesi, sì, cpè più facile di diffe patch, ma l'utilità di diffe patchè maggiore di cpper le situazioni in cui il cambiamento dei file è importante da tracciare.


In effetti, git non memorizza realmente la cronologia dei file come diff dei commit successivi. Per ogni commit sono store, il contenuto di ogni file (vedi "git show -s --pretty = raw" e "git ls-tree HEAD"). Quindi, oltre a questo livello poiché molti file saranno simili in diversi commit, utilizza la compressione delta per condividere i dati tra i file (ma questo non è legato alla cronologia).
ysdx,

Le differenze sono comunque un comodo strumento di visualizzazione per questa storia.
ysdx,

20

Quando ottieni una patch, spesso (a meno che tu non abbia apportato modifiche alle stesse identiche righe), puoi applicare la patch a un set di file che hai modificato anche tu.

La patch contiene informazioni sul vecchio e sul nuovo stato dei file. Se ottieni un file copiato non sai quale fosse l'originale (il vecchio stato) e non puoi applicare le differenze a un file (o set di file) che hai modificato anche senza grandi difficoltà. Quindi per i set di file sorgente non è la conservazione dello spazio a destare maggiore preoccupazione, sono le informazioni prima e dopo.

Prima delle differenze (contestuali / unificate) ciò veniva spesso fatto con le istruzioni per gli editor (inserire una riga dopo X, eliminare la riga Y), ma avrebbe funzionato solo se si fosse a conoscenza dello stato da cui sono iniziate queste istruzioni. Avendo quindi lo stesso problema della tua "soluzione" con la sola copia.


2
un file patch consente anche di annullarlo e applicarlo a più file contemporaneamente
Gilsham,

In realtà, i diff unificati ( diff -u) sono un miglioramento progettato per gli umani, non aiutano la solidità contro i conflitti rispetto al diff diffuso del contesto ( diff -c), credo. Perfino diffs ( diff) spesso funziona ancora senza conoscere esattamente lo "stato da cui sono iniziate queste istruzioni". Tuttavia, questo è meglio della risposta accettata perché parlare di come i file patch possono patchare più file sorgente allo stesso tempo è davvero un'aringa rossa.
Celada,

@celeda hai ragione riguardo alle differenze di contesto, tra quella e le differenze normali è dove sta la distinzione principale. Senza il contesto le patch sono molto più difficili da applicare al contrario, se non del tutto.
Anthon,

12

Se stai usando diff, puoi vedere cosa è esattamente cambiato, quindi usare diff / patch è un modo per impedire a qualcuno di evitare cambiamenti indesiderati nel file.


11

Le modifiche apportate ai file sono in genere molto più piccole rispetto ai file che vengono modificati.

Ciò significa che la memorizzazione di un diff può farti risparmiare molto spazio. Quando è diffstato creato, lo spazio su disco era costoso.

Ma significa anche che puoi riapplicare un diff a un file anche quando quel file è cambiato in altri modi. L' utility patch lo farà per te e ti dirà quando ci sono problemi.

Questo è in effetti il ​​motivo più importante per lavorare con le differenze nello sviluppo del software. Quando è stata apportata una modifica (di solito in più di un file), può essere salvata come diff: il risultato è chiamato set di modifiche o patch . Se tutto va bene, la patch non è solo un cambiamento arbitrario, ma implementa un qualche tipo di cambiamento funzionale, ad esempio una correzione di bug o una nuova funzionalità.

Nel frattempo, è possibile apportare una modifica diversa, possibilmente da uno sviluppatore diverso, anche in una posizione diversa. Se le modifiche non sono state apportate alle stesse parti degli stessi file, possono essere applicate in modo indipendente. In questo modo gli sviluppatori possono scambiarsi reciprocamente le patch per i test. È possibile creare un intero set di patch che rappresenta possibili cambiamenti; alcuni di questi alla fine potrebbero essere respinti, il resto sarà integrato nel sistema.

Quindi lavorare con diff consente uno sviluppo simultaneo. Non devi più lavorare su una modifica alla volta.

I moderni sistemi di controllo della versione distribuita sono una continuazione di questo modo di lavorare.


1

In breve, può. Se guardi alcuni video di Thinkg Big Larry Wall su YouTube, parla di come sono iniziati diff / patch e quali problemi sono stati risolti, e in sostanza si trattava di ridurre le dimensioni per la comunicazione su Internet mantenendo le patch flessibili e leggibili dall'uomo .

Se sei su un sistema locale e non ti importa di nessuna di queste cose, allora cpo va rsyncbene.


Grazie PSKocik. Potresti per favore condividere il link a quel video?
toddlermenot

Non sono d'accordo con l'ultima affermazione. In questi giorni non si tratta di dimensioni, si tratta di tenere traccia del processo di sviluppo in modo che diventi più facile da gestire.
reinierpost,

@reinierpost usa git per tracciare il mio processo di sviluppo. Non diffondo patch direttamente.
PSkocik,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.