GNU/Linux >> Linux Esercitazione >  >> Linux

Introduzione a differenze e patch

Se hai mai lavorato su una base di codice di grandi dimensioni con un modello di sviluppo distribuito, probabilmente hai sentito persone dire cose come "Sue ha appena inviato una patch" o "Rajiv sta controllando le differenze". Forse quei termini erano nuovi per te e ti sei chiesto cosa significassero. L'open source ha avuto un impatto qui, poiché il modello di sviluppo principale di grandi progetti dal server Web Apache al kernel Linux sono stati progetti di sviluppo "basati su patch" per tutta la loro vita. In effetti, lo sapevi che il nome di Apache ha avuto origine dall'insieme di patch che sono state raccolte e confrontate con il codice sorgente del server HTTPd NCSA originale?

Potresti pensare che questo sia folklore, ma una prima acquisizione del sito Web di Apache afferma che il nome derivava da questa raccolta originale di "patch"; quindi APA tCH y server, che è stato poi semplificato in Apache.

Ma abbastanza curiosità sulla storia. Cosa sono esattamente queste toppe e differenze di cui parlano gli sviluppatori?

Innanzitutto, per il bene di questo articolo, supponiamo che questi due termini facciano riferimento alla stessa cosa. "Diff" è semplicemente l'abbreviazione di "differenza"; un'utilità Unix con lo stesso nome rivela la differenza tra uno o più file. Di seguito esamineremo un esempio di utilità diff.

Una "patch" si riferisce a una raccolta specifica di differenze tra file che possono essere applicate a un albero del codice sorgente utilizzando l'utilità Unix diff. Quindi possiamo creare differenze (o patch) utilizzando lo strumento diff e applicarle a una versione senza patch dello stesso codice sorgente utilizzando lo strumento patch. Per inciso (e infrangendo la mia regola di non più curiosità sulla storia), la parola "patch" deriva dalla copertura fisica dei buchi delle schede perforate per apportare modifiche al software nei primi giorni dell'informatica, quando le schede perforate rappresentavano il programma eseguito dal processore del computer. L'immagine qui sotto, che si trova in questa pagina di Wikipedia che descrive le patch software, mostra questo concetto originale di "patch":

Ora che hai una conoscenza di base di patch e differenze, esploriamo come gli sviluppatori di software utilizzano questi strumenti. Se non hai utilizzato un sistema di controllo del codice sorgente come Git o Subversion, preparerò il terreno per lo sviluppo della maggior parte dei progetti software non banali. Se pensi alla vita di un progetto software come a un insieme di azioni lungo una sequenza temporale, potresti visualizzare modifiche al software, come l'aggiunta di una funzionalità o una funzione a un file di codice sorgente o la correzione di un bug, che appaiono in punti diversi su la timeline, con ogni punto discreto che rappresenta lo stato di tutti i file di codice sorgente in quel momento. Chiameremo questi punti di cambiamento "commit", usando la stessa nomenclatura utilizzata dallo strumento di controllo del codice sorgente più popolare di oggi, Git. Quando vuoi vedere la differenza tra il codice sorgente prima e dopo un determinato commit, o tra molti commit, puoi utilizzare uno strumento per mostrarci le differenze o le differenze.

Se stai sviluppando software utilizzando lo stesso strumento di controllo del codice sorgente, Git, potresti avere modifiche nel tuo sistema locale che desideri fornire ad altri da aggiungere potenzialmente come commit al proprio albero. Un modo per fornire modifiche locali ad altri è creare una differenza delle modifiche del tuo albero locale e inviare questa "patch" ad altri che stanno lavorando sullo stesso codice sorgente. Ciò consente agli altri di applicare patch al proprio albero e di vedere l'albero del codice sorgente con le modifiche applicate.

Linux, Git e GitHub

