Git Stash
git stash
stocke (ou stashe) temporairement les changements apportés à votre copie de travail pour que vous puissiez effectuer d'autres tâches, puis revenir et les réappliquer par la suite. Le stashing est pratique si vous avez besoin de changer rapidement de contexte et de travailler sur autre chose, mais que vous êtes en plein dans un changement de code et que n'êtes pas tout à fait prêt à commiter.
- Git Stash
Faire un stash de votre travail
La commande git stash
prend vos changements non commités (stagés et non stagés), les enregistre pour une utilisation ultérieure, puis les replace dans votre copie de travail. Par exemple :
$ 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
Ressource connexe
branche git
DÉCOUVRIR LA SOLUTION
Découvrir Git avec Bitbucket Cloud
À ce stade, vous pouvez procéder à des changements, créer de nouveaux commits, basculer entre des branches et effectuer toute autre opération Git, puis revenir et réappliquer votre stash lorsque vous êtes prêt.
Notez que le stash est local pour votre dépôt Git. Les stashes ne sont pas transférés au serveur lors d'un push.
Appliquer à nouveau vos changements stashés
Vous pouvez réappliquer les changements stashés au préalable avec 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)
L'apparition de votre stash supprime les changements qu'il contient et les réapplique à votre copie de travail.
Vous pouvez également réappliquer les changements à votre copie de travail et les conserver dans votre stash avec 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
C'est utile si vous souhaitez appliquer les mêmes changements stashés à plusieurs branches.
Maintenant que vous connaissez les bases de la mise en stash, vous devez être attentif à un point avec git stash
: par défaut, Git ne fera pas de stash des changements apportés aux fichiers non suivis ou ignorés.
Faire un stash des fichiers non trackés ou ignorés
Par défaut, l'exécution de git stash
fera un stash :
- des changements qui ont été ajoutés à votre index (changements stagés)
- des changements apportés aux fichiers actuellement trackés par Git (changements non stagés)
Mais elle ne fera pas un stash :
- des nouveaux fichiers dans votre copie de travail qui n'ont pas encore été stagés ;
- des fichiers qui ont été ignorés.
Par conséquent, si nous ajoutons un troisième fichier à notre exemple ci-dessus, mais que nous ne le stageons pas (autrement dit, nous n'exécutons pas git add
), git stash
n'en fera pas un stash.
$ 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
Ajouter l'option -u
(ou --include-untracked
) dit à git stash
de stasher également vos fichiers non trackés :
$ 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
Vous pouvez inclure des changements aux fichiers ignorés aussi bien en transmettant l'option -a
(ou --all
) lors de l'exécution de git stash
.
Gérer plusieurs stashes
Vous n'êtes pas limité à un stash unique. Vous pouvez exécuter git stash
à plusieurs reprises pour créer différents stashes, puis utiliser git stash list
pour les consulter. Par défaut, les stashes sont simplement identifiés comme « WIP » (Work in progress, travail en cours) en haut de la branche et du commit à partir duquel vous avez créé le stash. Après un certain temps, il peut être difficile de se souvenir de ce que contient chaque stash :
$ 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
Pour donner plus de contexte, il peut être judicieux d'annoter vos stashes avec une description avec 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
Par défaut, git stash pop
réappliquera le stash créé le plus récemment : stash@{0}
Vous pouvez choisir le stash à réappliquer en transmettant son identifiant comme le dernier argument, par exemple :
$ git stash pop stash@{2}
Affichage des comparaisons entre stashes
Vous pouvez afficher un résumé d'un stash avec git stash show
:
$ git stash show
index.html | 1 +
style.css | 3 +++
2 files changed, 4 insertions(+)
Ou transmettez l'option -p
(ou --patch
) pour afficher la comparaison complète d'un stash :
$ 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"/>
Stashes partiels
Vous pouvez également choisir de ne stasher qu'un fichier, qu'une collection de fichiers ou que des changements individuels depuis les fichiers. Si vous transmettez l'option -p
(ou --patch
) à git stash
, elle itérera chaque « bloc » changé dans votre copie de travail et vous demandera si vous souhaitez le stasher :
$ 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
Appuyez sur ? pour obtenir une liste complète des commandes de bloc. Les plus fréquemment utilisées sont :
Commande | Description |
---|---|
/ | Description recherche d'un bloc via regex |
? | Description Aide |
n | Description Ne pas faire un stash de ce bloc |
q | Description quit (les blocs déjà sélectionnés seront stashés) |
s | Description Divise ce bloc en plus petits |
y | Description Faire un stash de ce bloc |
Il n'existe aucune commande « d'annulation », mais appuyer sur CTRL-C
(SIGINT) annulera le processus de stash.
Créer une branche depuis votre stash
Si les changements sur votre branche divergent des changements dans votre stash, vous risquez de rencontrer des conflits lors de l'apparition ou de l'application de votre stash. À la place, vous pouvez utiliser git stash branch
pour créer une nouvelle branche à laquelle appliquer vos changements stashés :
$ 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)
Une nouvelle branche basée sur le commit à partir duquel vous avez créé votre stash fera l'objet d'un checkout, et vos changements stashés y figureront.
Nettoyez votre stash
Si vous décidez que vous n'avez plus besoin d'un stash spécifique, vous pouvez le supprimer git stash drop
:
$ git stash drop stash@{1}
Dropped stash@{1} (17e2697fd8251df6163117cb3d58c1f62a5e7cdb)
Vous pouvez également supprimer tous les stashes avec :
$ git stash clear
Fonctionnement du stash Git
Si vous désiriez simplement savoir comment utiliser git stash
, vous pouvez vous arrêter de lire. Mais si vous souhaitez comprendre les rouages de Git (et de git stash
), poursuivez votre lecture !
Les stashes sont en fait encodés dans votre dépôt en tant qu'objets de commit. La référence spéciale à .git/refs/stash
pointe vers votre stash le plus récent, et les stashes créés au préalable sont référencés par le reflog de la référence stash
. C'est pour cela que vous renvoyez vers les stashes via stash@{n}:
, vous renvoyez en fait à l'entrée n du reflog pour la référence stash
. Étant donné qu'un stash n'est qu'un commit, vous pouvez l'inspecter avec git log
:
En fonction de l'élément stashé, une opération git stash
unique crée deux ou trois nouveaux commits. Les commits dans le diagramme ci-dessus représentent :
stash@{0}
, un nouveau commit pour stocker les fichiers trackés qui se trouvaient sur votre copie de travail lors de l'exécution degit stash
;- le premier parent de
stash@{0}
, le commit préexistant qui se trouvait au niveau de HEAD lorsque vous avez exécutégit stash
; - le deuxième parent de
stash@{0}
, un nouveau commit représentant l'index lorsque vous exécutezgit stash
- Le troisième parent de
stash@{0}
, un nouveau commit représentant les fichiers non trackés qui se trouvaient sur votre copie de travail lors de l'exécution degit stash
. Ce troisième parent est uniquement créé si :- votre copie de travail contient réellement des fichiers non trackés ; et si
- vous avez spécifié l'option
--include-untracked
ou l'option--all
lorsque vous avez appelégit stash
.
Voici comment git stash
encode votre arborescence de travail et votre index sous forme de commits :
- Avant de faire un stash, l'arborescence de travail peut contenir des changements apportés aux fichiers trackés, non trackés et ignorés. Certains de ces changements peuvent également être stagés dans l'index.
- Appeler
git stash
encode tous les changements apportés aux fichiers trackés sous forme de deux nouveaux commits dans votre graphe orienté acyclique (DAG) : un pour les changements non stagés et un pour les changements stagés dans l'index. La réfrefs/stash
spéciale est mise à jour pour pointer vers eux.
- L'utilisation de l'option
--include-untracked
encode également tout changement apporté aux fichiers non trackés sous forme de commit supplémentaire.
- Utiliser l'option
--all
inclut les changements apportés à tous les fichiers ignorés avec les changements apportés aux fichiers non trackés dans le même commit.
Lorsque vous exécutez git stash pop
, les changements des commits ci-dessus sont utilisés pour mettre à jour votre copie de travail et votre index, et le reflog du stash est remanié de sorte à enlever le commit apparu. Notez que les commits apparus ne sont pas immédiatement supprimés, mais deviennent candidats pour une prochaine « garbage collection ».
Partager cet article
Thème suivant
Lectures recommandées
Ajoutez ces ressources à vos favoris pour en savoir plus sur les types d'équipes DevOps, ou pour les mises à jour continues de DevOps chez Atlassian.