Aller au contenu
Développement medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Git reset démystifié : les 3 arbres

8 min de lecture

git reset déplace HEAD et peut mettre à jour l’index et le working directory selon le mode choisi : --soft (HEAD seul), --mixed (HEAD + index, par défaut) ou --hard (les trois). Ce guide vous apprend à choisir le bon mode selon votre situation, à comprendre les 3 arbres internes de Git, et à éviter toute perte de données lors d’un reset.

Prérequis : Enregistrer des modifications et Sélection de révisions.

  • Comprendre les 3 arbres de Git : HEAD, index et répertoire de travail
  • Maîtriser --soft, --mixed et --hard et leurs effets respectifs
  • Distinguer reset, checkout, restore et switch : quand utiliser quoi
  • Annuler des modifications à différents stades du workflow

Git manipule en permanence trois « arbres » (structures de données) :

ArbreRôleCommande pour le voir
HEADDernier commit (snapshot du repo)git log --oneline -1
Index (staging area)Prochain commit en préparationgit diff --cached
Working DirectoryFichiers sur le disquegit diff

Le workflow normal fait circuler les modifications de droite à gauche :

Working Dir → Index → HEAD
git add git commit

git reset fait l’inverse : il déplace HEAD et peut propager le changement vers l’index et/ou le working directory.

Fenêtre de terminal
git reset --soft HEAD~1
  • HEAD recule d’un commit
  • Index inchangé → les modifications restent stagées
  • Working directory inchangé

Usage : « annuler le dernier commit mais garder les modifications prêtes à être recommitées ».

Fenêtre de terminal
# Regrouper les 3 derniers commits en un seul
git reset --soft HEAD~3
git commit -m "feat: fonctionnalité complète"
Fenêtre de terminal
git reset HEAD~1 # --mixed est le défaut
git reset --mixed HEAD~1 # Identique
  • HEAD recule d’un commit
  • Index mis à jour → les modifications passent en non stagées
  • Working directory inchangé

Usage : « annuler le commit et le staging, mais garder les fichiers modifiés ».

Fenêtre de terminal
# Désélectionner un fichier (sans toucher au working dir)
git reset HEAD fichier.py
# Équivalent moderne :
git restore --staged fichier.py
Fenêtre de terminal
git reset --hard HEAD~1
  • HEAD recule d’un commit
  • Index vidé
  • Working directory écrasé → modifications perdues

Usage : « tout annuler, revenir à l’état exact d’un commit ».

Fenêtre de terminal
# Revenir exactement à l'état de origin/main
git reset --hard origin/main
ModeHEADIndexWorking DirDonnées perdues ?
--softDéplacéInchangéInchangéNon
--mixedDéplacéMis à jourInchangéNon
--hardDéplacéMis à jourMis à jourOui (non commitées)

Quand vous spécifiez un chemin, reset ne déplace pas HEAD. Il met à jour uniquement l’index pour ce fichier :

Fenêtre de terminal
# Désélectionner un fichier (retirer du staging)
git reset HEAD fichier.py
# Identique à :
git restore --staged fichier.py

Avec une révision :

Fenêtre de terminal
# Remettre fichier.py dans l'index à la version de HEAD~3
git reset HEAD~3 -- fichier.py

Le working directory n’est pas modifié — seul l’index est mis à jour.

Les commandes modernes simplifient le paysage :

ActionAncienne syntaxeNouvelle syntaxe
Changer de branchegit checkout branchegit switch branche
Désélectionner un fichiergit reset HEAD fichiergit restore --staged fichier
Annuler les modifications d’un fichiergit checkout -- fichiergit restore fichier
Revenir à un commit (détached HEAD)git checkout a1b2c3dgit switch --detach a1b2c3d

git reset reste nécessaire pour déplacer HEAD d’une branche (soft/mixed/hard). Les autres cas ont des commandes dédiées plus claires.

Critèregit resetgit revert
MécanismeSupprime les commitsCrée un commit d’annulation
HistoriqueRéécrit (SHA changent)Préserve (ajout d’un commit)
Commits partagésNon — casse l’historique des autresOui — sûr pour les branches partagées
GranularitéRevient à un pointAnnule un commit spécifique

Règle simple : reset pour les commits locaux non poussés, revert pour les commits partagés.

Annuler le dernier commit (garder les modifications)

Section intitulée « Annuler le dernier commit (garder les modifications) »
Fenêtre de terminal
git reset --soft HEAD~1
# Les modifications sont dans le staging, prêtes à être modifiées
Fenêtre de terminal
git reset
# Toutes les modifications passent de stagé à non stagé
Fenêtre de terminal
git reset --hard origin/main
# Working directory identique à origin/main
Fenêtre de terminal
git reset --mixed HEAD~1
# Les modifications sont dans le working dir
git add partie-1.py
git commit -m "feat: partie 1"
git add partie-2.py
git commit -m "feat: partie 2"
Fenêtre de terminal
# Le reflog conserve la position précédente
git reflog
# a1b2c3d HEAD@{1}: reset: moving to origin/main
# e4f5a6b HEAD@{2}: commit: ma feature importante
git reset --hard HEAD@{2}
# Restauré !
SymptômeCause probableSolution
Fichiers perdus après --hardReset destructifgit reflog + git reset --hard HEAD@{n}
reset n’a pas désélectionnéOmission du chemingit reset HEAD fichier.py (avec le chemin)
Collaborateurs cassés après resetCommits partagés réécritsUtilisez revert pour les commits partagés
Index ne correspond pas au working dir--mixed appliquéNormal : --mixed vide l’index, pas le working dir
  • Git a 3 arbres : HEAD, Index (staging), Working Directory
  • --soft : déplace HEAD → modifications restent stagées
  • --mixed (défaut) : déplace HEAD + vide l’index → modifications non stagées
  • --hard : tout réinitialise → destructif pour les fichiers non commitées
  • reset sur un fichier = mettre à jour l’index (pas HEAD)
  • reset pour commits locaux, revert pour commits partagés
  • Le reflog sauve toujours — même après un --hard accidentel

Ce site vous est utile ?

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

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn