La reserva de canvis (stash) és un magatzem de Git que permet guardar temporalment
els canvis que encara no es volen confirmar (commit).
Aquesta funció és útil quan cal fer alguna acció de Git que, d'altra manera,
faria perdre els canvis del Directori de treball. Per exemple:
Canviar de branca: si la branca de destí modifica els mateixos fitxers.
Incorporar canvis d'una altra branca: amb merge, rebase o pull.
La reserva de canvis permet guardar aquests canvis temporalment i recuperar-los
més avant, quan siga necessari.
Preparació del repositori
S'inicialitza un repositori amb canvis en el fitxer README.md i una branca addicional,
altres_canvis, on s'han fet canvis en el mateix fitxer.
setup_stash.sh
#!/bin/bash# Elimina el repositori si existeixif[-d~/git_stash];thenrm-rf~/git_stash
fimkdir-p~/git_stash
cd~/git_stash
gitinit
gitbranch-mmain
echo"# Reserva de canvis">README.md
gitaddREADME.md
gitcommit-m"Commit inicial"gitcheckout-baltres_canvis
echo"Altres canvis">>README.md
gitcommit-a-m"Altres canvis"gitcheckoutmain
gitlga
jpuigcerver@fp:~$mkdir-p~/git_stash
jpuigcerver@fp:~$cd~/git_stash
jpuigcerver@fp:~/git_stash$gitinit
Initialized empty Git repository in ~/git_stash/.git/jpuigcerver@fp:~/git_stash(main)$gitbranch-mmain
jpuigcerver@fp:~/git_stash(main)$echo"# Reserva de canvis">README.md
jpuigcerver@fp:~/git_stash(main)$gitaddREADME.md
jpuigcerver@fp:~/git_stash(main)$gitcommit-m"Commit inicial"[main (root-commit) 5cc4104] Commit inicial 1 file changed, 1 insertion(+) create mode 100644 README.mdjpuigcerver@fp:~/git_stash(main)$gitcheckout-baltres_canvis
Switched to a new branch 'altres_canvis'jpuigcerver@fp:~/git_stash(altres_canvis)$echo"Altres canvis">>README.md
jpuigcerver@fp:~/git_stash(altres_canvis)$gitcommit-a-m"Altres canvis"[altres_canvis 602f4b0] Altres canvis 1 file changed, 1 insertion(+)jpuigcerver@fp:~/git_stash(altres_canvis)$gitcheckoutmain
Switched to branch 'main'jpuigcerver@fp:~/git_stash(main)$gitlga
*602f4b0-(0 seconds ago)Altres canvis-Joan Puigcerver(altres_canvis)*5cc4104-(0 seconds ago)Commit inicial-Joan Puigcerver(HEAD -> main)
Crea el nou repositori en una carpeta independent per evitar problemes amb els exemples i exercicis anteriors.
Per què és útil git stash?
Suposa que treballes en la branca principal main i has fet canvis en el fitxer README.md.
Aquests canvis es troben en el Directori de treball i encara no s'han confirmat (commit).
En aquest moment, decideixes canviar a una altra branca. Si aquesta operació modifica
la mateixa part dels fitxers on has fet canvis, Git ho impedeix perquè no els perdes.
jpuigcerver@fp:~/git_stash(main)$echo"Canvi A">>README.md
jpuigcerver@fp:~/git_stash(main)$gitstatus
On branch mainChanges not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory)modified: README.mdno changes added to commit (use "git add" and/or "git commit -a")jpuigcerver@fp:~/git_stash(main)$gitcheckoutaltres_canvis
error: Your local changes to the following files would be overwritten by checkout: README.mdPlease commit your changes or stash them before you switch branches.Aborting
El missatge d'error recomana dues opcions:
Confirmar els canvis (commit): permet canviar de branca sense problemes,
però potser encara no vols confirmar-los.
Guardar els canvis de manera temporal amb l'ordre git stash.
Els canvis s'emmagatzemen temporalment en una pila, de manera que:
Els canvis nous es guarden en la primera posició de la pila, amb l'índex 0: stash@{0}.
Així, els canvis més recents es troben en la part superior de la pila i són més fàcils d'accedir,
ja que la majoria d'ordres stash treballen per defecte amb stash@{0}.
Figura 1. Reserva de canvis amb una única entrada.
L'índex dels canvis que ja hi havia en la pila s'incrementa en 1.
Figura 2. Reserva de canvis amb entrades existents.
Exemple: Crear una reserva de canvis
Es guarden els canvis amb git stash i es canvia de branca.
jpuigcerver@fp:~/git_stash(main)$gitstatus
On branch mainChanges not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory)modified: README.mdno changes added to commit (use "git add" and/or "git commit -a")jpuigcerver@fp:~/git_stash(main)$gitdiff
diff --git a/README.md b/README.mdindex d6704e3..e23e265 100644--- a/README.md+++ b/README.md@@ -1 +1,2 @@# Reserva de canvis
+Canvi Ajpuigcerver@fp:~/git_stash(main)$gitstash-m"Canvi A"Saved working directory and index state On main: Canvi Ajpuigcerver@fp:~/git_stash(main)$gitstatus
On branch mainnothing to commit, working tree cleanjpuigcerver@fp:~/git_stash(main)$gitcheckoutaltres_canvis
Switched to branch 'altres_canvis'jpuigcerver@fp:~/git_stash(altres_canvis)$gitcheckoutmain
Switched to branch 'main'
S'observa que els canvis ja no es troben en el Directori de treball
i que ara es pot canviar de branca sense problemes.
Exemple: Crear diverses reserves de canvis
Es creen dues reserves més, amb els canvis B i C.
Canvi B:
jpuigcerver@fp:~/git_stash(main)$echo"Canvi B">>README.md
jpuigcerver@fp:~/git_stash(main)$gitstash-m"Canvi B"Saved working directory and index state On main: Canvi Bjpuigcerver@fp:~/git_stash(main)$gitstatus
On branch mainnothing to commit, working tree cleanjpuigcerver@fp:~/git_stash(main)$gitstashlist
stash@{0}: On main: Canvi Bstash@{1}: On main: Canvi A
Canvi C:
jpuigcerver@fp:~/git_stash(main)$echo"Canvi C">>README.md
jpuigcerver@fp:~/git_stash(main)$gitstash-m"Canvi C"Saved working directory and index state On main: Canvi Cjpuigcerver@fp:~/git_stash(main)$gitstatus
On branch mainnothing to commit, working tree cleanjpuigcerver@fp:~/git_stash(main)$gitstashlist
stash@{0}: On main: Canvi Cstash@{1}: On main: Canvi Bstash@{2}: On main: Canvi A
S'observa que l'índex dels canvis anteriors s'incrementa amb cada reserva nova.
Els canvis reservats es poden recuperar amb l'acció apply, que els aplica en el Directori de treball:
gitstashapply[<index>]
[<index>]: (opcional) índex de la reserva que es vol aplicar. Per defecte, stash@{0}.
Figura 3. Recuperar canvis amb stash apply.
Exemple: Recuperar els canvis amb apply
S'apliquen els canvis de la reserva més recent.
jpuigcerver@fp:~/git_stash(main)$gitstatus
On branch mainnothing to commit, working tree cleanjpuigcerver@fp:~/git_stash(main)$gitstashapply
On branch mainChanges not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory)modified: README.mdno changes added to commit (use "git add" and/or "git commit -a")jpuigcerver@fp:~/git_stash(main)$gitstatus
On branch mainChanges not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory)modified: README.mdno changes added to commit (use "git add" and/or "git commit -a")jpuigcerver@fp:~/git_stash(main)$gitdiff
diff --git a/README.md b/README.mdindex d6704e3..208685c 100644--- a/README.md+++ b/README.md@@ -1 +1,2 @@# Reserva de canvis
+Canvi Cjpuigcerver@fp:~/git_stash(main)$gitstashlist
stash@{0}: On main: Canvi Cstash@{1}: On main: Canvi Bstash@{2}: On main: Canvi A
L'acció apply manté la reserva en la pila. Si, a més, es vol esborrar la reserva després
d'aplicar-la, s'utilitza l'acció pop:
gitstashpop[<index>]
[<index>]: (opcional) índex de la reserva que es vol aplicar i esborrar. Per defecte, stash@{0}.
Figura 4. Recuperar canvis i esborrar la reserva amb stash pop.
Exemple: Recuperar els canvis amb pop
S'apliquen els canvis de la reserva més recent i s'esborra la reserva.
jpuigcerver@fp:~/git_stash(main)$gitrestoreREADME.md# (1)!jpuigcerver@fp:~/git_stash(main)$gitstatus
On branch mainnothing to commit, working tree cleanjpuigcerver@fp:~/git_stash(main)$gitstashpop
On branch mainChanges not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: README.mdno changes added to commit (use "git add" and/or "git commit -a")Dropped refs/stash@{0} (5421da4ebcbd229b003f105eeefea1b6cfa13f3e)jpuigcerver@fp:~/git_stash(main)$gitstatus
On branch mainChanges not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory)modified: README.mdno changes added to commit (use "git add" and/or "git commit -a")jpuigcerver@fp:~/git_stash(main)$gitdiff
diff --git a/README.md b/README.mdindex d6704e3..208685c 100644--- a/README.md+++ b/README.md@@ -1 +1,2 @@# Reserva de canvis
+Canvi Cjpuigcerver@fp:~/git_stash(main)$gitstashlist
stash@{0}: On main: Canvi Bstash@{1}: On main: Canvi A
Es descarten els canvis del Directori de treball de l'exemple anterior.
Una reserva es pot eliminar de la pila amb l'acció drop:
gitstashdrop[<index>]
[<index>]: (opcional) índex de la reserva que es vol descartar. Per defecte, stash@{0}.
Exemple: Descartar els canvis
Es descarta la reserva més recent.
jpuigcerver@fp:~/git_stash(main)$gitstashlist
stash@{0}: On main: Canvi Bstash@{1}: On main: Canvi Ajpuigcerver@fp:~/git_stash(main)$gitstashdrop
Dropped refs/stash@{0} (a1be7febfb9e812173942ae63be37375e8d27d13)jpuigcerver@fp:~/git_stash(main)$gitstashlist
stash@{0}: On main: Canvi A
S'observa que la reserva descartada desapareix de la llista i que l'índex de la resta es redueix en 1.
📌 Aquest document pot quedar desactualitzat després d’imprimir-lo. Pots consultar la versió més recent
a la pàgina web.
🌿 Abans d’imprimir aquest document, considera si és realment necessari. Redueix el consum de paper i ajuda a protegir el nostre entorn.