Aller au contenu
Développement medium

Git stash et git clean : mettre de côté et nettoyer

14 min de lecture

git stash met vos modifications de côté dans une pile temporaire, et git clean supprime les fichiers non suivis. Ces deux commandes gardent votre répertoire de travail propre quand vous devez changer de contexte. Ce guide vous apprend à utiliser toutes les options utiles de stash (-u, --patch, --keep-index), à récupérer un stash perdu et à nettoyer sélectivement avec git clean.

Prérequis : Enregistrer des modifications et Les branches en bref.

  • Stasher et récupérer des modifications en cours sans créer de commit
  • Utiliser les options avancées : -u (untracked), --patch, --keep-index
  • Gérer plusieurs stashes et les nommer pour s'y retrouver
  • Nettoyer le répertoire de travail avec git clean pour repartir sur une base propre

Vous travaillez sur une feature quand un bug urgent arrive. Votre working directory est sale, impossible de changer de branche :

Fenêtre de terminal
git stash
# Saved working directory and index state WIP on feature: a1b2c3d ...
git switch main
# ... corriger le bug ...
git switch feature
git stash pop

git stash sauvegarde les fichiers modifiés et l'index (staging area) dans une pile, puis restaure un working directory propre.

La distinction à retenir dans ce bloc est celle entre pop et apply. pop retire l'entrée de la pile après l'avoir appliquée, apply la conserve. Réflexe utile : quand vous n'êtes pas certain que le stash s'appliquera proprement, utilisez apply, vérifiez le résultat, puis supprimez l'entrée avec drop. Attention aussi à la numérotation : stash@{0} désigne toujours le plus récent, donc les numéros se décalent après chaque pop ou drop.

Fenêtre de terminal
# Sauvegarder (avec un message descriptif)
git stash push -m "wip: calcul de remise"
# Lister les stash
git stash list
# stash@{0}: On feature: wip: calcul de remise
# stash@{1}: WIP on main: fix header
# Appliquer le dernier stash ET le supprimer de la pile
git stash pop
# Appliquer SANS supprimer (utile pour appliquer sur plusieurs branches)
git stash apply
# Appliquer un stash spécifique
git stash apply stash@{1}
# Supprimer un stash
git stash drop stash@{0}
# Vider toute la pile
git stash clear

Deux options de ce tableau modifient ce qui entre dans le stash (-u, -a, et la forme -- fichier), les autres modifient ce qui reste dans votre répertoire de travail après l'opération. Ne les confondez pas : --keep-index n'allège pas le stash, il change seulement l'état du disque après coup. C'est le piège le plus fréquent de cette commande.

OptionEffet
-m "message"Ajoute un message descriptif
--keep-indexStashe tout, mais laisse les modifications déjà stagées en place dans l'index et sur le disque
--include-untracked / -uInclut aussi les fichiers non suivis (nouveaux fichiers)
--all / -aInclut tout, même les fichiers ignorés par .gitignore
--patch / -pSélection interactive (hunk par hunk)
-- fichier1 fichier2Stashe uniquement les fichiers spécifiés

Exemples :

Fenêtre de terminal
# Stasher uniquement les modifications non stagées
git stash push --keep-index -m "non stagé uniquement"
# Stasher aussi les nouveaux fichiers
git stash push -u -m "avec les nouveaux fichiers"
# Stasher un seul fichier
git stash push -m "config only" -- src/config.py

Si vos modifications de stash causent des conflits au pop :

Fenêtre de terminal
git stash branch nouvelle-branche stash@{0}

Git crée la branche depuis le commit où le stash a été fait, applique le stash, et le supprime de la pile. Pas de conflit possible.

Inspecter avant d'appliquer évite la plupart des pop malheureux, en particulier quand la pile contient plusieurs entrées créées à des jours d'intervalle. Sans argument, git stash show porte sur stash@{0}. Un point qui surprend souvent : la sortie par défaut n'inclut pas les fichiers non suivis, même s'ils ont été stashés avec -u. Ajoutez -u à show pour les voir.

Fenêtre de terminal
# Résumé des fichiers modifiés
git stash show
# Diff complet
git stash show -p
# Diff d'un stash spécifique
git stash show -p stash@{2}

git clean supprime les fichiers et dossiers qui ne sont pas versionnés par Git. C'est l'outil de nettoyage du working directory.

Le dry-run doit porter exactement les mêmes options que la commande réelle, sinon il ne prouve rien. C'est particulièrement vrai pour -d : sans lui, git clean ignore les répertoires non suivis, et vous obtenez une liste rassurante qui ne reflète pas ce que fera git clean -fd. Comparez les deux sorties ci-dessous, le répertoire temp/ n'apparaît que dans la seconde.

Fenêtre de terminal
# Sans -d : les répertoires non suivis sont ignorés
git clean -n
# Would remove build.log
# Would remove debug.out
# Avec -d : le répertoire temp/ apparaît enfin
git clean -nd
# Would remove build.log
# Would remove debug.out
# Would remove temp/
# Supprimer pour de vrai (nécessite -f)
git clean -fd

