TL;DR
-
git resetsposta il puntatore del branch indietro, rimuovendo commit dalla cronologia. Usalo per pulizie locali prima del push. -
git reset --softmantiene le modifiche nell'area di staging,--mixed(predefinito) le rimuove dallo staging, e--hardle scarta completamente. -
git revertcrea un nuovo commit che annulla un commit precedente. Usalo per modifiche già pushate su un branch condiviso. -
Non usare mai
git resetsu branch condivisi. Se qualcosa è già stato pushato, usa invecegit revert. -
Se esegui per errore
git reset --hard, controllagit reflogper recuperare i commit persi.
Cos'è Git?
Git è uno strumento open-source di controllo versione creato nel 2005 da Linus Torvalds. Viene usato principalmente per tracciare in modo efficiente le modifiche ai file di progetto, così che i membri del progetto abbiano uno storico di tutti i cambiamenti e possano unire le modifiche senza perdere informazioni preziose. Il nostro
Inoltre, il corso Introduction to GitHub Concepts copre le funzionalità chiave di GitHub, la navigazione dell'interfaccia e come svolgere con successo le attività collaborative quotidiane.
Git revert e Git reset sono due comandi usati in Git per annullare modifiche al codice e alla cronologia del progetto, ma in modi diversi. Prima di entrare nel vivo, creiamo un progetto Git.
Crea un progetto Git
Di seguito trovi le istruzioni per creare un progetto git e inizializzarlo con alcuni file:
mkdir git_revert_reset
cd git_revert_reset
git init .
-
mkdir git_revert_resetcrea una cartella chiamatagit_revert_reset. -
cd git_revert_resetsposta nella cartella. -
git init .inizializza la cartella come repository git.
Considerandolo come un progetto di data science, possiamo creare i seguenti file per acquisizione dati, preprocessing e training del modello usando il comando touch:
touch data_acquisition.py data_preprocessing.py model_training.py
Questo è il contenuto finale della cartella del progetto.
git_revert_reset
|---------- data_acquisition.py
|---------- data_preprocessing.py
|---------- model_training.py
Git Reset

Diagramma di Git Reset (Fonte)
Il comando git reset viene usato per annullare le modifiche nella working directory e tornare a un commit specifico scartando tutti i commit effettuati dopo di esso.
Per esempio, immagina di aver fatto dieci commit. Usando git reset sul primo commit, rimuoverai tutti e nove i commit successivi, tornando allo stato del primo commit.
Prima di usare git reset, è importante considerare il tipo di modifiche che intendi fare; altrimenti, rischi di creare più caos che benefici.
Puoi usare diverse opzioni insieme a git reset, ma queste sono le principali. Ognuna si usa in base alla situazione: git reset --soft, git reset --mixed e git reset --hard
git reset --soft
L'opzione --soft serve a spostare il riferimento di HEAD (dove si trova l'ultimo commit in locale) a un commit specifico. Per esempio, se ti accorgi di aver dimenticato di aggiungere un file al commit, puoi tornare indietro usando --soft secondo il seguente formato:
-
git reset --soft HEAD~nper tornare al commit con un riferimento specifico (n).git reset --soft HEAD~1torna all'ultimo commit. -
git reset --soft <commit ID>sposta indietro la head al<commit ID>.
Vediamo alcuni esempi.
git add data_acquisition.py data_preprocessing.py
git commit -m "added data acquisition and preprocessing scripts"
Questo è il risultato del comando precedente.
[master (root-commit) faf864e] added data acquisition and preprocessing scripts
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 data_acquisition.py
create mode 100644 data_preprocessing.py
Possiamo controllare lo stato del commit come segue:
git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
model_training.py
nothing added to commit but untracked files present (use "git add" to track)
Ma abbiamo dimenticato di aggiungere lo script model_training.py al commit.
Poiché l'ultimo commit si trova in HEAD, possiamo sistemare il problema eseguendo le tre istruzioni seguenti.
-
Annulla l'ultimo commit mantenendo le modifiche in staging con
git reset --soft HEAD~1. -
Aggiungi il file dimenticato con
git add. -
Registra le modifiche con un commit finale
git commit.
git reset --soft HEAD~1
git add model_training.py
git commit -m "added all the python scripts"
Il risultato seguente ha riportato git reset a master dopo tutti i passaggi precedenti:
[master (root-commit) faf864e] added all the python scripts
3 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 data_acquisition.py
create mode 100644 data_preprocessing.py
create mode 100644 model_training.py
Per una spiegazione più approfondita dei reset soft, vedi la nostra guida completa a Git Reset Soft. Se devi solo correggere il messaggio dell’ultimo commit o aggiungere file dimenticati, git commit --amend è spesso un'alternativa più rapida al reset.
git reset --mixed
Questa è l'opzione predefinita di git reset. Eseguire questo comando ha due effetti: (1) annulla tutti i commit e (2) rimuove le modifiche dallo staging. Immagina di aver aggiunto per errore il file model_training.py e di volerlo togliere perché l'addestramento del modello non è ancora finito. Ecco come procedere:
- Rimuovi dallo staging i file che erano nel commit con git reset HEAD
- Aggiungi solo i file di cui hai bisogno per il commit
git reset HEAD
git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
model_training.py
data_acquisition.py
data_preprocessing.py
nothing added to commit but untracked files present (use "git add" to track)
Ora possiamo aggiungere solo gli ultimi due file da includere nel commit e poi effettuare il commit.
git add data_acquisition.py data_preprocessing.py
git commit -m "Removed the model_training.py from the commit"
git reset --hard
Questa opzione può essere pericolosa. Quindi, usala con cautela!
In pratica, quando esegui un hard reset su un commit specifico, forzi HEAD a tornare a quel commit ed elimini tutto il resto dopo di esso.
Prima di eseguire l'hard reset, diamo un'occhiata al contenuto della cartella.
ls
data_acquisition.py data_preprocessing.py model_training.py
git reset --hard
HEAD is now at 97159bc added data acquisition and preprocessing scripts
Ora controlliamo il contenuto della cartella:
ls
data_acquisition.py data_preprocessing.py
Notiamo che il file non tracciato model_training.py è stato eliminato. Di nuovo, assicurati di capire cosa stai facendo con il reset, perché le conseguenze possono essere drastiche!
Se esegui per errore un hard reset, git reflog è la tua rete di sicurezza. Git conserva un log di tutte le modifiche ai riferimenti per circa 30 giorni, quindi spesso puoi recuperare i commit "persi" eseguendo git reflog e poi git reset --hard HEAD@{n} per tornare allo stato precedente al reset. Nota che le modifiche non committate o non in staging non possono essere recuperate in questo modo.
Git Revert

