Close

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.

Logo Git
materiale correlato

Scheda di riferimento rapido di Git

Logo di Bitbucket
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.

4 nodi di cui l'ultimo è main

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

4 nodi di cui main punta all'ultimo nodo e HEAD punta al secondo nodo

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

2 set da 2 nodi, di cui main e HEAD puntano al secondo nodo del primo set

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.

diagramma dell'ambito di git reset

'--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 sono state sottoposte a push in un repository pubblico. Dopo aver pubblicato un commit, devi presumere che altri sviluppatori vi facciano affidamento.

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.

Diagramma di ciò che accade dopo il ripristino: si ottengono due rami principali

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.

Le persone collaborano utilizzando una parete piena di strumenti

Blog di Bitbucket

Illustrazione su Devops

Percorso di apprendimento DevOps

Funzione Demo Den per demo con esperti Atlassian

Come Bitbucket Cloud funziona con Atlassian Open DevOps

Iscriviti alla nostra newsletter DevOps

Thank you for signing up