Questo modello di condivisione dei file di patch è il modo in cui opera la comunità del kernel Linux per quanto riguarda le modifiche proposte oggi. Se guardi gli archivi per una qualsiasi delle popolari mailing list del kernel Linux — LKML è la principale, ma altre includono linux-containers, fs-devel, Netdev, solo per citarne alcuni — troverai molti sviluppatori che pubblicano patch che desidero che altri esaminino, testino e possibilmente portino nell'albero Git del kernel Linux ufficiale ad un certo punto. È al di fuori dello scopo di questo articolo discutere di Git, il sistema di controllo del codice sorgente scritto da Linus Torvalds, in modo più dettagliato, ma vale la pena notare che Git abilita questo modello di sviluppo distribuito, consentendo alle patch di vivere separatamente da un repository principale, spingendo e tirando in alberi diversi e seguendo il loro flusso di sviluppo specifico.

Prima di andare avanti, non possiamo ignorare il servizio più popolare in cui le patch e le differenze sono rilevanti:GitHub. Dato il suo nome, puoi probabilmente indovinare che GitHub è basato su Git, ma offre un flusso di lavoro basato su Web e API attorno allo strumento Git per lo sviluppo di progetti open source distribuito. Uno dei modi principali in cui le patch vengono condivise in GitHub non è tramite e-mail, come il kernel Linux, ma creando una richiesta pull . Quando esegui il commit delle modifiche sulla tua copia di un albero del codice sorgente, puoi condividere tali modifiche creando una richiesta pull su un repository comunemente condiviso per quel progetto software. GitHub è utilizzato oggi da molti progetti open source attivi e popolari, come Kubernetes, Docker, Container Network Interface (CNI), Istio e molti altri. Nel mondo GitHub, gli utenti tendono a utilizzare l'interfaccia basata sul Web per rivedere le differenze o le patch che compongono una richiesta pull, ma puoi comunque accedere ai file di patch non elaborati e usarli dalla riga di comando con l'utilità di patch.

Mettersi al lavoro

Ora che abbiamo trattato patch e differenze e come vengono utilizzate nelle comuni comunità o strumenti open source popolari, diamo un'occhiata ad alcuni esempi.

Il primo esempio include due copie di un albero dei sorgenti e uno ha le modifiche che vogliamo visualizzare usando l'utilità diff. Nei nostri esempi, esamineremo le differenze "unificate" perché questa è la vista prevista per le patch nella maggior parte del moderno mondo di sviluppo software. Controllare la pagina del manuale diff per ulteriori informazioni sulle opzioni e sui modi per produrre differenze. Il codice sorgente originale si trova in source-orig e la nostra seconda base di codice modificata si trova in una directory denominata source-fixed. Per mostrare le differenze in un formato diff unificato nel tuo terminale, usa il seguente comando:

$ diff -Naur sources-orig/ sources-fixed/

...che quindi mostra il seguente output del comando diff:

diff -Naur sources-orig/officespace/interest.go sources-fixed/officespace/interest.go
--- sources-orig/officespace/interest.go        2018-08-10 16:39:11.000000000 -0400
+++ sources-fixed/officespace/interest.go       2018-08-10 16:39:40.000000000 -0400
@@ -11,15 +11,13 @@
   InterestRate float64
 }

