git reset
Il comando git reset
è uno strumento complesso e versatile per l'annullamento delle modifiche. Ha tre forme principali di chiamata. Questi moduli corrispondono agli argomenti della riga di comando --soft, --mixed, --hard
. Ciascuno dei tre argomenti corrisponde ai tre meccanismi interni di gestione dello stato di Git: l'albero di commit (HEAD
), l'indice di staging e la directory di lavoro.
git reset e i tre alberi di Git
Per capire come utilizzare correttamente git reset
, occorre prima comprendere i sistemi di gestione interni di Git. A volte questi meccanismi sono definiti i "tre alberi" di Git. Definirli "alberi" può essere fuorviante, perché non si tratta di strutture di dati ad albero tradizionali, ma di strutture di dati basate su nodi e puntatori che Git utilizza per tenere traccia di una cronologia delle modifiche. Il modo migliore per fornire una dimostrazione di questi meccanismi è quello di creare un set di modifiche in un repository e di eseguirlo utilizzando i tre alberi.
Per iniziare, creeremo un nuovo repository con i seguenti comandi:
$ mkdir git_reset_test
$ cd git_reset_test/
$ git init .
Initialized empty Git repository in /git_reset_test/.git/
$ touch reset_lifecycle_file
$ git add reset_lifecycle_file
$ git commit -m"initial commit"
[main (root-commit) d386d86] initial commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 reset_lifecycle_file
Il codice di esempio riportato sopra crea un nuovo repository Git con un singolo file vuoto, reset_lifecycle_file
. A questo punto, il repository di esempio presenta un unico commit (d386d86
) derivante dall'aggiunta di reset_lifecycle_file
.
materiale correlato
Scheda di riferimento rapido di Git
Scopri la soluzione
Impara a utilizzare Git con Bitbucket Cloud
La directory di lavoro
Il primo albero che esamineremo è la "directory di lavoro". Questo albero è sincronizzato con il file system locale ed è una rappresentazione delle modifiche immediate apportate al contenuto di file e directory.
$ echo 'hello git reset' > reset_lifecycle_file
$ git status
On branch main
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: reset_lifecycle_file
Nel repository demo, modifichiamo e aggiungiamo alcuni contenuti a reset_lifecycle_file
. La chiamata di git status
indica che Git è a conoscenza delle modifiche apportate al file.demo Queste modifiche fanno attualmente parte del primo albero, "la directory di lavoro". git status
può essere utilizzato per mostrare le modifiche apportate a tale directory. Verranno visualizzate in rosso con un prefisso "modificato".
Indice di staging
Il prossimo albero è l'"indice di staging". Tiene traccia delle modifiche apportate dalla directory di lavoro, che sono state promosse con git add
, in modo che siano archiviate nel prossimo commit. Questo albero è un meccanismo di caching interno complesso. Git generalmente cerca di nascondere all'utente i dettagli di implementazione dell'indice di staging.
Per visualizzare con precisione lo stato dell'indice di staging dobbiamo utilizzare un comando Git meno noto, git ls-files
. Il comando git ls-files
è essenzialmente un'utilità di debug per ispezionare lo stato dell'albero indice di staging.
git ls-files -s
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 reset_lifecycle_file
Qui abbiamo eseguito git ls-files
con l'opzione -s
o --stage
. Senza l'opzione -s
, l'output di git ls-files
è semplicemente un elenco di nomi di file e percorsi che fanno attualmente parte dell'indice. L'opzione -s
mostra i metadati aggiuntivi per i file nell'indice di staging. Questi metadati sono i bit della modalità, il nome dell'oggetto e il numero di stage dei contenuti in staging. Ciò che qui ci interessa è il nome dell'oggetto, cioè il secondo valore (d7d77c1b04b5edd5acfc85de0b592449e5303770
). Questo è un hash SHA-1 standard di un oggetto Git. È un hash del contenuto dei file. La cronologia dei commit memorizza i propri oggetti SHA per identificare i puntatori a commit e riferimenti, e l'indice di staging ha i propri oggetti SHA per tenere traccia delle versioni dei file nell'indice.
Successivamente, promuoveremo reset_lifecycle_file
nell'indice di staging.
$ git add reset_lifecycle_file
$ git status
On branch main Changes to be committed:
(use "git reset HEAD ..." to unstage)
modified: reset_lifecycle_file
Qui abbiamo chiamato git add reset_lifecycle_file
, che aggiunge il file all'indice di staging. Quando si chiama git status
, reset_lifecycle_file
è visualizzato in verde sotto "Modifiche da sottoporre a commit". È importante notare che git status
non è una rappresentazione fedele dell'indice di staging. L'output del comando git status
visualizza le modifiche avvenute tra la cronologia dei commit e l'indice di staging. A questo punto esaminiamo il contenuto dell'indice di staging.
$ git ls-files -s 100644 d7d77c1b04b5edd5acfc85de0b592449e5303770 0 reset_lifecycle_file
Possiamo vedere che l'oggetto SHA per reset_lifecycle_file
è stato aggiornato da e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
a d7d77c1b04b5edd5acfc85de0b592449e5303770
.
Cronologia dei commit
L'ultimo albero è la cronologia dei commit. Il comando git commit
aggiunge modifiche a una snapshot permanente che risiede nella cronologia dei commit e che include anche lo stato dell'indice di staging al momento del commit.
$ git commit -am"update content of reset_lifecycle_file"
[main dc67808] update content of reset_lifecycle_file
1 file changed, 1 insertion(+)
$ git status
On branch main
nothing to commit, working tree clean
Qui abbiamo creato un nuovo commit con il messaggio "update content of resetlifecyclefile"
. Il set di modifiche è stato aggiunto alla cronologia dei commit. La chiamata di git status
a questo punto mostra che non sono presenti modifiche in sospeso a nessuno degli alberi. L'esecuzione di git log
mostrerà la cronologia dei commit. Ora che abbiamo seguito questo set di modifiche con i tre alberi, possiamo iniziare a utilizzare git reset
.
Come funziona
A un livello superficiale, git reset
ha un comportamento simile a quello di git checkout
. Mentre git checkout
opera esclusivamente sul puntatore di riferimento HEAD
, git reset
sposta il puntatore di riferimento HEAD
e il puntatore di riferimento del branch corrente. Per dimostrare meglio questo comportamento, considera l'esempio seguente.
Questo esempio dimostra una sequenza di commit sul branch main
. Il riferimento HEAD
e il riferimento del branch main
puntano attualmente al commit d. Ora eseguiamo e confrontiamo sia git checkout b
che git reset b.
git checkout b
Con git checkout
, il riferimento main
punta ancora a d
. Il riferimento HEAD
è stato spostato e ora indica il commit b
. Il repository ora è in uno stato HEAD
scollegato.
git reset b
git reset
, invece, sposta sia il riferimento HEAD
che i riferimenti del branch nel commit specificato.
Oltre ad aggiornare i puntatori dei riferimenti di commit, git reset
modifica lo stato dei tre alberi. La modifica dei puntatori di riferimento avviene sempre ed è un aggiornamento del terzo albero, l'albero di commit. Gli argomenti della riga di comando --soft, --mixed
e --hard
indicano come modificare gli alberi dell'indice di staging e della directory di lavoro.
Opzioni principali
La chiamata predefinita di git reset
ha argomenti impliciti --mixed
e HEAD
. Ciò significa che l'esecuzione di git reset
è equivalente all'esecuzione di git reset --mixed HEAD
. In questo modulo HEAD
è il commit specificato. Invece di HEAD
può essere utilizzato qualsiasi hash di commit Git SHA-1.
'--hard
Questa è l'opzione più diretta, più pericolosa e utilizzata con maggiore frequenza. Quando si passa --hard
i puntatori di riferimento della cronologia dei commit vengono aggiornati al commit specificato. Quindi, l'indice di staging e la directory di lavoro vengono ripristinati in modo da corrispondere a quelli del commit specificato. Qualsiasi precedente modifica in sospeso all'indice di staging e alla directory di lavoro viene ripristinata in modo da corrispondere allo stato dell'albero di commit. Ciò significa che qualsiasi processo in sospeso che era presente nell'indice di staging e nella directory di lavoro andrà perso.
Per dimostrarlo, continuiamo con il repository di esempio a tre alberi che abbiamo creato in precedenza. Innanzitutto apportiamo alcune modifiche al repository. Esegui i seguenti comandi nel repository di esempio:
$ echo 'new file content' > new_file
$ git add new_file
$ echo 'changed content' >> reset_lifecycle_file
Questi comandi hanno creato un nuovo file denominato new_file
e lo hanno aggiunto al repository. Inoltre, il contenuto di reset_lifecycle_file
verrà modificato. Dopo aver apportato queste modifiche, esaminiamo lo stato del repository utilizzando git status
.
$ git status
On branch main
Changes to be committed:
(use "git reset HEAD ..." to unstage)
new file: new_file
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: reset_lifecycle_file
Qui abbiamo chiamato git add reset_lifecycle_file
, che aggiunge il file all'indice di staging. Quando si chiama git status
, reset_lifecycle_file
è visualizzato in verde sotto "Modifiche da sottoporre a commit". È importante notare che git status
non è una rappresentazione fedele dell'indice di staging. L'output del comando git status
visualizza le modifiche avvenute tra la cronologia dei commit e l'indice di staging. A questo punto esaminiamo il contenuto dell'indice di staging.
$ git ls-files -s
100644 8e66654a5477b1bf4765946147c49509a431f963 0 new_file
100644 d7d77c1b04b5edd5acfc85de0b592449e5303770 0 reset_lifecycle_file
Possiamo vedere che new_file
è stato aggiunto all'indice. Abbiamo apportato aggiornamenti a reset_lifecycle_file
, ma lo SHA dell'indice di staging (d7d77c1b04b5edd5acfc85de0b592449e5303770
) resta invariato. È il comportamento previsto perché non ho utilizzato git add
per promuovere queste modifiche all'indice di staging. Queste modifiche sono presenti nella directory di lavoro.
Ora eseguiamo il comando git reset --hard
ed esaminiamo il nuovo stato del repository.
$ git reset --hard
HEAD is now at dc67808 update content of reset_lifecycle_file
$ git status
On branch main
nothing to commit, working tree clean
$ git ls-files -s
100644 d7d77c1b04b5edd5acfc85de0b592449e5303770 0 reset_lifecycle_file
Qui abbiamo eseguito un "hard reset" utilizzando l'opzione --hard
. Git visualizza l'output in cui è indicato che HEAD
punta all'ultimo commit dc67808
. Successivamente, controlliamo lo stato del repository con git status
. Git indica che non sono presenti modifiche in sospeso. Esaminiamo anche lo stato dell'indice di staging e vediamo che è stato ripristinato a un punto precedente all'aggiunta di new_file
. Le modifiche apportate a reset_lifecycle_file
e l'aggiunta di new_file
sono state eliminate. Questa perdita di dati non può essere annullata, quindi è fondamentale tenerne conto.
'--mixed
Questa è la modalità operativa predefinita. I puntatori di riferimento sono aggiornati. L'indice di staging è ripristinato allo stato del commit specificato. Le eventuali modifiche annullate dall'indice di staging vengono spostate nella directory di lavoro. Continuiamo.
$ echo 'new file content' > new_file
$ git add new_file
$ echo 'append content' >> reset_lifecycle_file
$ git add reset_lifecycle_file
$ git status
On branch main
Changes to be committed:
(use "git reset HEAD ..." to unstage)
new file: new_file
modified: reset_lifecycle_file
$ git ls-files -s
100644 8e66654a5477b1bf4765946147c49509a431f963 0 new_file
100644 7ab362db063f9e9426901092c00a3394b4bec53d 0 reset_lifecycle_file
Nell'esempio riportato sopra abbiamo apportato alcune modifiche al repository. Ancora una volta, abbiamo aggiunto new_file
e modificato il contenuto di reset_lifecycle_file
. Queste modifiche vengono quindi applicate all'indice di staging con git add
. Con il repository in questo stato, ora eseguiamo il reset.
$ git reset --mixed
$ git status
On branch main
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: reset_lifecycle_file
Untracked files:
(use "git add ..." to include in what will be committed)
new_file
no changes added to commit (use "git add" and/or "git commit -a")
$ git ls-files -s
100644 d7d77c1b04b5edd5acfc85de0b592449e5303770 0 reset_lifecycle_file
Qui abbiamo eseguito un "reset misto". Lo ripetiamo: --mixed
è la modalità predefinita e ha lo stesso effetto dell'esecuzione di git reset
. L'output di git status
e git ls-files
mostra che l'indice di staging è stato ripristinato allo stato in cui reset_lifecycle_file
è l'unico file nell'indice. L'oggetto SHA per reset_lifecycle_file
è stato ripristinato alla versione precedente.
L'aspetto importante da tenere presente è che git status
mostra che ci sono delle modifiche a reset_lifecycle_file
e che è presente un file non monitorato: new_file
. Si tratta del comportamento --misto
esplicito. L'indice di staging è stato ripristinato e le modifiche in sospeso sono state spostate nella directory di lavoro. Nel caso dell'--hard
reset, invece, oltre all'indice di staging è stata ripristinata anche la directory di lavoro e questi aggiornamenti sono andati persi.
'--soft
Quando viene passato l'argomento --soft
, i puntatori di riferimento vengono aggiornati e il reset si interrompe qui. L'indice di staging e la directory di lavoro restano invariati. Questo comportamento può essere difficile da dimostrare in modo chiaro. Proseguiamo con il nostro repository dimostrativo e prepariamolo per un soft reset.
$ git add reset_lifecycle_file
$ git ls-files -s
100644 67cc52710639e5da6b515416fd779d0741e3762e 0 reset_lifecycle_file
$ git status
On branch main
Changes to be committed:
(use "git reset HEAD ..." to unstage)
modified: reset_lifecycle_file
Untracked files:
(use "git add ..." to include in what will be committed)
new_file
Qui abbiamo nuovamente utilizzato git add
per promuovere reset_lifecycle_file
modificato nell'indice di staging. Confermiamo che l'indice è stato aggiornato con l'output git ls-files
. Nell'output di git status
"Modifiche da sottoporre a commit" ora è visualizzato in verde. Il file new_file
degli esempi precedenti è presente nella directory di lavoro come file non monitorato. Eseguiamo rapidamente rm new_file
per eliminare il file in quanto non ci servirà per i prossimi esempi.
Con il repository in questo stato, ora eseguiamo un soft reset.
$ git reset --soft
$ git status
On branch main
Changes to be committed:
(use "git reset HEAD ..." to unstage)
modified: reset_lifecycle_file
$ git ls-files -s
100644 67cc52710639e5da6b515416fd779d0741e3762e 0 reset_lifecycle_file
Abbiamo eseguito un "soft reset". Esaminando lo stato del repository con git status
e git ls-files
vediamo che non è cambiato nulla. Si tratta del comportamento previsto. Un soft reset eseguirà solo il reset della cronologia dei commit. Per impostazione predefinita, git reset
è chiamato con HEAD
come commit di destinazione. Poiché la cronologia dei commit era già in HEAD
e abbiamo implicitamente effettuato il reset su HEAD
, non si è verificato alcun cambiamento.
Per comprendere e utilizzare meglio --soft
, ci serve un commit di destinazione che non sia HEAD
. reset_lifecycle_file
è in attesa nell'indice di staging. Creiamo un nuovo commit.
$ git commit -m"prepend content to reset_lifecycle_file"
A questo punto, il nostro repository dovrebbe avere tre commit. Torneremo indietro nel tempo al primo commit. A tale scopo, ci servirà l'ID del primo commit, che può essere trovato visualizzando l'output di git log
.
$ git log
commit 62e793f6941c7e0d4ad9a1345a175fe8f45cb9df
Author: bitbucket
Date: Fri Dec 1 15:03:07 2017 -0800
prepend content to reset_lifecycle_file
commit dc67808a6da9f0dec51ed16d3d8823f28e1a72a
Author: bitbucket
Date: Fri Dec 1 10:21:57 2017 -0800
update content of reset_lifecycle_file
commit 780411da3b47117270c0e3a8d5dcfd11d28d04a4
Author: bitbucket
Date: Thu Nov 30 16:50:39 2017 -0800
initial commit
Tieni presente che gli ID della cronologia dei commit sono univoci per ogni sistema. Ciò significa che gli ID di commit in questo esempio saranno diversi da quelli che vedrai sul tuo PC. L'ID di commit che ci interessa per questo esempio è 780411da3b47117270c0e3a8d5dcfd11d28d04a4
. Si tratta dell'ID che corrisponde al "commit iniziale". Una volta individuato l'ID, lo useremo come destinazione per il soft reset.
Prima di intraprendere il nostro viaggio indietro nel tempo, controlliamo lo stato attuale del repository.
$ git status && git ls-files -s
On branch main
nothing to commit, working tree clean
100644 67cc52710639e5da6b515416fd779d0741e3762e 0 reset_lifecycle_file
Qui eseguiamo un comando combinato di git status e
git ls-files -s
. Mostra che sono presenti modifiche in sospeso al repository e che il file reset_lifecycle_file
nell'indice di staging ha una versione di 67cc52710639e5da6b515416fd779d0741e3762e
. Tenendo conto di questo aspetto, eseguiamo un soft reset al nostro primo commit.
$git reset --soft 780411da3b47117270c0e3a8d5dcfd11d28d04a4
$ git status && git ls-files -s
On branch main
Changes to be committed:
(use "git reset HEAD ..." to unstage)
modified: reset_lifecycle_file
100644 67cc52710639e5da6b515416fd779d0741e3762e 0 reset_lifecycle_file
Il codice riportato sopra esegue un "soft reset" e chiama anche il comando combinato git status
e git ls-files
, che restituisce lo stato del repository. Possiamo esaminare l'output dello stato del repository e tenere conto di alcune osservazioni interessanti. Innanzitutto, git status
indica che sono state apportate modifiche a reset_lifecycle_file
e le evidenzia indicando che si tratta di modifiche in staging per il commit successivo. In secondo luogo, l'input git ls-files
indica che l'indice di staging non è cambiato e mantiene lo SHA 67cc52710639e5da6b515416fd779d0741e3762e che avevamo in precedenza.
Per chiarire ulteriormente cosa è successo in questo reset, esaminiamo il git log:
$ git log commit 780411da3b47117270c0e3a8d5dcfd11d28d04a4 Author: bitbucket Date: Thu Nov 30 16:50:39 2017 -0800 initial commit
L'output del log ora mostra che è presente un solo commit nella cronologia dei commit. Questo aiuta a illustrare chiaramente l'azione di --soft
. Analogamente a tutte le chiamate git reset
, la prima azione necessaria per il reset è il reset dell'albero di commit. I nostri esempi precedenti con --hard
e --mixed
puntavano entrambi a HEAD
e non hanno spostato l'albero di commit indietro nel tempo. Durante un soft reset, questo è tutto ciò che accade.
Ciò potrebbe quindi creare confusione riguardo ai motivi per cui git status
indica che sono presenti file modificati. --soft
non modifica l'indice di staging, quindi gli aggiornamenti all'indice di staging ci hanno accompagnati indietro nel tempo tramite la cronologia dei commit. Questo può essere confermato dall'output di git ls-files -s
, che mostra che lo SHA per reset_lifecycle_file
è rimasto invariato. A titolo di promemoria, git status
non visualizza lo stato dei "tre alberi", ma mostra essenzialmente una differenza tra di essi. In questo caso, mostra il fatto che l'indice di staging è in anticipo rispetto alle modifiche nella cronologia dei commit, come se ne avessimo già effettuato lo staging.
Differenze tra reset e revert
Se git revert è un modo "sicuro" per annullare le modifiche, git reset
può essere considerato come il metodo pericoloso. Con git reset
il rischio di perdere lavoro è reale. git reset
non elimina mai un commit; tuttavia, i commit possono diventare "orfani", il che significa che non esiste un percorso diretto da un riferimento per accedervi. I commit orfani di solito possono essere trovati e ripristinati utilizzando git reflog. Git eliminerà definitivamente tutti i commit orfani dopo aver eseguito il garbage collector interno. Per impostazione predefinita, Git è configurato per eseguire il garbage collector ogni 30 giorni. La cronologia dei commit è uno dei "tre alberi git"; gli altri due, cioè l'indice di staging e la directory di lavoro, non sono permanenti come i commit. Bisogna fare attenzione quando si utilizza questo strumento, poiché è uno dei pochi comandi Git che potrebbero causare perdita di lavoro.
Mentre il revert è progettato per annullare in modo sicuro un commit pubblico, git reset
è progettato per annullare le modifiche locali all'indice di staging e alla directory di lavoro. Poiché hanno obiettivi distinti, i due comandi sono implementati in modo diverso: il reset rimuove completamente un set di modifiche, mentre il revert mantiene il set di modifiche originale e utilizza un nuovo commit per applicare l'annullamento.
Non eseguire il reset della cronologia pubblica
Non dovresti mai utilizzare git reset
quando alcune snapshot successive a
La rimozione di un commit che altri membri del team hanno continuato a sviluppare comporta seri problemi in termini di collaborazione. Quando provano a effettuare la sincronizzazione con il repository, una parte della cronologia del progetto sembrerà improvvisamente scomparsa. La sequenza riportata di seguito mostra cosa succede quando si tenta di eseguire il reset di un commit pubblico. Il branch origin/main
è la versione del repository centrale del branch main
locale.
Non appena aggiungi nuovi commit dopo il reset, Git interpreta la cronologia locale come diversa da origin/main
e il commit di merge necessario per sincronizzare i repository rischia di creare confusione e frustrazione nel team.
Assicurati, quindi, di utilizzare git reset
su un progetto locale che non ha avuto successo, non sulle modifiche pubblicate. Se devi correggere un commit pubblico, il comando git revert
è stato progettato specificamente per questo scopo.
Esempi
git reset <file>
Rimuove il file specificato dall'area di staging, ma lascia invariata la directory di lavoro. In questo modo si annulla lo staging di un file senza sovrascrivere alcuna modifica.
git reset
Esegue il reset dell'area di staging in modo che corrisponda al commit più recente, ma lascia invariata la directory di lavoro. In questo modo si annulla lo staging di tutti i file senza sovrascrivere alcuna modifica e hai la possibilità di ricreare da zero la snahpshot in staging.
git reset --hard
Esegue il reset dell'area di staging e della directory di lavoro in modo che corrispondano al commit più recente. Oltre ad annullare le modifiche, il flag --hard
indica a Git di sovrascrivere anche tutte le modifiche nella directory di lavoro. In altre parole, tutte le modifiche non apportate vengono annullate, quindi prima di utilizzarlo assicurati di voler davvero eliminare i tuoi progetti locali.
git reset
Riporta la punta del branch corrente su commit
, ripristina l'area di staging per garantire la corrispondenza, ma non modifica la directory di lavoro. Tutte le modifiche apportate dopo
risiederanno nella directory di lavoro, che ti consente di eseguire di nuovo il commit della cronologia di progetto utilizzando snapshot più pulite e atomiche.
git reset --hard
Riporta la punta del branch corrente su
e ripristina sia l'area di staging che la directory di lavoro per garantire la corrispondenza. In questo modo vengono cancellate non solo le modifiche non eseguite, ma anche tutte le modifiche successive.
Rimozione dello staging di un file
Il comando git reset
è utilizzato spesso durante la preparazione della snapshot in staging. Il prossimo esempio presuppone che tu abbia due file denominati hello.py
e main.py
che hai già aggiunto al repository.
# Edit both hello.py and main.py
# Stage everything in the current directory
git add .
# Realize that the changes in hello.py and main.py
# should be committed in different snapshots
# Unstage main.py
git reset main.py
# Commit only hello.py
git commit -m "Make some changes to hello.py"
# Commit main.py in a separate snapshot
git add main.py
git commit -m "Edit main.py"
Come puoi vedere, git reset
è utile per mantenere commit altamente mirati perché ti consente di annullare lo staging delle modifiche che non sono correlate al commit successivo.
Rimozione dei commit locali
Il prossimo esempio mostra un caso d'uso più avanzato. Dimostra cosa accade quando lavori a un nuovo progetto da un po' di tempo, ma decidi di eliminarlo completamente dopo aver effettuato il commit di alcune snapshot.
# Create a new file called `foo.py` and add some code to it
# Commit it to the project history
git add foo.py
git commit -m "Start developing a crazy feature"
# Edit `foo.py` again and change some other tracked files, too
# Commit another snapshot
git commit -a -m "Continue my crazy feature"
# Decide to scrap the feature and remove the associated commits
git reset --hard HEAD~2
Il comando git reset HEAD~2
sposta il branch corrente indietro di due commit, rimuovendo di fatto le due snapshot che abbiamo appena creato dalla cronologia del progetto. Ricorda che questo tipo di reset deve essere utilizzato solo su commit non pubblicati. Non eseguire mai questa operazione se hai già effettuato il push dei commit a un repository condiviso.
Riepilogo
Ricapitolando: git reset
è un potente comando che viene utilizzato per annullare le modifiche locali allo stato di un repository Git. git reset
funziona sui "tre alberi di Git", cioè la cronologia dei commit (HEAD
), l'indice di staging e la directory di lavoro. Sono presenti tre opzioni della riga di comando che corrispondono ai tre alberi. Le opzioni --soft, --mixed
e --hard
possono essere passate a git reset
.
In questo articolo abbiamo utilizzato diversi altri comandi Git per dimostrare i processi di reset. Scopri di più su questi comandi nelle singole pagine dedicate a git status, git log, git add, git checkout, git reflog e git revert.
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.