git reset

Instantanés de base

Réinitialiser le HEAD courant à l’état indiqué


La commande 'git reset' sert à annuler des modifications en déplaçant le HEAD de la branche courante vers un commit donné. Elle a trois modes principaux : --soft (garde les modifications indexées), --mixed (par défaut - garde les modifications dans le répertoire de travail) et --hard (jette toutes les modifications). Cette commande est essentielle pour annuler des commits, désindexer des fichiers et gérer votre historique. Attention avec 'git reset --hard', qui jette définitivement les modifications.

Synopsis

git reset [-q] [<tree-ish>] [--] <pathspec>...
git reset [-q] [--pathspec-from-file=<file>] [<tree-ish>]
git reset (--patch | -p) [<tree-ish>] [--] [<pathspec>...]
git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]
[ ] facultatif| ou<arg> valeur à remplacer... répétable--flag option

Options

Cliquez sur une option pour la déplier

Débutant (3)

Réinitialise HEAD sur le commit indiqué mais garde toutes les modifications indexées. Votre répertoire de travail et votre zone de préparation ne changent pas. Sert à annuler des commits en gardant les modifications prêtes à être committées de nouveau.

Si nécessaireAnnuler des commits en gardant les modifications préparées — par ex. pour recommitter ou fusionner

Exemple

git reset --soft HEAD~1

Le mode par défaut. Réinitialise HEAD et la zone de préparation, mais garde les modifications dans le répertoire de travail. Sert à désindexer des modifications tout en les gardant modifiables.

RecommandéLa façon la plus sûre d’annuler un commit local ou de retirer de la préparation ; garde vos modifications

Exemple

git reset HEAD~1

Réinitialise HEAD, la zone de préparation ET le répertoire de travail sur le commit donné. Les modifications non committées des fichiers suivis sont jetées, et les fichiers non suivis qui gênent les fichiers du commit sont écrasés (les autres fichiers non suivis ne sont pas touchés). Aucune annulation possible pour les modifications non committées.

DéconseilléDétruit les modifications non commitées des fichiers suivis — mettez-les dans le stash ou committez d’abord

Exemple

git reset --hard HEAD~1

Intermédiaire (1)

Choisir de façon interactive les blocs à désindexer. Permet de retirer certaines modifications de la zone de préparation tout en gardant les autres indexées.

Si nécessaireRetirer interactivement des hunks de la préparation

Exemple

git reset -p

Avancé (2)

Réinitialise l’index et met à jour les fichiers qui diffèrent entre le commit et HEAD, mais garde les modifications non indexées. Les modifications indexées sont jetées. S’interrompt si un fichier à modifier a des modifications non indexées.

Si nécessaireAbandonne une fusion ; jette les modifications préparées mais garde celles qui ne le sont pas

Exemple

git reset --merge HEAD~1

Réinitialise l’index et met à jour les fichiers qui diffèrent entre le commit et HEAD. S’interrompt si l’un de ces fichiers a des modifications locales. Conserve les modifications non committées des fichiers identiques entre les deux commits.

Si nécessairePlus sûr que --hard pour reculer : refuse d’écraser les modifications locales

Exemple

git reset --keep HEAD~1

Choisir la bonne option

Modes de reset : qu’est-ce qui est conservé ?

Comprendre les trois modes principaux de reset et ce qu’il advient de vos modifications

CommandeHEAD se déplaceZone de préparationRépertoire de travailÀ utiliser quand
--softOuiConservé (indexé)ConservéAnnuler un commit pour le refaire avec des modifications
--mixed (default)OuiVidé (désindexé)ConservéAnnuler un commit pour retoucher avant d’indexer
--hardOuiVidéModifications suivies PERDUES (non suivies gardées)Jeter complètement le commit et toutes les modifications

Reset, revert ou checkout

Choisir la bonne commande d’annulation selon la situation

CommandeModifie l’historique ?Sans danger pour les commits poussés ?Idéal pour
git resetOui (déplace la branche)Non - pose problèmeAnnuler des commits locaux pas encore poussés
git revertNon (ajoute un nouveau commit)Oui - sans danger pour les branches partagéesAnnuler des commits poussés sur des branches partagées
git checkout -- fileNoOuiJeter les modifications non committées de fichiers précis

Désindexer des modifications : reset ou restore

Le Git moderne propose git restore comme alternative à reset pour désindexer

CommandeButTouche les commits ?Recommandé
git reset HEAD fileDésindexer un fichierNoFaçon traditionnelle
git restore --staged fileDésindexer un fichierNoFaçon moderne (Git 2.23+)
git resetDésindexer tous les fichiersNoFonctionne bien
git restore --staged .Désindexer tous les fichiersNoIntention plus explicite

Modes de reset avancés

Quand utiliser --merge et --keep plutôt que --hard

CommandeGarde les modifications locales ?S’interrompt en cas de conflit ?Cas d’usage
--hardNon - détruit toutNoReset complet, les modifications n’importent pas
--mergeModifications non indexées seulement (les indexées sont perdues)OuiAbandonner une fusion en gardant le travail sans rapport
--keepOui (dans les fichiers que le reset ne touche pas)OuiAnnuler un commit mais garder les modifications locales sans rapport

Exemples

Annuler le dernier commit, garder les modifications indexées

git reset --soft HEAD~1

Recule HEAD d’un commit. Les modifications de ce commit restent indexées, prêtes à être committées de nouveau.


Annuler le dernier commit, garder les modifications dans le répertoire de travail

git reset HEAD~1

Mode par défaut (--mixed). Recule HEAD d’un commit. Les modifications sont conservées mais désindexées.


Jeter complètement le dernier commit et les modifications

git reset --hard HEAD~1

Recule HEAD d’un commit et jette TOUTES les modifications non committées des fichiers suivis. Avec prudence - le travail non committé perdu est irrécupérable (le commit lui-même reste dans git reflog).


Désindexer un fichier précis

git reset HEAD file.js

Retire file.js de la zone de préparation sans jeter les modifications. Le fichier reste modifié dans le répertoire de travail.

Exemples de workflows

1
git log --oneline -3

Voir les commits récents pour confirmer lequel annuler

2
git reset --soft HEAD~1

Annuler le commit, garder les modifications indexées

3
git status

Vérifier que les modifications sont indexées

4
git commit -m "Better message"

Committer de nouveau avec un nouveau message

1
git status

Voir ce qui est actuellement indexé

2
git reset HEAD unwanted-file.js

Désindexer un ou plusieurs fichiers

3
git status

Vérifier que le fichier n’est plus indexé

4
git commit

Committer seulement les fichiers voulus

1
git status

Relire ce qui va être perdu

2
git stash

(Facultatif) Mettre les modifications de côté au cas où

3
git reset --hard HEAD~1

Jeter le dernier commit ET toutes les modifications suivies (les fichiers non suivis restent)

4
git status

Vérifier que le répertoire de travail est propre

1
git reflog

Retrouver le hash du commit d’avant le reset

2
git reset --hard abc1234

Revenir sur ce hash de commit

3
git log --oneline

Vérifier que les commits sont restaurés

Dépannage

fatal: ambiguous argument 'HEAD~1': unknown revision

Cause : Vous êtes sur le commit initial - il n’y a pas de commit précédent sur lequel revenir

Vérifiez git log. S’il n’y a qu’un seul commit, vous ne pouvez pas reculer davantage. Utilisez git update-ref -d HEAD pour tout recommencer.

error: Entry 'app.js' not uptodate. Cannot merge.

Cause : Un fichier que --merge ou --keep devrait modifier a des modifications locales non committées, donc le reset est abandonné

Committez ou mettez de côté vos modifications d’abord, ou utilisez --hard si vous voulez les jeter

--hard utilisé par erreur, modifications perdues

Cause : Le reset hard jette définitivement tout le travail non committé

Si les modifications avaient été committées : git reflog pour retrouver le commit, puis git reset --hard <hash>. Si elles n’ont jamais été committées : elles sont sans doute perdues pour toujours.

Le reset a marché mais un collègue dit que l’historique est cassé

Cause : Vous avez réinitialisé des commits déjà poussés sur une branche partagée

Pour les branches partagées, utilisez plutôt git revert. Pour réparer : git reflog, retrouvez le commit d’origine, faites un reset dessus, puis un force push (en vous coordonnant avec l’équipe).

fatal: ambiguous argument 'HEAD' en lançant git reset HEAD file

Cause : Le dépôt n’a encore aucun commit, donc HEAD n’existe pas (ou le chemin est faux)

Retirez HEAD : git reset file.js (ou git rm --cached file.js). Vérifiez le chemin exact avec git status.

Astuces et pièges

Bonnes pratiques

  • ✓N’utilisez jamais git reset sur des commits poussés sur des branches partagées - utilisez plutôt git revert
  • ✓Lancez toujours git status avant un reset pour comprendre ce qui sera touché
  • ✓Préférez --soft quand vous voulez refaire un commit avec des modifications
  • ✓Faites git stash avant un reset --hard si vous risquez de vouloir récupérer vos modifications
  • ✓Rappelez-vous que git reflog permet de rattraper la plupart des erreurs de reset (pour les modifications committées)
  • ✓Utilisez git reset HEAD <file> pour désindexer des fichiers au lieu de réinitialiser des commits entiers
  • ✓Pensez à git restore --staged, l’alternative moderne pour désindexer des fichiers

Erreurs fréquentes

  • ✗Utiliser 'git reset --hard' sans réaliser qu’il supprime définitivement les modifications non committées. Vérifiez toujours deux fois avant d’utiliser --hard.
  • ✗Réinitialiser des commits déjà poussés sur un dépôt distant partagé. Cela réécrit l’historique et pose problème aux collaborateurs. Utilisez plutôt 'git revert'.
  • ✗Confondre 'git reset' et 'git revert'. Reset recule le pointeur de branche ; revert crée un nouveau commit qui annule des modifications.
  • ✗Ne pas savoir qu’on peut se rattraper d’un mauvais reset avec 'git reflog', pour retrouver le hash du commit précédent.
  • ✗Utiliser 'git reset --hard HEAD' pour jeter des modifications de travail alors que 'git checkout -- .' ou 'git restore .' conviendrait mieux.

FAQ

A:

Soft garde les modifications indexées. Mixed (par défaut) les garde dans le répertoire de travail mais désindexées. Hard jette tout. Retenez : soft = annuler le commit seulement, mixed = annuler le commit + désindexer, hard = tout annuler.

A:

Pour les modifications committées : oui, retrouvez le hash du commit d’origine avec git reflog, puis faites un reset dessus. Pour les modifications non committées perdues par --hard : en général non, elles ont définitivement disparu.

A:

HEAD~1 signifie « un commit avant HEAD ». HEAD~2, deux commits en arrière, etc. Vous pouvez aussi utiliser directement des hashes de commit, comme git reset abc1234.

A:

Reset pour les commits locaux pas encore poussés - il réécrit proprement l’historique. Revert pour les commits poussés sur des branches partagées - il crée un nouveau commit qui annule les modifications sans réécrire l’historique.

A:

Utilisez git reset HEAD filename pour désindexer un fichier précis. HEAD ne bouge pas et aucun commit n’est touché : le fichier est simplement retiré de la zone de préparation.

A:

Il supprime définitivement les modifications non committées. Contrairement aux modifications committées (récupérables via le reflog), un travail jamais committé ne peut pas être récupéré après un reset hard.