+// compute the rounded interest for a transaction
 func computeInterest(acct *Account, t Transaction) float64 {

   interest := t.Amount * t.InterestRate
   roundedInterest := math.Floor(interest*100) / 100.0
   remainingInterest := interest - roundedInterest

-  // a little extra..
-  remainingInterest *= 1000
-
   // Save the remaining interest into an account we control:
   acct.Balance = acct.Balance + remainingInterest

Le prime righe dell'output del comando diff potrebbero usare qualche spiegazione:I tre --- i segni mostrano il nome del file originale; tutte le righe che esistono nel file originale ma non nel nuovo file confrontato saranno precedute da un singolo - da notare che questa riga è stata “sottratta” dalle fonti. Il +++ i segni mostrano il contrario:il nuovo file confrontato e le aggiunte trovate in questo file sono contrassegnati con un singolo + simbolo per mostrare che sono stati aggiunti nella nuova versione del file. Ogni "pezzo" (questo è ciò che le sezioni precedute da @@ sono chiamati) del file di patch della differenza ha numeri di riga contestuali che aiutano lo strumento di patch (o altri processori) a sapere dove applicare questa modifica. Puoi vedere dalla funzione di riferimento del film "Office Space" che abbiamo corretto (rimuovendo tre righe) l'avidità di uno dei nostri sviluppatori di software, che ha aggiunto un po' al calcolo degli interessi arrotondato insieme a un commento alla nostra funzione .

Se vuoi che qualcun altro provi le modifiche da questo albero, puoi salvare questo output da diff in un file di patch:

$ diff -Naur sources-orig/ sources-fixed/ >myfixes.patch

Ora hai un file di patch, myfixes.patch, che può essere condiviso con un altro sviluppatore per applicare e testare questo insieme di modifiche. Un collega sviluppatore può applicare le modifiche utilizzando lo strumento patch, dato che la sua directory di lavoro corrente si trova nella base dell'albero del codice sorgente:

$ patch -p1 < ../myfixes.patch
patching file officespace/interest.go

Ora l'albero dei sorgenti del tuo collega sviluppatore è aggiornato e pronto per creare e testare le modifiche che sono state applicate tramite la patch. E se questo sviluppatore avesse apportato modifiche a interest.go separatamente? Finché le modifiche non sono in conflitto diretto, ad esempio, modificano le stesse esatte linee, lo strumento patch dovrebbe essere in grado di risolvere dove unire le modifiche. Ad esempio, viene utilizzato un file interest.go con diverse altre modifiche in il seguente esempio di esecuzione della patch:

$ patch -p1 < ../myfixes.patch
patching file officespace/interest.go
Hunk #1 succeeded at 26 (offset 15 lines).

In questo caso, patch avverte che le modifiche non sono state applicate nella posizione originale del file, ma sono state sfalsate di 15 righe. Se hai modificato pesantemente i file, la patch potrebbe smettere di cercare di trovare dove si adattano le modifiche, ma fornisce opzioni (con gli avvisi necessari nella documentazione) per aumentare la "sfocatura" corrispondente (che esulano dallo scopo di questo articolo) .

Se stai usando Git e/o GitHub, probabilmente non utilizzerai gli strumenti diff o patch come strumenti standalone. Git offre gran parte di questa funzionalità in modo da poter utilizzare le capacità integrate di lavorare su un albero di origine condiviso con l'unione e il pull di modifiche di altri sviluppatori. Una funzionalità simile consiste nell'usare git diff per fornire l'output diff unificato nell'albero locale o tra due riferimenti qualsiasi (un identificatore di commit, il nome di un tag o di un ramo e così via). Puoi persino creare un file di patch che qualcuno che non utilizza Git potrebbe trovare utile semplicemente collegando l'output di git diff a un file, dato che utilizza il formato esatto del comando diff che la patch può consumare. Naturalmente, GitHub incorpora queste funzionalità in un'interfaccia utente basata sul Web in modo da poter visualizzare le modifiche ai file su una richiesta pull. In questa visualizzazione, noterai che è effettivamente una visualizzazione differenziata unificata nel tuo browser Web e GitHub ti consente di scaricare queste modifiche come file di patch non elaborato.

Riepilogo

Hai imparato cosa sono una differenza e una patch, così come i comuni strumenti da riga di comando Unix/Linux che interagiscono con loro. A meno che tu non sia uno sviluppatore di un progetto che utilizza ancora un metodo di sviluppo basato su file di patch, come il kernel Linux, utilizzerai queste capacità principalmente attraverso un sistema di controllo del codice sorgente come Git. Ma è utile conoscere lo sfondo e le basi delle funzionalità che molti sviluppatori utilizzano quotidianamente attraverso strumenti di livello superiore come GitHub. E chissà, potrebbero tornare utili un giorno quando avrai bisogno di lavorare con le patch da una mailing list nel mondo Linux.


Linux
  1. I 5 migliori repository di codice sorgente

  2. Ottieni il codice sorgente per qualsiasi comando Linux

  3. Come chiamare la funzione C in C++, la funzione C++ in C (mix di C e C++)

  4. Codice per malloc e gratuito

  5. Dov'è il codice di pianificazione di Linux CFS?

Introduzione al sistema di controllo della versione

Un'introduzione alle metriche di Prometheus e al monitoraggio delle prestazioni

Un'introduzione all'hashing e ai checksum in Linux

Un'introduzione alle regole e agli scenari firewalld

Codice VS remoto veloce e sporco facile 100%

Rimuovere il codice sorgente Ppa?