Scopri come annullare le modifiche in Git usando Bitbucket Cloud
Obiettivo
Scopri come annullare le modifiche sul tuo computer locale e su un repository di Bitbucket Cloud mentre collabori con altre persone.
Brief della missione
Comandi trattati in questo tutorial:
- git revert, git reset, git log e git status
Ora
40 minuti
Pubblico
Questo tutorial presuppone la familiarità con i seguenti comandi git: git clone
, git commit
, git pull
e git push
Sbagliare è umano. Non tutti i push sono perfetti, quindi questo tutorial ti spiegherà come usare le funzioni git più comuni per annullare una o più modifiche in modo sicuro.
Questo tutorial presuppone familiarità con i seguenti comandi git:
Se non conosci questi comandi, possiamo aiutarti a Imparare a usare Git con Bitbucket Cloud. Poi torna qui per scoprire come annullare le modifiche. Questi comandi git
possono essere usati negli ambienti Windows o Unix. In questo tutorial saranno utilizzate le utility della riga di comando Unix per spiegare la navigazione dei file di sistema.
Annullamento delle modifiche sul computer locale
Se la modifica che desideri annullare si trova sul tuo sistema locale e non è stato eseguito il push a un repository remoto, esistono due modi principali per annullarla:
Comando | Definizione |
---|---|
| Definizione Un comando "undo", ma non una tradizionale operazione di annullamento. Anziché rimuovere il commit, inverte le modifiche nel commit e aggiunge poi un nuovo commit con il contenuto inverso. In questo modo la cronologia di Git non va perduta, il che è fondamentale per garantire l'integrità della cronologia delle tue revisioni e una collaborazione affidabile. |
| Definizione
Un comando
Per una descrizione dettagliata del funzionamento del comando |
Scopri la soluzione
Tutorial avanzati su Git
materiale correlato
Comandi Git
In questo tutorial, imparerai a usare molti altri comandi git che possono esserti utili per l'annullamento delle modifiche. Iniziamo!
Eseguire un fork di un repository
Creiamo innanzitutto un repository unico con tutti i codici sorgente. In questa fase stiamo eseguendo il "fork del repository": si tratta di una procedura git
estesa che ha luogo quando si ospita un repository condiviso con un servizio di hosting di terzi come Bitbucket.
1. Inserisci o clicca sul seguente URL: https://bitbucket.org/atlassian/tutorial-documentation-tests/commits/all
2. Clicca sul simbolo + sulla barra laterale di sinistra, quindi seleziona Esegui il fork di questo repository, controlla la finestra di dialogo e clicca su Esegui il fork del repository.
3. Verrai indirizzato alla panoramica del nuovo repository.
4. Clicca sul simbolo + e seleziona Clona questo repository.
5. Clona il repository sul tuo computer.
6. Accedi alla Directory contenente il repository clonato.
Ora che hai un repository pieno di codici e una cronologia esistente sul tuo sistema locale, puoi iniziare ad annullare alcune modifiche.
Trovare le modifiche sul sistema locale
Ovviamente devi saper individuare la modifica che desideri annullare. Puoi fare questo sfogliando l'interfaccia utente di commit su Bitbucket e usando alcune utility della riga di comando che possono individuare una modifica specifica.
git status
Ovviamente devi saper individuare la modifica che desideri annullare. Puoi fare questo sfogliando l'interfaccia utente di commit su Bitbucket e usando alcune utility della riga di comando che possono individuare una modifica specifica.
$ git status
On branch main
Your branch is up-to-date with 'origin/main'.
nothing to commit, working tree clean
Qui l'output del comando git status
mostra che è tutto aggiornato con il branch principale remoto e che non sono presenti modifiche in attesa del commit. Nel prossimo esempio apporteremo alcune modifiche al repository e lo esamineremo nello stato con modifiche in sospeso. Ciò significa che nel sistema locale sono presenti modifiche ai file nel repository che non hai preparato (o indicizzato) per l'aggiunta alla cronologia del progetto.
Per illustrare questo esempio, apri innanzitutto il file myquote2.html
. Apporta alcune modifiche ai contenuti di myquote2.html
, salva ed esci dal file. Eseguiamo di nuovo il comando git status
per esaminare il repository in questo stato.
$ git status
On branch main
Your branch is up-to-date with 'origin/main'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
Modified: myquote2.html
no changes added to commit (use "git add" and/or "git commit -a")
--
Qui l'output mostra che il repository contiene modifiche in sospeso in myquote2.html
. Buone notizie! Se la modifica che desideri annullare non è stata ancora aggiunta, come nell'esempio qui sopra, all'area di gestione, puoi modificare il file e procedere. Git inizia a monitorare una modifica solo quando la aggiungi all'area di gestione ed esegui poi il commit nella cronologia del progetto.
Ora "annulliamo" le modifiche che abbiamo apportato a myquote2.html
. Poiché si tratta di un esempio molto semplice con modifiche minime, abbiamo a disposizione due metodi per annullare le modifiche. Se eseguiamo git checkout myquote2.html
, il repository ripristinerà myquote2.html
alla versione del commit precedente. In alternativa, possiamo eseguire il comando git reset --hard
, che riconvertirà l'intero repository all'ultimo commit.
Git log
Il comando git log
ti consente di elencare la cronologia del progetto, filtrarla e cercare modifiche specifiche. Mentre git status
ti consente di esaminare la directory di lavoro e l'area di gestione, git log
mostra solo la cronologia del commit.
Puoi trovare lo stesso log della cronologia del commit nell'interfaccia utente di Bitbucket accedendo ai commit di un repository. Puoi trovare i commit del nostro repository demo al seguente indirizzo: https://bitbucket.org/dans9190/tutorial-documentation-tests/commits/all. L'output sarà simile a quello dell'utility della riga di comando git log
e può esserti utile per trovare e identificare un commit da annullare.
Nel prossimo esempio puoi vedere diversi elementi nella cronologia, ma di fatto ogni modifica consiste in un commit che dovremo trovare e annullare.
$ git status
On branch main
Your branch is up-to-date with 'origin/main'.
nothing to commit, working tree clean
$ git log
commit 1f08a70e28d84d5034a8076db9103f22ec2e982c
Author: Daniel Stevens <dstevens@atlassian.com>
Date: Wed Feb 7 17:06:50 2018 +0000
Initial Bitbucket Pipelines configuration
commit 52f823ca251a132225dd1cc18ad768de8d336e84
Author: Daniel Stevens <dstevens@atlassian.com>
Date: Fri Sep 30 15:50:58 2016 -0700
repeated quote to show how a change moves through the process
commit 4801b87c2147dce83f1bf31acfcffa6cb1d7e0a5
Merge: 1a6a403 3b29606
Author: Dan Stevens [Atlassian] <dstevens@atlassian.com>
Date: Fri Jul 29 18:45:34 2016 +0000
Merged in changes (pull request #6)
Changes
Analizziamo più nel dettaglio uno dei commit nella lista:
commit 52f823ca251a132225dd1cc18ad768de8d336e84
Author: Daniel Stevens <dstevens@atlassian.com>
Date: Fri Sep 30 15:50:58 2016 -0700
repeated quote to show how a change moves through the process
Come puoi notare, ogni messaggio di commit contiene quattro elementi:
Elemento | Descrizione |
---|---|
Hash del commit | Descrizione Una stringa alfanumerica (codificata con SHA-1) che identifica questa modifica specifica |
Autore | Descrizione La persona che ha eseguito il commit della modifica |
Data | Descrizione La data in cui è stato eseguito il commit della modifica nel progetto |
Messaggio di commit | Descrizione Una stringa di testo che descrive le modifiche. Suggerimento: scrivi messaggi di commit brevi e descrittivi e contribuirai alla creazione di un repository di lavoro migliore per tutti. |
Individuare un commit specifico
Molto probabilmente la modifica che desideri annullare si troverà abbastanza indietro nella cronologia del progetto, che può essere molto ampia. Impariamo quindi alcune operazioni di base che consistono nell'usare il comando git log
per trovare una modifica specifica.
1. Accedi alla finestra del tuo terminale e vai al livello superiore del tuo repository locale usando il comando cd
(cambia directory).
$ cd ~/repos/tutorial-documentation-tests/
Inserisci il comando git log --oneline
. Aggiungendo --oneline
, visualizzerai ogni commit su una riga separata e vedrai una porzione maggiore di cronologia nel tuo terminale.
Premi il tasto q per uscire dal log di commit e tornare al tuo prompt dei comandi in qualsiasi momento.
Il prossimo esempio mostra ciò che vedrai:
$ git log --oneline
1f08a70 (HEAD -> main, origin/main, origin/HEAD) Initial Bitbucket Pipelines configuration
52f823c repeated quote to show how a change moves through the process
4801b87 Merged in changes (pull request #6)
1a6a403 myquote edited online with Bitbucket
3b29606 (origin/changes) myquote2.html edited online with Bitbucket
8b236d9 myquote edited online with Bitbucket
235b9a7 testing prs
c5826da more changes
...
2. Premi il tasto q per tornare al tuo prompt dei comandi.
3. Individua il commit con l'hash c5826da
e altre modifiche nella lista che ha prodotto il comando git log
. Qualcuno non ha scritto un messaggio di commit descrittivo, quindi dovremo capire se sono presenti le modifiche di cui abbiamo bisogno.
4. Evidenzia e copia l'hash di commit c5826da
dal risultato di git log
nella finestra del terminale.
5. Digita git show
, quindi incolla o trascrivi l'hash del commit che hai copiato e premi Invio. Dovresti vedere quanto segue:
$git show c5826daeb6ee3fd89e63ce35fc9f3594fe243605
commit c5826daeb6ee3fd89e63ce35fc9f3594fe243605
Author: Daniel Stevens <dstevens@atlassian.com>
Date: Tue Sep 8 13:50:23 2015 -0700
more changes
diff --git a/README.md b/README.md
index bdaee88..6bb2629 100644
--- a/README.md
+++ b/README.md
@@ -11,12 +11,7 @@ This README would normally document whatever steps are necessary to get your app
### How do I get set up? ###
* Summary of set up
-* Configuration
-* Dependencies
-* Database configuration
-* How to run tests
-* Deployment instructions
-* more stuff and things
:
La compilazione del prompt in basso proseguirà fino a quando non mostrerà la modifica completa. Premi q per uscire dal tuo prompt dei comandi.
Applicare un filtro a git log per trovare un commit specifico
Questo filtro | Fa questo | Questo comando di esempio | Ha come risultato |
---|---|---|---|
| Fa questo Limita il numero di commit mostrati | Questo comando di esempio | Ha come risultato I 10 commit più recenti nella cronologia |
| Fa questo Limita i commit mostrati all'intervallo di tempo corrispondentePuoi anche usare | Questo comando di esempio | Ha come risultato Tutti i commit dopo il 4 luglio 2017 |
| Fa questo Elenca tutti i commit il cui autore corrisponde al nome | Questo comando di esempio | Ha come risultato Tutti i commit eseguiti da qualsiasi autore con Alana nel campo del nome |
| Fa questo Riporta tutti i commit con un messaggio di commit che corrisponde alla stringa che hai inserito | Questo comando di esempio | Ha come risultato Tutti i commit che contengono la stringa di testo HOT- nel messaggio |
Ti abbiamo presentato una breve panoramica del comando git log
. Se ti interessa, dai un'occhiata anche al tutorial avanzato sul comando git log.
Annullare una modifica con git reset
Per iniziare, annulliamo l'ultimo commit nella cronologia. In questo caso, supponiamo che tu abbia appena abilitato le pipelines CI/CD di Bitbucket ma hai capito che lo script non è del tutto corretto.
1. Inserisci git log --oneline
nella finestra del tuo terminale.
2. Copia l'hash del commit per il secondo commit nel log: 52f823c
, quindi premi q per uscire dal log.
3. Inserisci git reset --soft 52f823c
nella finestra del tuo terminale. Il comando dovrebbe essere eseguito in background se ha esito positivo. Ecco fatto! Hai apportato la tua prima modifica. Ora vediamo il risultato di questa azione.
4. Inserisci git status
nella finestra del tuo terminale e vedrai che il commit è stato annullato ed è diventato una modifica senza commit. Dovrebbe avere il seguente aspetto:
$ git status
On branch main
Your branch is behind 'origin/main' by 1 commit, and can be fast-forwarded.
(use "git pull" to update your local branch)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: bitbucket-pipelines.yml
5. Inserisci git log --oneline
nella finestra del tuo terminale. Dovresti vedere quanto segue:
$ git log --oneline
52f823c repeated quote to show how a change moves through the process
4801b87 Merged in changes (pull request #6)
1a6a403 myquote edited online with Bitbucket
3b29606 (origin/changes) myquote2.html edited online with Bitbucket
8b236d9 myquote edited online with Bitbucket
235b9a7 testing prs
c5826da more changes
43a87f4 remivng
d5c4c62 a few small changes
23a7476 Merged in new-feature2 (pull request #3)
5cc4e1e add a commit message
cbbb5d6 trying a thing
438f956 adding section for permissions and cleaning up some formatting
23251c1 updated snipptes.xml organization into resources. other files misc changes
3f630f8 Adding file to track changes
6. Noterai che il nuovo valore HEAD
del branch è il commit 52f823c
, che è esattamente ciò che volevi.
7. Premi q per uscire dal log. Lascia aperto il tuo terminale perché, ora che sai eseguire un semplice ripristino, proveremo a fare qualcosa di un po' più complesso.
Annullare più modifiche con git reset
Per iniziare, annulliamo l'ultimo commit nella cronologia. In questo caso, supponiamo che tu abbia appena abilitato le pipelines CI/CD di Bitbucket ma hai capito che lo script non è del tutto corretto.
1. Inserisci git log --online
2. Copia l'hash del commit 1a6a403
(modificato in myquote online con Bitbucket), che corrisponde al commit nella richiesta di pull #6 contenente le modifiche che desideriamo annullare.
3. Inserisci git reset 1a6a403
nella finestra del tuo terminale. L'output dovrebbe avere il seguente aspetto:
$ git reset 1a6a403
Unstaged changes after reset:
M README.md
M myquote2.html
Noterai che ora le modifiche sono in uno stato "senza commit". Ciò significa che abbiamo rimosso diverse modifiche sia dalla cronologia del progetto che dall'area di gestione.
4. Inserisci git status
nella finestra del tuo terminale. L'output dovrebbe avere il seguente aspetto:
$ git status
On branch main
Your branch is behind 'origin/main' by 6 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README.md
modified: myquote2.html
Untracked files:
(use "git add <file>..." to include in what will be committed)
bitbucket-pipelines.yml
no changes added to commit (use "git add" and/or "git commit -a")
Ora puoi vedere che la prima modifica che abbiamo annullato (il file bitbucket-pipelines.yml
) non è tracciata da git
. Questo perché git reset
rimuove la modifica sia dalla testa del branch che dall'area di monitoraggio o dell'indice di git
. Il processo alla base è più complesso di quanto sembri. Puoi approfondire questo argomento in git reset
.
5. Inserisci git log --oneline
nella finestra del tuo terminale.
1a6a403 myquote edited online with Bitbucket
8b236d9 myquote edited online with Bitbucket
43a87f4 remivng
d5c4c62 a few small changes
23a7476 Merged in new-feature2 (pull request #3)
5cc4e1e add a commit message
cbbb5d6 trying a thing
438f956 adding section for permissions and cleaning up some formatting
23251c1 updated snipptes.xml organization into resources. other files misc changes
3f630f8 Adding file to track changes
e52470d README.md edited online with Bitbucket
e2fad94 README.md edited online with Bitbucket
592f84f Merge branch 'main' into new-feature2 Merge branch especially if it merges an updated upstream into a topic branch.
7d0bab8 added a line
879f965 adding to the quote file
8994332 Merged in HOT-235 (pull request #2)
b4a0b43 removed sarcastic remarks because they violate policy.
b5f5199 myquote2.html created online with Bitbucket
b851618 adding my first file
5b43509 writing and using tests
Ora l'output del log mostra che è stata modificata anche la cronologia del commit e inizia con il commit 1a6a403. A titolo esemplificativo, supponiamo ora di voler annullare il ripristino che abbiamo appena eseguito. Dopo ulteriori considerazioni, forse preferiamo mantenere i contenuti della richiesta di pull #6.
Eseguire il push delle reimpostazioni a Bitbucket
Il comando git reset
costituisce uno dei pochi metodi "annulla" offerti da Git
. In genere il ripristino viene considerato un'opzione "non sicura" per annullare le modifiche. Va bene quando si lavora localmente su un codice isolato ma diventa rischioso quando lo condivi con i membri del team.
Per condividere un branch che è stato ripristinato con un team in remoto, è necessario eseguire un "push forzato". Puoi avviare un "push forzato" eseguendo git push -f
. Un push forzato distruggerà qualsiasi cronologia sul branch successiva all'ultimo push.
Segue un esempio di questo scenario "non sicuro":
- Lo sviluppatore A sta lavorando su un branch per sviluppare una nuova funzione.
- Lo sviluppatore B sta lavorando sullo stesso branch per sviluppare un'altra funzione.
- Lo sviluppatore B decide di ripristinare il branch a uno stato precedente al momento in cui gli sviluppatori A e B hanno iniziato a lavorare.
- Lo sviluppatore B esegue quindi il push forzato per ripristinare il branch al repository remoto.
- Lo sviluppatore A esegue il pull del branch per ricevere eventuali aggiornamenti. Durante questa fase, lo sviluppatore A riceve l'aggiornamento forzato. Questo ripristina il branch locale dello sviluppatore A a una versione precedente e i commit vanno perduti.
Annullare un comando git reset
Finora abbiamo passato gli hash SHA dei git commit
ai git reset
. Ora l'output di git log
non contiene i commit che abbiamo ripristinato. Come possiamo recuperarli? Git non elimina mai completamente un commit a meno che non sia stato rimosso anche il puntatore. Inoltre Git
memorizza un log separato di tutte le operazioni, definito "reflog". Possiamo esaminare il reflog eseguendo il comando git reflog
.
1a6a403 HEAD@{0}: reset: moving to 1a6a403
1f08a70 HEAD@{1}: reset: moving to origin/main
1f08a70 HEAD@{2}: clone: from git@bitbucket.org:dans9190/tutorial-documentation-tests.git
L'output di git reflog
dovrebbe essere simile a quello mostrato sopra. Puoi vedere la cronologia delle azioni nel repository. La riga in alto è un riferimento all'operazione che abbiamo eseguito per reimpostare la pull request n.6. Ora eseguiamo un'ulteriore operazione di reimpostazione della pull request n.6. La seconda colonna dell'output di questo reflog indica un puntatore di riferimento a un'azione di modifica eseguita sul repository. Qui HEAD@{{0}}
è un riferimento al comando di reimpostazione eseguito in precedenza. Non vogliamo ripetere tale comando di reimpostazione, quindi reimposteremo il repository su HEAD@{{1}}.
$ git reset --hard HEAD@{1}
HEAD is now at 1f08a70 Initial Bitbucket Pipelines configuration
Esaminiamo ora la cronologia dei commit dei repository con git log --oneline
:
$git log --online
1f08a70 Initial Bitbucket Pipelines configuration
52f823c repeated quote to show how a change moves through the process
4801b87 Merged in changes (pull request #6)
1a6a403 myquote edited online with Bitbucket
3b29606 myquote2.html edited online with Bitbucket
8b236d9 myquote edited online with Bitbucket
235b9a7 testing prs
c5826da more changes
43a87f4 remivng
d5c4c62 a few small changes
23a7476 Merged in new-feature2 (pull request #3)
5cc4e1e add a commit message
cbbb5d6 trying a thing
438f956 adding section for permissions and cleaning up some formatting
23251c1 updated snipptes.xml organization into resources. other files misc changes
3f630f8 Adding file to track changes
e52470d README.md edited online with Bitbucket
e2fad94 README.md edited online with Bitbucket
592f84f Merge branch 'main' into new-feature2 Merge branch especially if it merges an updated upstream into a topic branch.
7d0bab8 added a line
:
Ora l'output del log mostra che è stata modificata anche la cronologia del commit e inizia con il commit 1a6a403. A titolo esemplificativo, supponiamo ora di voler annullare il ripristino che abbiamo appena eseguito. Dopo ulteriori considerazioni, forse preferiamo mantenere i contenuti della richiesta di pull #6.
git revert
Gli esempi precedenti hanno illustrato alcune operazioni di annullamento usando git reset
e git reflog
. Git contiene un'altra utility "annulla" che viene spesso considerata "più sicura" rispetto al ripristino. L'inversione crea nuovi commit che invertono le modifiche apportate ai commit specificati. È possibile eseguire in modo sicuro il push di questi commit di inversione in repository remoti per poterli condividere con altri sviluppatori.
La seguente sezione mostrerà l'uso del comando git revert
. Continuiamo con l'esempio della sezione precedente. Per iniziare, esaminiamo il log e troviamo un commit da invertire.
$ git log --online
1f08a70 Initial Bitbucket Pipelines configuration
52f823c repeated quote to show how a change moves through the process
4801b87 Merged in changes (pull request #6)
1a6a403 myquote edited online with Bitbucket
1f08a70 Initial Bitbucket Pipelines configuration
52f823c repeated quote to show how a change moves through the process
4801b87 Merged in changes (pull request #6)
1a6a403 myquote edited online with Bitbucket
3b29606 myquote2.html edited online with Bitbucket
8b236d9 myquote edited online with Bitbucket
235b9a7 testing prs
c5826da more changes
43a87f4 remivng
d5c4c62 a few small changes
23a7476 Merged in new-feature2 (pull request #3)
5cc4e1e add a commit message
cbbb5d6 trying a thing
438f956 adding section for permissions and cleaning up some formatting
23251c1 updated snipptes.xml organization into resources. other files misc changes
3f630f8 Adding file to track changes
e52470d README.md edited online with Bitbucket
e2fad94 README.md edited online with Bitbucket
592f84f Merge branch 'main' into new-feature2 Merge branch especially if it merges an updated upstream into a topic branch.
7d0bab8 added a line
:
Per questo esempio selezioniamo il commit 1f08a70
più recente come commit su cui operare. In questo caso, supponiamo di voler annullare le modifiche apportate nel commit. Esegui:
$ git revert 1f08a70
Avvierai un flusso di lavoro git merge
. Git creerà un nuovo commit il cui contenuto consiste in un'inversione del commit specificato per l'inversione. Git aprirà quindi un editor di testo configurato per eseguire un nuovo messaggio di commit. L'inversione è considerata l'opzione di annullamento più sicura a causa di questo flusso di lavoro di commit. La creazione di commit di inversione lascia una traccia evidente nella cronologia dei commit, che testimonia il momento in cui è stata eseguita l'operazione di annullamento.
Hai appena imparato ad annullare le modifiche!
Congratulazioni, hai completato il tutorial. Torna qui in qualsiasi momento o vai alla sezione Annullamento delle modifiche per approfondire questo argomento. Continua così!
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.