Cos'è una patch nel controllo versione git?


137

Sono nuovo sia per il controllo git che per il controllo delle versioni, quindi sto cercando di capire cos'è una patch e in che cosa differisce dalle altre attività che faccio in git?

Quando applico una patch? Succede ogni volta che commetto?

Risposte:


116

In questo post di blog puoi vedere come creare una patch (raccolta di modifiche che desideri comunicare e applicare a un altro repository)

patch git
(immagine tratta dal post del blog " Bioruby with git: come funzionerebbe? ", pubblicato da Jan AERTS nel 2008 )

Vedi anche Contribuire a Rails con Git come un altro esempio concreto.

Al giorno d'oggi, la richiesta pull di GitHub rende davvero semplice l' applicazione di patch sui repository GitHub, utile quando non si è un contributore diretto (ovvero non si ha il diritto di inviare direttamente a un repository).
In realtà, abbastanza recentemente GitHub ha introdotto " Better Pull Request Email " per migliorare la notifica di nuove patch.


4
Una buona risposta e una che mi dice che una 'patch' GIT non è ciò che sto cercando.
RonLugge,

91

Patch è un programma Unix che aggiorna i file di testo secondo le istruzioni contenute in un file separato, chiamato file patch.

Quindi, in altre parole, può significare il file con istruzioni o un programma che elabora quel file e lo applica a qualcosa.

Ora, cos'è un file patch? Supponiamo che tu abbia un file di testo con 2 righe:

This is line A.
This is line B, or otherwise #2.

Quindi cambi la prima riga e ora il tuo file è simile al seguente:

This is SPARTA.
This is line B, or otherwise #2.

Come descriveresti la modifica al contenuto del file? Puoi dire che la prima riga "Questa è la riga A." è stato sostituito con "This is SPARTA." o anche l'ultima parola "A" della prima riga sostituita con un'altra parola "SPARTA". E questo è esattamente ciò che ci dice diff . Diciamo che ho due versioni di questo file, una chiamata file1.txt e un'altra file2.txt, quindi eseguo diff e ottengo questo:

$ diff -u file1.txt file2.txt 
--- file1.txt   2011-11-26 11:07:03.131010360 -0500
+++ file2.txt   2011-11-26 11:07:13.171010362 -0500
@@ -1,2 +1,2 @@
-This is line A.
+This is SPARTA.
 This is line B, or otherwise #2.

Avendo una descrizione delle modifiche, è possibile applicarlo a un contenuto iniziale e ottenere un contenuto modificato. E quei cambiamenti, messi in un formato unificato che i programmi simili a "patch" possono capire, sono chiamati file patch. È come invece di prendere un pesce da qualcuno che ti insegnano a pescare, in modo che tu possa scavare quel pesce dalle acque da solo. Ora, applichiamo la nostra patch a file1.txt per farla apparire esattamente come file2.txt:

$ cat file1.txt 
This is line A.
This is line B, or otherwise #2.
$ cat file2.txt 
This is SPARTA.
This is line B, or otherwise #2.
$ diff -u file1.txt file2.txt > changes.patch
$ cat changes.patch 
--- file1.txt   2011-11-26 11:09:38.651010370 -0500
+++ file2.txt   2011-11-26 11:07:13.171010362 -0500
@@ -1,2 +1,2 @@
-This is line A.
+This is SPARTA.
 This is line B, or otherwise #2.
$ patch < changes.patch 
patching file file1.txt
$ cat file1.txt 
This is SPARTA.
This is line B, or otherwise #2.
$ 

Potresti pensare che sia più semplice avere solo due versioni di questo file. Bene, in questo semplice caso è vero. Ma quando hai molti file e quei file sono molto grandi, è molto più efficiente avere alcune linee di modifiche piuttosto che due copie dell'intero.

Quando parliamo di git, il file patch significa sempre la stessa cosa, ma usare diff + patch da soli sarebbe un incubo. Ad esempio, dovrai sempre avere due versioni del file (o anche l'intero repository) estratto per poterle confrontare. Non suona così bene, vero? Quindi git si occupa di tutto il duro lavoro per te: confronta il tuo file locale con quello che c'è nel repository con cui stai lavorando e può mostrartelo come "diff" o applicare quel "diff" come patch aka commette le tue modifiche o ti consente persino di applicare alcuni file patch che hai già. Senza approfondire i dettagli, in questo senso git è assolutamente lo stesso di altri sistemi di controllo di versione come SVN, o anche CVS o perforce.

Spero che sia d'aiuto!


Mai saputo che git usa il patchprogramma integrato . Pensavo che Git avesse una sua implementazione.
Radiantshaw,

43

Una patch è un piccolo file che indica le modifiche apportate in un repository. Viene generalmente utilizzato quando qualcuno esterno al tuo team ha accesso in sola lettura ma disponeva di una buona modifica del codice. Quindi crea una patch e te la invia. Lo si applica e lo si spinge nel repository git. Tutti quindi beneficiano della versione aggiornata e l'autore della patch non ha avuto bisogno dell'accesso in lettura / scrittura.

È davvero principalmente una questione di sicurezza (almeno, questo è ciò per cui le persone lo usano).


1
Informazioni aggiuntive: Sebbene git non utilizzi le patch internamente, un obiettivo di progettazione per git è semplificare lo scambio di patch (poiché molti progetti funzionano in questo modo, ad esempio Linux e git stesso). Quindi git ha comandi speciali per gestire le patch ( git diffmostra le modifiche come patch di default, git applyconsente di applicare una patch, ecc.).
sleske,

Congratullations! L'hai davvero risolto per quanto riguarda le patch utilizzate, ovvero un mezzo per inviare le modifiche ai repository per cui l'autore delle modifiche non ha accesso in scrittura. Pertanto, il modello di richiesta fork e pull di GitHub è un sostituto del modello patch di distribuzione del cambiamento. Quindi credo che le patch siano utili solo al di fuori del contesto di strumenti come GitHub.
mljrg,

8

Un file patch rappresenta un singolo set di modifiche che possono essere applicate a qualsiasi ramo, in qualsiasi ordine. Usando la patch, otterrai differenze tra uno o più file. E in seguito, puoi applicare le differenze (patch) per ottenere le modifiche su nuovi file. Ci sono molti usi per una patch in Git. Se sono presenti modifiche senza commit nella directory di lavoro e è necessario che tali modifiche vengano applicate da qualche altra parte, è sufficiente creare una patch e applicare la patch.

git diff > mypatch.patch

Se nel repository sono presenti nuovi file (non tracciati), è necessario posizionare il file prima di creare una patch (non eseguire il commit) e utilizzare il comando seguente

git diff --cached > mypatch.patch 

È possibile applicare successivamente la patch:

git apply mypatch.patch

Se si desidera apportare alcune modifiche a un repository git, che non si dispone di un'autorizzazione di scrittura, è sufficiente apportare le modifiche e creare una patch tra entrambi e inviare la patch a qualcuno che ha l'autorizzazione per applicare la patch, da questo le tue modifiche dovrebbero essere aggiunte a quel repository git.


Demo migliori: robots.thoughtbot.com/… . Il mio esempio di riepilogo di base: git format-patch <base_commit_or_branch_name>= riassumi tutti i commit da ora di nuovo a <base_commit_or_branch_name> in file belli e ordinati contenenti i messaggi diff e commit, per un facile invio (es: via e-mail) a qualcun altro che vuole patch la loro base di codice. Quindi il destinatario corregge il proprio sistema con il tuo file:cat *.patch | git am
Gabriel Staples,

7

Una patch è un insieme di differenze tra uno o più file, per mostrare ciò che è diverso tra loro. Generalmente genereresti solo una patch per mostrare a qualcuno cosa hai cambiato. Un esempio di quando potresti farlo è quando trovi e correggi un bug in un'applicazione open source e poi pubblichi la correzione sul loro bug tracker.

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.