Git stash
git stash
esegue lo shelve temporaneamente (o accantona) le modifiche apportate alla copia di lavoro per consentirti di lavorare su qualcos'altro e di tornare poi indietro e riapplicarle in un secondo momento. L'accantonamento è utile se devi cambiare rapidamente contesto e lavorare su qualcos'altro, ma sei a metà di una modifica del codice e non sei ancora pronto per il commit.
- Git stash
- Accantonamento del lavoro
- Riapplicazione delle modifiche accantonate
- Accantonamento dei file non monitorati o ignorati
- Gestione di più accantonamenti
- Visualizzazione delle differenze tra gli accantonamenti
- Accantonamenti parziali
- Creazione di un branch dall'accantonamento
- Pulizia dell'accantonamento
- Come funziona git stash
Accantonamento del lavoro
Il comando git stash
prende le modifiche non sottoposte a commit (sia preparate che non preparate per il commit), le salva per un uso futuro e poi le ripristina dalla copia di lavoro. Ad esempio:
$ git status
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
$ git stash
Saved working directory and index state WIP on main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage
$ git status
On branch main
nothing to commit, working tree clean
materiale correlato
Branch Git
Scopri la soluzione
Impara a utilizzare Git con Bitbucket Cloud
A questo punto puoi apportare modifiche, creare nuovi commit, passare da un branch all'altro ed eseguire qualsiasi altra operazione Git; quindi, puoi tornare indietro e riapplicare l'accantonamento quando preferisci.
Nota che l'accantonamento si trova in locale nel repository Git; gli accantonamenti non vengono trasferiti sul server quando esegui il push.
Riapplicazione delle modifiche accantonate
Puoi riapplicare le precedenti modifiche accantonate utilizzando git stash pop
:
$ git status
On branch main
nothing to commit, working tree clean
$ git stash pop
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Dropped refs/stash@{0} (32b3aa1d185dfe6d57b3c3cc3b32cbf3e380cc6a)
Il prelievo dell'accantonamento rimuove le modifiche da quest'ultimo e le riapplica alla copia di lavoro.
In alternativa, puoi riapplicare le modifiche alla copia di lavoro e conservarle nell'accantonamento con il comando git stash apply
:
$ git stash apply
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Questa procedura è utile se desideri applicare le stesse modifiche accantonate a più branch.
Ora che conosci le basi dell'accantonamento, occorre fare una precisazione su git stash
: per impostazione predefinita, Git non accantonerà le modifiche apportate ai file non monitorati o ignorati.
Accantonamento dei file non monitorati o ignorati
Per impostazione predefinita, l'esecuzione di git stash
accantonerà:
- modifiche aggiunte all'indice (modifiche preparate per il commit)
- modifiche apportate ai file attualmente monitorati da Git (modifiche non preparate per il commit)
Ma non accantonerà:
- nuovi file nella copia di lavoro che non sono stati ancora preparati per il commit
- file ignorati
Quindi, se aggiungiamo un terzo file al nostro esempio precedente, ma non lo prepariamo per il commit (ad es. non eseguiamo git add
), git stash
non lo accantonerà.
$ script.js
$ git status
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Untracked files:
script.js
$ git stash
Saved working directory and index state WIP on main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage
$ git status
On branch main
Untracked files:
script.js
L'aggiunta dell'opzione -u
(o --include-untracked
) dice a git stash
di accantonare anche i file non monitorati:
$ git status
On branch main
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Untracked files:
script.js
$ git stash -u
Saved working directory and index state WIP on main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage
$ git status
On branch main
nothing to commit, working tree clean
Puoi includere anche le modifiche ai file ignorati inviando l'opzione -a
(o --all
) quando esegui git stash
.
Gestione di più accantonamenti
Non sei limitato a un solo accantonamento. Puoi eseguire git stash
più volte per creare più accantonamenti e quindi usare git stash list
per visualizzarli. Per impostazione predefinita, gli accantonamenti sono identificati semplicemente come "WIP" (lavoro in corso) in cima al branch e al commit da cui hai creato l'accantonamento. Dopo un po', può essere difficile ricordare i contenuti di ciascun accantonamento:
$ git stash list
stash@{0}: WIP on main: 5002d47 our new homepage
stash@{1}: WIP on main: 5002d47 our new homepage
stash@{2}: WIP on main: 5002d47 our new homepage
Per fornire un po' più di contesto, è buona norma aggiungere una descrizione agli accantonamenti, usando git stash save "message"
:
$ git stash save "add style to our site"
Saved working directory and index state On main: add style to our site
HEAD is now at 5002d47 our new homepage
$ git stash list
stash@{0}: On main: add style to our site
stash@{1}: WIP on main: 5002d47 our new homepage
stash@{2}: WIP on main: 5002d47 our new homepage
Per impostazione predefinita, git stash pop
riapplicherà l'accantonamento creato più di recente: stash@ {0}
Puoi scegliere quale accantonamento riapplicare inviando il relativo identificatore come ultimo argomento, ad esempio:
$ git stash pop stash@{2}
Visualizzazione delle differenze tra gli accantonamenti
Puoi visualizzare un riepilogo di un accantonamento con git stash show
:
$ git stash show
index.html | 1 +
style.css | 3 +++
2 files changed, 4 insertions(+)
Oppure, puoi inviare l'opzione -p
(o --patch
) per visualizzare le differenze complete di un accantonamento:
$ git stash show -p
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..d92368b
--- /dev/null
+++ b/style.css
@@ -0,0 +1,3 @@
+* {
+ text-decoration: blink;
+}
diff --git a/index.html b/index.html
index 9daeafb..ebdcbd2 100644
--- a/index.html
+++ b/index.html
@@ -1 +1,2 @@
+<link rel="stylesheet" href="style.css"/>
Accantonamenti parziali
Puoi inoltre scegliere di accantonare un singolo file, una raccolta di file o singole modifiche all'interno dei file. Se invii l'opzione -p
(o --patch
) a git stash
, il comando scorrerà ogni "hunk" modificato nella copia di lavoro e ti chiederà se desideri accantonarlo:
$ git stash -p
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..d92368b
--- /dev/null
+++ b/style.css
@@ -0,0 +1,3 @@
+* {
+ text-decoration: blink;
+}
Stash this hunk [y,n,q,a,d,/,e,?]? y
diff --git a/index.html b/index.html
index 9daeafb..ebdcbd2 100644
--- a/index.html
+++ b/index.html
@@ -1 +1,2 @@
+<link rel="stylesheet" href="style.css"/>
Stash this hunk [y,n,q,a,d,/,e,?]? n
Puoi premere ? per un elenco completo dei comandi di hunk. Quelli più utili sono:
Comando | Descrizione |
---|---|
/ | Descrizione cerca un hunk in base all'espressione regolare |
? | Descrizione assistenza |
n | Descrizione non accantonare questo hunk |
q | Descrizione esci (tutti gli hunk che sono già stati selezionati verranno accantonati) |
s | Descrizione dividi questo hunk in hunk più piccoli |
y | Descrizione accantona questo hunk |
Non esiste un comando "abort" esplicito, ma se premi CTRL-C
(SIGINT) il processo di accantonamento verrà interrotto.
Creazione di un branch dall'accantonamento
Se le modifiche sul branch divergono da quelle nell'accantonamento, potresti incorrere in conflitti quando prelevi o applichi l'accantonamento. In alternativa, puoi usare git stash branch
per creare un nuovo branch a cui applicare le modifiche accantonate:
$ git stash branch add-stylesheet stash@{1}
Switched to a new branch 'add-stylesheet'
On branch add-stylesheet
Changes to be committed:
new file: style.css
Changes not staged for commit:
modified: index.html
Dropped refs/stash@{1} (32b3aa1d185dfe6d57b3c3cc3b32cbf3e380cc6a)
Esegue il checkout di un nuovo branch in base al commit da cui hai creato l'accantonamento, quindi vi inserisce le modifiche accantonate.
Pulizia dell'accantonamento
Se decidi che non ti serve più un determinato accantonamento, puoi eliminarlo con git stash drop
:
$ git stash drop stash@{1}
Dropped stash@{1} (17e2697fd8251df6163117cb3d58c1f62a5e7cdb)
Oppure puoi eliminare tutti gli accantonamenti con:
$ git stash clear
Come funziona git stash
Se vuoi solo sapere come usare git stash
, puoi fermarti qui, senza leggere oltre. Ma se ti incuriosisce conoscere il funzionamento interno di Git (e di git stash
), continua a leggere.
Gli accantonamenti sono in realtà codificati nel repository sotto forma di oggetti di commit. Il riferimento speciale in .git/refs/stash
punta all'accantonamento creato più di recente e gli accantonamenti creati in precedenza sono riportati nel log di riferimento del riferimento di stash
. Questo è il motivo per cui si fa riferimento agli accantonamenti con stash@{n}:
in realtà si fa riferimento all'ennesima voce del log di riferimento relativa al riferimento di stash
. Dal momento che un accantonamento è semplicemente un commit, puoi ispezionarlo con git log
:
A seconda degli elementi che hai accantonato, una singola operazione git stash
crea due o tre nuovi commit. I commit nel diagramma riportato sopra sono:
stash@{0}
, un nuovo commit per archiviare i file monitorati che erano nella copia di lavoro quando hai eseguitogit stash
- Il primo elemento principale di
stash@{0}
, il commit preesistente che si trovava su HEAD quando hai eseguitogit stash
- Il secondo elemento principale di
stash@{0}
, un nuovo commit che rappresentava l'indice quando hai eseguitogit stash
- Il terzo elemento principale di
stash@{0}
, un nuovo commit che rappresenta i file non monitorati che erano nella copia di lavoro quando hai eseguitogit stash
. Questo terzo elemento principale è stato creato solo se:- la copia di lavoro conteneva effettivamente file non monitorati; e
- hai specificato l'opzione
--include-untracked
o--all
quando hai richiamatogit stash
.
In che modo git stash
codifica la struttura di lavoro e l'indice sotto forma di commit:
- Prima dell'accantonamento, la struttura di lavoro può contenere le modifiche ai file monitorati, non monitorati e ignorati. Alcune di queste modifiche possono inoltre essere preparate per il commit nell'indice.
- Richiamando
git stash
, vengono codificate tutte le modifiche ai file monitorati come due nuovi commit nel DAG: uno per le modifiche non preparate per il commit e uno per le modifiche preparate per il commit nell'indice. Il riferimentorefs/stash
speciale viene aggiornato in modo da puntare a queste ultime.
- L'uso dell'opzione
--include-untracked
consente di codificare anche le eventuali modifiche ai file non monitorati come commit aggiuntivo.
- L'uso dell'opzione
--all
include le modifiche a tutti i file ignorati e le modifiche ai file non monitorati nello stesso commit.
Quando esegui git stash pop
, le modifiche provenienti dai commit riportati sopra vengono utilizzate per aggiornare la copia di lavoro e l'indice e il log di riferimento dell'accantonamento viene riordinato in modo da rimuovere il commit prelevato. Nota che i commit prelevati non vengono eliminati immediatamente, ma vengono tenuti da parte per un possibile uso nella futura garbage collection.
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.