Annullamento di modifiche e commit
In questa sezione parleremo delle strategie e dei comandi di annullamento disponibili in Git. È innanzitutto importante osservare che Git non dispone di un sistema di "annullamento" tradizionale come quelli delle applicazioni di elaborazione di testi. È meglio dunque evitare di collegare le operazioni Git ai modelli mentali di "annullamento" tradizionali. Inoltre, Git ha una propria nomenclatura per le operazioni di "annullamento" che è preferibile utilizzare in questo contesto. Questa nomenclatura include termini come, tra gli altri, reimpostazione, ripristino, estrazione e pulizia.
Una metafora divertente è pensare a Git come a un'utilità per la gestione della timeline. I commit sono snapshot di un momento o di punti di interesse specifici nella timeline della cronologia di un progetto. Inoltre, è possibile gestire più timeline tramite i branch. Quando si effettua un "annullamento" in Git, di solito si torna indietro nel tempo o si passa a un'altra timeline in cui non si sono verificati errori.
Questo tutorial fornisce tutte le competenze necessarie per lavorare con le revisioni precedenti di un progetto software. Innanzitutto, viene mostrato come esplorare i vecchi commit, poi viene illustrata la differenza tra il ripristino dei commit pubblici nella cronologia del progetto e la reimpostazione delle modifiche non pubblicate sul computer locale.
Trovare ciò che è andato perso: revisione dei vecchi commit
L'idea alla base di qualsiasi sistema di controllo delle versioni è quella di archiviare copie "sicure" di un progetto in modo che non ci si debba mai preoccupare di danneggiare irreparabilmente la base di codice. Una volta creata la cronologia dei commit del progetto, puoi rivedere e riesaminare qualsiasi commit al suo interno. Una delle utilità migliori per rivedere la cronologia di un repository Git è il comando git log
. Nell'esempio seguente, utilizziamo git log per ottenere una lista degli ultimi commit eseguiti in una popolare libreria grafica open source.
git log --oneline
e2f9a78fe Replaced FlyControls with OrbitControls
d35ce0178 Editor: Shortcuts panel Safari support.
9dbe8d0cf Editor: Sidebar.Controls to Sidebar.Settings.Shortcuts. Clean up.
05c5288fc Merge pull request #12612 from TyLindberg/editor-controls-panel
0d8b6e74b Merge pull request #12805 from harto/patch-1
23b20c22e Merge pull request #12801 from gam0022/improve-raymarching-example-v2
fe78029f1 Fix typo in documentation
7ce43c448 Merge pull request #12794 from WestLangley/dev-x
17452bb93 Merge pull request #12778 from OndrejSpanel/unitTestFixes
b5c1b5c70 Merge pull request #12799 from dhritzkiv/patch-21
1b48ff4d2 Updated builds.
88adbcdf6 WebVRManager: Clean up.
2720fbb08 Merge pull request #12803 from dmarcos/parentPoseObject
9ed629301 Check parent of poseObject instead of camera
219f3eb13 Update GLTFLoader.js
15f13bb3c Update GLTFLoader.js
6d9c22a3b Update uniforms only when onWindowResize
881b25b58 Update ProjectionMatrix on change aspect
materiale correlato
Scheda di riferimento rapido di Git
Scopri la soluzione
Impara a utilizzare Git con Bitbucket Cloud
Ogni commit dispone di un hash identificativo SHA-1 univoco. Questi ID vengono utilizzati per esaminare la timeline sottoposta a commit e rivedere i commit. Per impostazione predefinita, git log
mostrerà soltanto i commit relativi al branch attualmente selezionato. È del tutto possibile che il commit che stai cercando si trovi su un altro branch. Puoi visualizzare tutti i commit su tutti i branch eseguendo git log --branches=*
. Il comando git branch viene utilizzato per visualizzare ed esaminare altri branch. Richiamando il comando, git branch -a
restituirà una lista di tutti i nomi dei branch conosciuti. Uno di questi nomi di branch può quindi essere registrato utilizzando git log
.
Una volta trovato un riferimento di commit al punto della cronologia che desideri esaminare, puoi utilizzare il comando git checkout
per rivedere quel commit. Il comando git checkout
è un modo semplice per "caricare" una qualsiasi di queste snapshot salvate sul computer di sviluppo. Durante il normale processo di sviluppo, l'HEAD
di solito punta al branch main
o a un altro branch locale, ma quando estrai un commit precedente, l'HEAD
non punta più a un branch, ma direttamente a un commit. Ciò è definito stato "HEAD
scollegato" e può essere visualizzato come segue:
L'estrazione di un file meno recente non fa spostare il puntatore HEAD
, che rimane nello stesso branch e nello stesso commit, evitando di entrare nello stato "HEAD scollegato". Puoi quindi eseguire il commit della versione precedente del file in una nuova snapshot come faresti con qualsiasi altra modifica. Quindi, in effetti, questo utilizzo di git checkout
su un file serve come un modo per ripristinare una versione precedente di un singolo file. Per ulteriori informazioni su queste due modalità, visita la pagina relativa a git checkout
Visualizzazione di una revisione precedente
In questo esempio si presuppone che tu abbia iniziato a sviluppare un esperimento un po' folle (crazy), ma non sei sicuro di volerlo mantenere o meno. Per decidere, vuoi dare un'occhiata a qual era lo stato del progetto prima che dessi il via all'esperimento. Per prima cosa, devi trovare l'ID della revisione che desideri esaminare.
git log --oneline
Supponiamo che la cronologia del progetto sia simile alla seguente:
b7119f2 Continue doing crazy things
872fa7e Try something crazy
a1e8fb5 Make some important changes to hello.txt
435b61d Create hello.txt
9773e52 Initial import
Puoi usare git checkout
per visualizzare il commit "Make some import changes to hello.txt" come segue:
git checkout a1e8fb5
In questo modo, la directory di lavoro corrisponde allo stato esatto del commit a1e8fb5
. Puoi esaminare i file, compilare il progetto, eseguire test e persino modificare i file senza preoccuparti di perdere lo stato attuale del progetto. Niente di ciò che fai qui verrà salvato nel repository. Per continuare con lo sviluppo, devi tornare allo stato "attuale" del progetto:
git checkout main
In questo esempio si presuppone che le tue operazioni di sviluppo avvengano nel branch main
predefinito. Una volta tornato nel branch main
, puoi usare git revert o git reset per annullare eventuali modifiche indesiderate.
Annullare una snapshot sottoposta a commit
Tecnicamente, esistono diverse strategie per "annullare" un commit. Negli esempi seguenti si presuppone di avere una cronologia dei commit simile alla seguente:
git log --oneline
872fa7e Try something crazy
a1e8fb5 Make some important changes to hello.txt
435b61d Create hello.txt
9773e52 Initial import
Ci concentreremo sull'annullamento del commit 872fa7e Try something crazy
. Forse le cose ci sono un po' sfuggite di mano.
Come annullare un commit con git checkout
Tramite il comando git checkout
, possiamo estrarre il commit precedente (a1e8fb5
) impostando il repository su uno stato precedente al commit in questione. L'estrazione di un commit specifico comporterà l'impostazione del repository sullo stato "HEAD scollegato". Ciò significa che non stai più lavorando su nessun branch. In questo stato, qualsiasi nuovo commit eseguito rimarrà orfano quando si ritorna a un branch consolidato. I commit orfani possono essere eliminati definitivamente dal Garbage Collector di Git, che viene eseguito a intervalli configurati. Per evitare che i commit orfani vengano eliminati dalla garbage collection, dobbiamo assicurarci di trovarci in un branch.
Dallo stato HEAD scollegato, possiamo eseguire git checkout -b new_branch_without_crazy_commit
. Verrà così creato un nuovo branch chiamato new_branch_without_crazy_commit
che verrà impostato su quello stato. Il repository si trova ora in una nuova timeline della cronologia in cui il commit 872fa7e
non esiste più. A questo punto, possiamo continuare a lavorare su questo nuovo branch in cui il commit 872fa7e
non esiste più e possiamo considerarlo "annullato". Purtroppo, se invece il branch precedente ti serve (magari era il branch main
), questa strategia di annullamento non è appropriata. Diamo un'occhiata ad alcune altre strategie di "annullamento". Per ulteriori informazioni ed esempi, consulta la nostra analisi approfondita su git checkout.
Come annullare un commit pubblico con git revert
Supponiamo di tornare al primo esempio sulla cronologia dei commit. La cronologia che include il commit 872fa7e
. Questa volta proviamo con il ripristino dell'"annullamento". Se eseguiamo git revert HEAD
, Git creerà un nuovo commit con l'inverso dell'ultimo commit. In questo modo, viene aggiunto un nuovo commit alla cronologia del branch attuale che ora appare come:
git log --oneline
e2f9a78 Revert "Try something crazy"
872fa7e Try something crazy
a1e8fb5 Make some important changes to hello.txt
435b61d Create hello.txt
9773e52 Initial import
A questo punto, abbiamo tecnicamente "annullato" di nuovo il commit 872fa7e
. Sebbene 872fa7e
sia ancora presente nella cronologia, il nuovo commit e2f9a78
è l'inverso delle modifiche apportate in 872fa7e
. A differenza della precedente strategia di estrazione, possiamo continuare a utilizzare lo stesso branch. Questa è una soluzione di annullamento soddisfacente. Si tratta del metodo di "annullamento" ideale se si utilizzano repository pubblici condivisi. Se devi rispettare dei requisiti che richiedono di mantenere una cronologia Git curata e minima, questa strategia potrebbe non essere la più adatta.
Come annullare un commit con git reset
Per questa strategia di annullamento continueremo con lo stesso esempio. git reset è un comando completo con molteplici usi e funzioni. Se richiamiamo git reset --hard a1e8fb5
, la cronologia dei commit viene reimpostata su quel commit specificato. L'analisi della cronologia dei commit con git log
adesso sarà:
git log --oneline
a1e8fb5 Make some important changes to hello.txt
435b61d Create hello.txt
9773e52 Initial import
L'output del log mostra che i commit e2f9a78
e 872fa7e
non esistono più nella cronologia dei commit. A questo punto, possiamo continuare a lavorare e creare nuovi commit come se i commit dell'esperimento ("crazy") non fossero mai esistiti. Questo metodo di annullamento delle modifiche è quello che ha il minore impatto sulla cronologia. La reimpostazione è un'ottima soluzione per le modifiche locali, anche se implica delle complicazioni quando si lavora con un repository remoto condiviso. Se abbiamo un repository remoto condiviso su cui è stato inviato il commit 872fa7e
e proviamo a utilizzare il comando git push
su un branch in cui abbiamo reimpostato la cronologia, Git lo rileverà e genererà un errore. Git supporrà che il branch oggetto dell'invio non sia aggiornato a causa della mancanza di commit. In questi scenari, è meglio usare git revert
come metodo di annullamento preferito.
Annullamento dell'ultimo commit
Nella sezione precedente abbiamo descritto diverse strategie di annullamento dei commit. Queste strategie sono tutte applicabili anche al commit più recente. In alcuni casi, tuttavia, potrebbe non essere necessario rimuovere o reimpostare l'ultimo commit, che magari è stato creato prima del tempo. In questo caso è possibile modificare il commit più recente. Dopo aver apportato altre modifiche alla directory di lavoro e averle preparate per il commit usando git add, puoi eseguire git commit --amend
. Git aprirà l'editor di sistema configurato consentendoti di modificare l'ultimo messaggio di commit. Le nuove modifiche verranno aggiunte al commit modificato.
Annullamento delle modifiche non sottoposte a commit
Prima di venire sottoposte a commit nella cronologia del repository, le modifiche risiedono nell'indice di staging e nella directory di lavoro. Potrebbe essere necessario annullare le modifiche in queste due aree. L'indice di staging e la directory di lavoro sono meccanismi interni di gestione dello stato di Git. Per informazioni più dettagliate e un'analisi più approfondita sul funzionamento di questi due meccanismi, visita la pagina relativa a git reset.
La directory di lavoro
La directory di lavoro è in genere sincronizzata con il file system locale. Per annullare le modifiche nella directory di lavoro puoi modificare i file come faresti normalmente usando il tuo editor preferito. In Git sono incluse alcune utilità per semplificare la gestione della directory di lavoro. Il comando git clean, ad esempio, è utile per annullare le modifiche alla directory di lavoro. Inoltre, puoi richiamare git reset
con le opzioni --mixed
o --hard
per reimpostare la directory di lavoro.
L'indice di staging
Il comando git add viene utilizzato per aggiungere le modifiche all'indice di staging. git reset
viene utilizzato principalmente per annullare le modifiche all'indice di staging. Un ripristino --mixed
sposta tutte le modifiche in sospeso dall'indice di staging alla directory di lavoro.
Annullamento delle modifiche pubbliche
Quando si lavora in un team con repository remoti, è necessario prestare particolare attenzione all'annullamento delle modifiche. Il comando git reset
deve essere generalmente considerato come un metodo di annullamento "in locale". Quando si annullano le modifiche a un branch privato, è necessario eseguire un ripristino per isolare in modo sicuro la rimozione dei commit da altri branch che potrebbero essere in uso da parte di altri sviluppatori. I problemi sorgono quando viene eseguito un ripristino su un branch condiviso che viene poi inviato in remoto con il comando git push
. In questo caso, Git bloccherà l'invio segnalando che il branch oggetto dell'invio non è aggiornato rispetto al branch remoto, poiché non dispone di commit.
Il metodo preferito per annullare la cronologia condivisa è git revert
. Il ripristino è più sicuro della reimpostazione perché non rimuove alcun commit dalla cronologia condivisa. Il ripristino manterrà i commit che desideri annullare e creerà un nuovo commit che inverte quello indesiderato. Questo metodo è più sicuro per la collaborazione remota condivisa perché uno sviluppatore remoto può eseguire un pull del branch e ricevere il nuovo commit ripristinato che annulla quello indesiderato.
Riepilogo
Abbiamo esaminato molte strategie generali di annullamento disponibili in Git. È importante ricordare che esiste più di un modo per "annullare" gli elementi nei progetti Git. In questa pagina abbiamo parlato in generale di argomenti che sono approfonditi più nei dettagli nelle pagine specifiche dedicate ai comandi Git pertinenti. Gli strumenti di "annullamento" più comunemente usati sono git checkout, git revert e git reset. Ecco alcuni punti chiave da ricordare:
- In genere, una volta che vengono sottoposte a commit, le modifiche diventano permanenti
- Usa
git checkout
per spostarti e rivedere la cronologia dei commit git revert
è lo strumento migliore per annullare le modifiche pubbliche condivisegit reset
è il metodo migliore per annullare le modifiche private locali
Oltre ai comandi di annullamento principali, abbiamo dato un'occhiata ad altre utilità di Git: git log per trovare i commit persi, git clean per annullare le modifiche non sottoposte a commit e git add per modificare l'indice di staging.
Per ognuno di questi comandi è disponibile una documentazione approfondita. Per saperne di più su un comando specifico menzionato qui, visita i link corrispondenti.
Condividi l'articolo
Argomento successivo
Letture consigliate
Aggiungi ai preferiti queste risorse per ricevere informazioni sui tipi di team DevOps e aggiornamenti continui su DevOps in Atlassian.