Prima e dopo il Revert (Fonte)
Git revert è simile a git reset, ma l'approccio è leggermente diverso. Invece di rimuovere tutti i commit lungo il percorso, il revert annulla SOLO un singolo commit riportandoti ai file in staging prima del commit.
Quindi, invece di rimuovere un commit, git revert inverte le modifiche introdotte dal commit originale creando un nuovo commit con il contenuto inverso. È un modo sicuro per annullare un commit perché evita di perdere la cronologia.
È importante sapere che il revert non ha effetto se non specifichi l'hash o il riferimento del commit.
Esploriamo alcune opzioni comuni di git revert.
git revert --no-edit <commit ID>
L'opzione --no-edit consente di non modificare il messaggio usato per il commit che vuoi annullare, e farà sì che git revert applichi la modifica sul branch master.
Per illustrare questo scenario, creiamo due nuovi file da aggiungere.
touch model_monitoring.py data_monitoring.py
Dopo aver creato questi file, dobbiamo aggiungerli all'area di staging delle modifiche.
git add model_monitoring.py
Prima di procedere, diamo un'occhiata allo stato eseguendo il seguente comando.
git status
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: data_monitoring.py
new file: model_monitoring.py
Possiamo osservare che i due file sono stati aggiunti, ora possiamo fare il commit delle modifiche.
git commit -m "Added the monitoring script files"
[master (root-commit) eae84e7] Added the monitoring script files
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 data_monitoring.py
create mode 100644 model_monitoring.py
Quindi, l'hash del commit può essere ottenuto con il seguente comando. È utile quando vuoi agire su quello specifico commit.
git reflog
eae84e7 (HEAD -> master) HEAD@{0}: commit (initial): Added the monitoring script files
Ora, immaginiamo che il commit precedente non fosse intenzionale e vogliamo eliminarlo.
git revert --no-edit eae84e7
[master c61ef6b] Revert "Added the monitoring script files"
Date: Sat Nov 12 20:14:17 2022 -0600
2 files changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 data_monitoring.py
delete mode 100644 model_monitoring.py
Diamo un'occhiata al log dei commit:
git log
commit c61ef6b4e86f41f47c8c77de3b5fca3945a7c075 (HEAD -> master)
Author: Zoumana Keita <[email protected]>
Date: Sat Nov 12 20:14:17 2022 -0600
Revert "Added the monitoring script files"
This reverts commit eae84e7669af733ee6c1b854f2fcd9acfea9d4a3.
commit eae84e7669af733ee6c1b854f2fcd9acfea9d4a3
Author: Zoumana Keita <[email protected]>
Date: Sat Nov 12 20:05:57 2022 -0600
Added the monitoring script files
Dal log, notiamo che è stato creato un nuovo commit con l'ID c61ef6b4e86f41f47c8c77de3b5fca3945a7c075 per invertire il commit originale con l'ID eae84e7669af733ee6c1b854f2fcd9acfea9d4a3.
In questo esempio, dato che abbiamo un singolo commit, potremmo usare git revert HEAD, che ha lo stesso effetto. Per altri esempi, vedi la nostra guida per fare il revert dell'ultimo commit.
git revert <commit hash>
Questo rimuoverà solo le modifiche associate a quell'hash di commit e non influenzerà nessun altro commit.
Quale git revert pensi avrà effetto, considerando l'ID generato in precedenza?
Se la tua risposta è stata c61ef6b4e86f41f47c8c77de3b5fca3945a7c075 allora hai ragione. Considerare eae84e7669af733ee6c1b854f2fcd9acfea9d4a3 non avrà effetto, poiché è stato sostituito da uno nuovo.
Vediamo cosa succede provando a eseguire il revert.
git revert c61ef6b4e86f41f47c8c77de3b5fca3945a7c075
[master aaead40] Revert "Revert "Added the monitoring script files""
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 data_monitoring.py
create mode 100644 model_monitoring.py
Come puoi vedere, i due file creati e committati inizialmente sono tornati!
git revert --no-commit <commit ID>
Lo scopo di usare l'opzione --no-commit o -n è impedire a git di creare automaticamente il commit del revert. Questo è utile se vuoi rivedere le modifiche apportate dal revert prima di committarle.
Consideriamo il seguente esempio:
git revert --no-commit c61ef6b4e86f41f47c8c77de3b5fca3945a7c075
Questo annullerà le modifiche apportate dal commit con ID c61ef6b4e86f41f47c8c77de3b5fca3945a7c075 ma non creerà automaticamente un nuovo commit per registrare il revert. Invece, metterà in staging le modifiche inverse così che tu possa rivederle e decidere se committare manualmente il revert.
Git Revert vs. Reset
git reset e git revert annullano entrambi le modifiche, ma funzionano in modo diverso e si adattano a situazioni diverse.
| Criterio | git reset | git revert |
|---|---|---|
| Come funziona | Sposta indietro il puntatore del branch, scartando commit dalla cronologia | Crea un nuovo commit che inverte le modifiche di un commit precedente |
| Cronologia dei commit | Riscrive la cronologia (i commit vengono rimossi) | Preserva la cronologia completa (aggiunge un nuovo commit di revert) |
| Sicuro per branch condivisi? | No (i collaboratori avranno conflitti se hanno pullato i commit rimossi) | Sì (la cronologia resta coerente per tutti i collaboratori) |
| Portata | Può annullare più commit alla volta | Annulla un commit per volta (usa --no-commit per raggruppare) |
| Caso d'uso ideale | Pulire branch locali o privati prima del push | Annullare modifiche già pushate su un remote |
| Livello di rischio | Alto con --hard (elimina definitivamente il lavoro non committato) | Basso (nessun dato viene mai perso) |
Come regola generale: usa git reset per ripulire la cronologia locale non ancora pushata e git revert per annullare in sicurezza qualsiasi cosa altri possano aver pullato. Per i dettagli sul revert dei merge commit, vedi la nostra guida Git Revert Merge Commit.
Conclusione
Il punto chiave: usa git reset per ripulire la cronologia locale che non hai ancora pushato e git revert per annullare in sicurezza le modifiche su branch condivisi. Fai particolare attenzione con git reset --hard, perché rimuove in modo permanente le modifiche non committate dalla tua working directory.
Per continuare a migliorare le tue competenze con Git, dai un'occhiata a questi tutorial correlati di DataCamp:
Domande frequenti su Git Reset e Revert
Qual è la differenza tra git reset e git revert?
git reset viene usato per annullare commit nel repository locale spostando il puntatore del branch a un commit precedente, scartando di fatto i commit effettuati dopo quel punto. git revert, invece, viene usato per annullare modifiche già committate creando un nuovo commit che annulla le modifiche introdotte dal commit specifico.
Dovresti usare git reset hard?
Usa cautela con git reset hard perché può eliminare completamente le modifiche e rimuoverle dalla directory locale. Prima di usarlo, sii sicuro al 100% di quello che stai facendo.
Quando dovrei usare git reset?
git reset è utile quando vuoi annullare commit che non sono stati pushati su un repository remoto. Può essere usato per rimuovere commit che contengono errori o che non sono più necessari.
È importante notare che git reset è un'operazione locale e non influisce sul repository remoto. Se hai già pushato i commit che vuoi annullare, dovresti invece usare git revert.
Quando dovrei usare git revert?
git revert è utile quando vuoi annullare commit che sono già stati pushati su un repository remoto. È un'opzione sicura perché non elimina alcun commit e lascia una traccia chiara delle modifiche apportate nel repository.
È importante notare che git revert può annullare solo commit che non sono stati integrati in altri branch. Se vuoi annullare commit che fanno parte di un branch già mergiato, dovresti usare git reset o un altro metodo per rimuovere i commit.
Che cos'è git reset?
git reset viene usato per annullare modifiche nella tua cronologia di commit o nella working directory. Ti consente di reimpostare il tuo HEAD a un commit specifico e, opzionalmente, modificare l'indice (staging area) e la working directory.
Quali sono le differenze tra --soft, --mixed e --hard in git reset?
--soft: sposta HEAD al commit specificato ma mantiene le modifiche in staging per il commit. --mixed (predefinito): sposta HEAD al commit specificato e rimuove le modifiche dallo staging (mantiene intatta la working directory). --hard: sposta HEAD al commit specificato e scarta tutte le modifiche nell'indice e nella working directory.


Git è nato come strumento per sviluppatori software, ma è diventato lo standard per chiunque lavori con il codice. Oggi, data scientist, data engineer e machine learning engineer adottano anch'essi queste best practice.
In questo tutorial, tratto le differenze principali tra
git resetegit revert, due comandi Git per annullare modifiche. Ti mostrerò esempi pratici di ogni modalità, dall'inizializzazione di un progetto al revert di commit specifici.