Les deux options qui décident réellement du périmètre de suppression sont -x et -X, et une majuscule les sépare. Le -x minuscule ajoute les fichiers ignorés à la liste, donc supprime tout ce qui n'est pas versionné. Le -X majuscule restreint aux seuls fichiers ignorés, ce qui préserve les nouveaux fichiers que vous n'avez pas encore ajoutés au dépôt. Sur un poste de travail, -X est presque toujours le bon choix, -x étant réservé au cas où vous voulez réellement un dépôt identique à un git clone frais.

OptionEffet
-fForce, obligatoire pour supprimer
-nDry-run, affiche sans supprimer
-dSupprime aussi les dossiers non suivis
-xSupprime aussi les fichiers ignorés (.gitignore)
-XSupprime uniquement les fichiers ignorés
-iMode interactif
-e <motif>Exclut un motif de la suppression

Exemples courants :

Fenêtre de terminal
# Supprimer fichiers + dossiers non suivis
git clean -fd
# Tout supprimer (y compris les ignorés) : reset complet
git clean -fdx
# Supprimer uniquement les artefacts de build (fichiers ignorés)
git clean -fdX
# Mode interactif (le plus sûr)
git clean -i

Le mode interactif est la seule variante de git clean qui ne demande pas -f : elle vous fait valider avant chaque suppression, ce qui remplace la protection du flag de forçage. C'est le mode à privilégier quand la liste du dry-run contient un fichier dont vous n'êtes pas sûr. Comme pour le dry-run, pensez à ajouter -d si vous voulez que les répertoires non suivis apparaissent dans la liste proposée.

Fenêtre de terminal
git clean -i -d
Would remove the following items:
build.log debug.out temp/
*** Commands ***
1: clean 2: filter by pattern 3: select by numbers
4: ask each 5: quit 6: help
What now>

Choisissez 4 (ask each) pour valider fichier par fichier, ou 5 (quit) pour sortir sans rien supprimer.

Si vous avez accidentellement lancé git stash clear ou git stash drop sur un stash important, il est souvent encore récupérable grâce aux objets Git orphelins.

Fenêtre de terminal
# Lister les objets stash non référencés dans l'historique
git fsck --unreachable | grep commit | awk '{print $3}' | while read sha; do
git log -1 --oneline --no-walk "$sha"
done

Cela affiche les commits orphelins récents. Un stash est techniquement un commit, et son message vous permet de le repérer : WIP on <branche> quand il a été créé sans message, On <branche> : <votre message> sinon. La commande liste aussi des commits index on <branche> : ce sont les objets internes que Git crée pour mémoriser l'état de l'index, ignorez-les et ciblez les entrées WIP on ou On.

Pour inspecter et restaurer :

Fenêtre de terminal
# Voir le contenu d'un commit orphelin
git show <sha>
# Appliquer les modifications
git stash apply <sha>

Pour un working directory parfaitement propre :

Fenêtre de terminal
# D'abord, sauvegarder les modifications suivies
git stash push -u -m "backup avant nettoyage"
# Ensuite, supprimer les artefacts ignorés
git clean -fdX
# Après l'opération, récupérer le travail
git stash pop

Les deux premières lignes de ce tableau décrivent la même situation vue sous deux angles : un pop qui rencontre un conflit applique quand même ce qu'il peut, mais conserve l'entrée dans la pile. C'est voulu, Git préfère laisser une copie de secours plutôt que la détruire pendant que vous résolvez le conflit. Une fois le conflit réglé, à vous de faire le drop manuellement, sinon vous accumulerez des entrées fantômes que vous rappliquerez par erreur plus tard.

SymptômeCause probableSolution
CONFLICT au stash popLe code a évolué depuis le stashgit stash branch nom pour appliquer sur le bon contexte
stash pop ne supprime pas le stashConflit lors de l'applicationRésolvez les conflits puis git stash drop manuellement
clean ne supprime rienOubli de -fAjoutez -f (obligatoire)
clean supprime trop-x inclut les ignorésUtilisez -X pour uniquement les ignorés, ou -e pour exclure
Fichier non stashéFichier non suivi (nouveau)Ajoutez -u : git stash push -u
  • git stash sauvegarde les modifications dans une pile, parfait pour changer de contexte
  • -u pour inclure les fichiers non suivis, --keep-index pour garder le staging
  • git stash pop applique et supprime, apply applique sans supprimer
  • git clean -n toujours en premier (dry-run), puis -f pour exécuter
  • git clean -fdX : nettoyage des artefacts de build (fichiers ignorés uniquement)

Six questions qui reviennent en permanence sur git stash, dont la première porte sur une commande qui n'existe pas : il n'y a pas de git unstash, la récupération passe par pop ou apply. Les autres réponses reprennent en format court les points du guide sur le nommage, la suppression et le stash partiel.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn