git stash : mettre des modifications de côté puis les récupérer
git stash range les modifications non commitées dans un espace à part et ramène le répertoire de travail au dernier commit, pour que vous puissiez passer à une autre tâche. Pour récupérer vos changements, utilisez git stash pop (applique et supprime l'entrée) ou git stash apply (applique et conserve l'entrée) ; il n'existe pas de commande git unstash.
À quoi sert git stash
Situation classique : vous êtes en pleine tâche, des fichiers sont modifiés, il est trop tôt pour commiter — et on vous demande de corriger d'urgence un bug sur une autre branche. Impossible de changer de branche, ou vous craignez de perdre votre travail. git stash met toutes les modifications non commitées « dans une poche » et ramène le répertoire de travail à l'état du dernier commit.
$ git stash
Saved working directory and index state WIP on feature/login: 3f2a1c4 Formulaire de connexion
$ git status
On branch feature/login
nothing to commit, working tree clean
Vous pouvez maintenant changer de branche, corriger le bug, revenir et ressortir ce que vous aviez mis de côté. Chaque sauvegarde est une entrée dans la pile du stash ; en interne, Git la stocke comme un commit spécial, donc les données sont fiables et ne dépendent d'aucune branche.
Comment mettre des modifications de côté : les principales options
Avec une description claire
La description par défaut « WIP on branche » ne vous dira plus rien dans une semaine. Nommez vos entrées :
git stash push -m "validation du formulaire, e-mail pas terminé"
git stash sans argument est un raccourci pour git stash push. L'ancienne forme git stash save "message" fonctionne encore, mais dans vos nouveaux usages préférez push -m.
En incluant les nouveaux fichiers
Par défaut, stash ne prend que les fichiers suivis — modifiés ou ajoutés à l'index. Les nouveaux fichiers qui ne sont jamais passés par git add restent dans le répertoire de travail. C'est une surprise fréquente.
git stash -u # --include-untracked : inclut les fichiers non suivis
git stash -a # --all : inclut aussi les fichiers de .gitignore
Prudence avec -a : node_modules, les builds et les configs locales partiront aussi dans la poche. En général, -u suffit.
Seulement une partie des modifications
git stash push -m "config" src/config.js # uniquement les fichiers indiqués
git stash -p # choisir les fragments en interactif
git stash --staged # uniquement ce qui est dans l'index (Git 2.35+)
git stash --keep-index # tout mettre de côté, mais garder l'index dans le répertoire
--keep-index est utile avant un commit : vous ne gardez dans le répertoire de travail que ce que vous allez commiter, vous lancez les tests et vous vérifiez que le commit se suffit à lui-même.
Comment récupérer les modifications (git unstash)
La commande git unstash n'existe pas dans Git — c'est souvent ce que l'on tape en cherchant à ressortir ce qu'on a mis de côté. Deux commandes servent à cela.
| Commande | Ce qu'elle fait | Entrée dans la pile |
|---|---|---|
git stash pop | Applique les dernières modifications mises de côté | Supprimée si l'application se fait sans conflit |
git stash apply | Applique les dernières modifications mises de côté | Conservée |
git stash pop stash@{2} | Applique une entrée précise | Supprimée |
git stash apply --index | Restaure aussi la séparation entre index et répertoire de travail | Conservée |
$ git stash pop
On branch feature/login
Changes not staged for commit:
modified: src/auth.js
modified: src/form.js
Dropped refs/stash@{0} (8c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d)
Attention : par défaut, même ce qui se trouvait dans l'index au moment du stash revient sous forme de modifications ordinaires. Si vous tenez à retrouver votre index préparé, ajoutez --index.
pop ou apply
Au quotidien, pop est pratique : on ressort et on oublie. Choisissez apply quand vous voulez appliquer les mêmes modifications sur plusieurs branches ou que vous n'êtes pas sûr que tout se passera bien — l'entrée reste comme filet de sécurité, et vous pourrez la supprimer ensuite avec git stash drop.
Gérer la liste des entrées mises de côté
$ git stash list
stash@{0}: On feature/login: validation du formulaire, e-mail pas terminé
stash@{1}: WIP on main: 9b7e0d2 Mettre à jour les dépendances
stash@{2}: On feature/api: expérience avec le cache
La pile fonctionne selon le principe « dernier entré, premier sorti » : stash@{0} est toujours l'entrée la plus récente, et les numéros se décalent après chaque push et chaque drop.
| Commande | Rôle |
|---|---|
git stash show | Statistiques résumées des modifications de la dernière entrée |
git stash show -p stash@{1} | Diff complet d'une entrée précise |
git stash drop stash@{1} | Supprimer une entrée |
git stash clear | Supprimer toutes les entrées d'un coup |
git stash branch nom stash@{0} | Créer une branche à partir du commit sur lequel le stash a été fait, y appliquer l'entrée puis la supprimer |
Pour que git stash show affiche par défaut le diff complet plutôt que les statistiques, ainsi que les fichiers non suivis, il existe les réglages stash.showPatch et stash.showIncludeUntracked.
Scénario pas à pas : un bug urgent au milieu d'une tâche
- Mettez de côté le travail en cours, nouveaux fichiers compris :
git stash push -u -m "login : brouillon". - Passez sur la branche principale et créez une branche de correctif :
git switch main,git pull,git switch -c hotfix/null-email. - Corrigez le bug, commitez, envoyez en revue.
- Revenez à votre tâche :
git switch feature/login. - Ressortez vos modifications :
git stash pop. Vérifiez avecgit status— tout est là.
Aujourd'hui, beaucoup utilisent git worktree pour ce scénario : un second répertoire de travail pour le même dépôt permet de ne rien mettre de côté du tout. Mais pour un changement de contexte de cinq minutes, stash reste plus simple.
Conflits lors de l'application d'un stash
Si, après le stash, les mêmes lignes ont changé dans la branche, l'application se termine par un conflit :
$ git stash pop
Auto-merging src/auth.js
CONFLICT (content): Merge conflict in src/auth.js
The stash entry is kept in case you need it again.
Dans ce cas, l'entrée n'est pas supprimée, même avec pop. Résolvez le conflit dans le fichier comme d'habitude, puis faites git add pour marquer la résolution (ou git restore --staged si vous ne voulez pas laisser les modifications dans l'index), et supprimez l'entrée devenue inutile avec git stash drop.
Si le conflit est compliqué, un contournement est plus pratique : git stash branch tmp-login. Git crée une branche à partir du commit exact sur lequel vous aviez fait le stash — les modifications s'y appliquent sans conflit, et vous les fusionnerez ensuite avec la branche principale par un merge classique.
Comment récupérer un stash supprimé par erreur
Vous avez lancé git stash drop ou clear par erreur ? Tout n'est pas perdu. L'entrée était un commit, et tant que le ramasse-miettes ne l'a pas supprimé, on peut le retrouver parmi les objets « orphelins » (dangling) :
git fsck --no-reflog | grep "dangling commit"
git show 8c1d2e3 # vérifier que c'est bien le bon stash
git stash apply 8c1d2e3
Si vous venez de supprimer l'entrée avec drop ou pop, le hash est affiché directement dans la sortie de la commande — sur la ligne Dropped refs/stash@{0} (...). Il suffit de le passer à git stash apply.
Comment stash fonctionne en interne
Comprendre le mécanisme fait disparaître la peur de perdre des données. Chaque entrée du stash est un commit ordinaire, pointé par la référence refs/stash. Il a deux parents : le commit HEAD sur lequel vous étiez et un commit séparé contenant l'état de l'index. Avec -u, un troisième parent s'ajoute avec les fichiers non suivis. La liste stash@{N} n'est que le journal (reflog) de la référence refs/stash.
Plusieurs conséquences pratiques en découlent. On peut passer un stash à n'importe quelle commande qui accepte un commit : git diff stash@{0}, git show stash@{0}:src/auth.js (le contenu d'un seul fichier de l'entrée) ou git checkout stash@{0} -- src/auth.js pour récupérer un seul fichier sans appliquer toute l'entrée. Et une entrée supprimée reste dans la base d'objets jusqu'à ce que le ramasse-miettes l'efface.
Stash et les autres commandes Git
Certaines commandes savent mettre les modifications de côté toutes seules. git rebase --autostash et git pull --rebase --autostash mettent de côté les changements non commités avant de commencer et les restaurent à la fin. Vous pouvez activer ce comportement en permanence avec les réglages rebase.autoStash true et merge.autoStash true. Si un conflit survient à la restauration, Git conserve l'entrée dans la pile stash habituelle et vous le signale.
Changer de branche avec git switch ne nécessite pas toujours un stash non plus : si vos modifications ne touchent pas les fichiers qui diffèrent entre les branches, Git les emporte simplement avec vous. Le stash est utile quand Git répond « Your local changes would be overwritten by checkout » ou quand vous ne voulez pas emmener vos changements sur l'autre branche.
Erreurs fréquentes
- Les nouveaux fichiers « ne sont pas partis ». Ils ne sont pas suivis, il faut
-u. - Le stash utilisé comme stockage à long terme. Un mois plus tard, la liste contient dix « WIP on main » sans nom, et personne ne sait ce qu'il y a dedans. Pour un travail long, faites un commit sur une branche dédiée — au moins, on peut le pousser.
- Oublier que l'entrée est restée après un conflit et l'appliquer une seconde fois plus tard. Après avoir résolu un conflit, faites toujours
drop. - Le stash n'est pas synchronisé avec le serveur. Il n'existe que dans votre dépôt local,
git pushne l'envoie pas. Si vous supprimez le dossier du projet, le stash disparaît. - Appliquer la mauvaise entrée. Avant
pop, regardezgit stash listetgit stash show -p.
En résumé
git stash est un moyen rapide de libérer le répertoire de travail sans perdre les modifications non commitées : git stash push -u -m "description" pour mettre de côté, git stash pop pour récupérer. Utilisez apply quand vous voulez un filet de sécurité, git stash list et show -p pour ne pas vous y perdre, et ne transformez pas le stash en entrepôt — pour tout ce qui dure, il y a les commits et les branches. Le passage d'une tâche à l'autre avec stash se pratique dans le cours Git.
Questions fréquentes
Peut-on appliquer un stash sur une autre branche ?
Oui, le stash n'est lié à aucune branche : placez-vous sur la branche voulue et lancez git stash pop ou apply. Si les modifications ne s'appliquent pas proprement, vous aurez un conflit ordinaire.
git stash conserve-t-il les modifications de l'index ?
Oui, mais avec un pop ou un apply classique, tout revient sous forme de modifications non indexées. Pour restaurer aussi l'index, utilisez git stash apply --index.
Combien d'entrées peut-on garder dans le stash ?
Il n'y a pas de limite stricte, mais les entrées plus anciennes que la durée de conservation du reflog peuvent être supprimées par le ramasse-miettes. En pratique, ne gardez que quelques entrées récentes.
Comment faire un stash d'un seul fichier ?
Indiquez le chemin après deux tirets ou directement après push : git stash push -m description -- src/config.js. Seul ce fichier part dans le stash, les autres modifications restent dans le répertoire de travail.
Quelle différence entre un stash et un commit temporaire ?
Un commit vit dans une branche, on peut l'envoyer sur le serveur puis le retoucher avec amend ou rebase. Le stash n'existe qu'en local dans une pile à part et sert surtout aux changements de contexte rapides.
Ce sujet est traité en détail avec de la pratique dans le cours « Git de zéro à développeur confirmé ».
Voir le cours