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.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre les 3 arbres de Git : HEAD, index et répertoire de travail
- Maîtriser
--soft,--mixedet--hardet leurs effets respectifs - Distinguer
reset,checkout,restoreetswitch: quand utiliser quoi - Annuler des modifications à différents stades du workflow
Les 3 arbres de Git
Section intitulée « Les 3 arbres de Git »Git manipule en permanence trois « arbres » (structures de données) :
| Arbre | Rôle | Commande pour le voir |
|---|---|---|
| HEAD | Dernier commit (snapshot du repo) | git log --oneline -1 |
| Index (staging area) | Prochain commit en préparation | git diff --cached |
| Working Directory | Fichiers sur le disque | git diff |
Le workflow normal fait circuler les modifications de droite à gauche :
Working Dir → Index → HEAD git add git commitgit reset fait l’inverse : il déplace HEAD et peut propager le
changement vers l’index et/ou le working directory.
Les 3 modes de git reset
Section intitulée « Les 3 modes de git reset »--soft : déplacer HEAD uniquement
Section intitulée « --soft : déplacer HEAD uniquement »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 ».
# Regrouper les 3 derniers commits en un seulgit reset --soft HEAD~3git commit -m "feat: fonctionnalité complète"--mixed (défaut) : HEAD + index
Section intitulée « --mixed (défaut) : HEAD + index »git reset HEAD~1 # --mixed est le défautgit 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 ».
# Désélectionner un fichier (sans toucher au working dir)git reset HEAD fichier.py# Équivalent moderne :git restore --staged fichier.py--hard : HEAD + index + working directory
Section intitulée « --hard : HEAD + index + working directory »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 ».
# Revenir exactement à l'état de origin/maingit reset --hard origin/mainRécapitulatif visuel
Section intitulée « Récapitulatif visuel »| Mode | HEAD | Index | Working Dir | Données perdues ? |
|---|---|---|---|---|
--soft | Déplacé | Inchangé | Inchangé | Non |
--mixed | Déplacé | Mis à jour | Inchangé | Non |
--hard | Déplacé | Mis à jour | Mis à jour | Oui (non commitées) |
reset sur un fichier
Section intitulée « reset sur un fichier »Quand vous spécifiez un chemin, reset ne déplace pas HEAD. Il met
à jour uniquement l’index pour ce fichier :
# Désélectionner un fichier (retirer du staging)git reset HEAD fichier.py# Identique à :git restore --staged fichier.pyAvec une révision :
# Remettre fichier.py dans l'index à la version de HEAD~3git reset HEAD~3 -- fichier.pyLe working directory n’est pas modifié — seul l’index est mis à jour.
reset vs checkout vs restore vs switch
Section intitulée « reset vs checkout vs restore vs switch »Les commandes modernes simplifient le paysage :
| Action | Ancienne syntaxe | Nouvelle syntaxe |
|---|---|---|
| Changer de branche | git checkout branche | git switch branche |
| Désélectionner un fichier | git reset HEAD fichier | git restore --staged fichier |
| Annuler les modifications d’un fichier | git checkout -- fichier | git restore fichier |
| Revenir à un commit (détached HEAD) | git checkout a1b2c3d | git 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.
reset vs revert
Section intitulée « reset vs revert »| Critère | git reset | git revert |
|---|---|---|
| Mécanisme | Supprime les commits | Crée un commit d’annulation |
| Historique | Réécrit (SHA changent) | Préserve (ajout d’un commit) |
| Commits partagés | Non — casse l’historique des autres | Oui — sûr pour les branches partagées |
| Granularité | Revient à un point | Annule un commit spécifique |
Règle simple : reset pour les commits locaux non poussés,
revert pour les commits partagés.
Cas pratiques
Section intitulée « Cas pratiques »Annuler le dernier commit (garder les modifications)
Section intitulée « Annuler le dernier commit (garder les modifications) »git reset --soft HEAD~1# Les modifications sont dans le staging, prêtes à être modifiéesDésélectionner tout le staging
Section intitulée « Désélectionner tout le staging »git reset# Toutes les modifications passent de stagé à non stagéRevenir à origin/main après un mess
Section intitulée « Revenir à origin/main après un mess »git reset --hard origin/main# Working directory identique à origin/mainSéparer un gros commit en plusieurs
Section intitulée « Séparer un gros commit en plusieurs »git reset --mixed HEAD~1# Les modifications sont dans le working dirgit add partie-1.pygit commit -m "feat: partie 1"git add partie-2.pygit commit -m "feat: partie 2"Récupérer après un reset --hard accidentel
Section intitulée « Récupérer après un reset --hard accidentel »# Le reflog conserve la position précédentegit reflog# a1b2c3d HEAD@{1}: reset: moving to origin/main# e4f5a6b HEAD@{2}: commit: ma feature importante
git reset --hard HEAD@{2}# Restauré !Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
Fichiers perdus après --hard | Reset destructif | git reflog + git reset --hard HEAD@{n} |
reset n’a pas désélectionné | Omission du chemin | git reset HEAD fichier.py (avec le chemin) |
| Collaborateurs cassés après reset | Commits partagés réécrits | Utilisez revert pour les commits partagés |
| Index ne correspond pas au working dir | --mixed appliqué | Normal : --mixed vide l’index, pas le working dir |
À retenir
Section intitulée « À retenir »- 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éesresetsur un fichier = mettre à jour l’index (pas HEAD)resetpour commits locaux,revertpour commits partagés- Le reflog sauve toujours — même après un
--hardaccidentel