Skip to main content

The Git Reset Command


Table of contents


  1. Introduction to Git Reset
  2. The three Reset modes
  3. Reset --soft
  4. Reset --mixed
  5. Reset --hard
  6. Reset a specific file
  7. Recovering after a Reset
  8. Comparison summary


1 - Introduction to Git Reset



git reset is a powerful command that lets you:

  • Undo commits
  • Remove files from staging
  • Return to a previous state

The three Git areas

To understand reset, let's recall the three areas:

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│ Working │ │ Staging │ │ Repository │
│ Directory │ │ Area │ │ (HEAD) │
│ │ │ │ │ │
│ Fichiers │ │ Index │ │ Commits │
│ modifiés │ │ prêt │ │ historique │
└─────────────────┘ └─────────────────┘ └─────────────────┘
▲ ▲ ▲
│ │ │
└──────────────────────┴───────────────────────┘
git reset agit sur ces zones

🔝 Back to table of contents



2 - The three Reset modes



ModeWorking DirectoryStaging AreaHEAD
--soft✅ Preserved✅ Preserved🔄 Moved
--mixed (default)✅ Preserved🔄 Reset🔄 Moved
--hard🔄 Reset🔄 Reset🔄 Moved

Visualization

                        --soft   --mixed  --hard
│ │ │
HEAD (Commits) │ │ │
▲ ▼ ▼ ▼
│ (déplacé)(déplacé)(déplacé)

Staging Area │ │ │
▲ │ ▼ ▼
│ (intact) (reset) (reset)

Working Directory │ │ │
▲ │ │ ▼
│ (intact) (intact) (reset)

🔝 Back to table of contents



3 - Reset --soft



What it does

  • ✅ Moves HEAD to the specified commit
  • ✅ Keeps the staging area intact
  • ✅ Keeps the working directory intact

Use cases

  • Undo a commit while keeping the changes ready to re-commit
  • Fix a commit message
  • Combine several commits (an alternative to squash)

Syntax

git reset --soft HEAD~1    # Annule le dernier commit
git reset --soft HEAD~3 # Annule les 3 derniers commits
git reset --soft abc1234 # Revient au commit abc1234

Practical example

# Situation : vous venez de faire un commit avec un mauvais message
git log --oneline
# abc1234 mauvais message de commit
# def5678 commit précédent

# Annuler le commit (garder les fichiers staged)
git reset --soft HEAD~1

# Vérifier : les fichiers sont toujours staged
git status
# Changes to be committed:
# modified: file.txt

# Refaire le commit avec le bon message
git commit -m "feat: bon message de commit"

🔝 Back to table of contents



4 - Reset --mixed (default)



What it does

  • ✅ Moves HEAD to the specified commit
  • 🔄 Resets the staging area
  • ✅ Keeps the working directory intact

Use cases

  • Remove files from staging without losing the changes
  • Undo a commit and reorganize the changes
  • Split a large commit into several small ones

Syntax

git reset HEAD~1           # --mixed est le défaut
git reset --mixed HEAD~1 # Explicite
git reset HEAD file.txt # Reset un fichier spécifique

Practical example

# Situation : vous avez ajouté trop de fichiers au staging
git add .
git status
# Changes to be committed:
# modified: feature.js
# modified: debug.log # Oups, on ne veut pas ce fichier !

# Retirer tout du staging
git reset

# Ajouter seulement ce qu'on veut
git add feature.js
git commit -m "feat: add feature"

Split a commit

# Commit trop gros
git reset HEAD~1

# Maintenant les fichiers sont unstaged
# On peut les commiter séparément
git add file1.js
git commit -m "feat: first part"

git add file2.js
git commit -m "feat: second part"

🔝 Back to table of contents



5 - Reset --hard



What it does

  • ✅ Moves HEAD to the specified commit
  • 🔄 Resets the staging area
  • 🔄 Resets the working directory

⚠️ DANGER: Uncommitted changes are LOST!

Use cases

  • Completely discard changes
  • Return to a clean state
  • Sync with the remote after a force push

Syntax

git reset --hard HEAD~1    # Annule complètement le dernier commit
git reset --hard HEAD # Annule toutes les modifications locales
git reset --hard origin/main # Synchronise avec le remote

Practical example

# Situation : tout est cassé, on veut revenir à un état propre
git status
# Plein de modifications partout...

# ATTENTION : Ceci supprime TOUTES les modifications !
git reset --hard HEAD

# Ou revenir à l'état du remote
git reset --hard origin/main

Protection before reset --hard

# Toujours vérifier le statut avant
git status

# Optionnel : sauvegarder dans un stash
git stash

# Puis faire le reset
git reset --hard HEAD~1

# Si besoin, récupérer le stash
git stash pop

🔝 Back to table of contents



6 - Reset a specific file



Remove a file from staging

# Équivalent à "unstage"
git reset HEAD fichier.txt

# Ou la syntaxe moderne
git restore --staged fichier.txt

Undo the changes to a file (working directory)

# Attention : perte des modifications !
git checkout -- fichier.txt

# Ou la syntaxe moderne
git restore fichier.txt

Reset a file to a specific version

# Reset un fichier à son état dans un commit spécifique
git checkout abc1234 -- fichier.txt

🔝 Back to table of contents



7 - Recovering after a Reset



The reflog to the rescue

Git keeps a history of all HEAD movements:

git reflog

Result:

abc1234 HEAD@{0}: reset: moving to HEAD~1
def5678 HEAD@{1}: commit: feat: important feature
ghi9012 HEAD@{2}: commit: previous commit

Recover a commit after a reset

# Trouver le commit perdu
git reflog

# Revenir au commit
git reset --hard def5678

# Ou créer une branche pour le récupérer
git branch recovered-branch def5678

Retention period

Git keeps the reflog for 90 days by default. After that, orphan commits are removed by the garbage collector.

🔝 Back to table of contents



8 - Comparison summary



Summary table

CommandHEADStagingWorking DirUsage
reset --softIntactIntactEdit message/squash
reset --mixedResetIntactReorganize staging
reset --hardResetResetDiscard everything

Cheat sheet

--soft  = "Je veux annuler le commit mais garder mes changements prêts"
--mixed = "Je veux annuler le commit et réorganiser mes fichiers"
--hard = "Je veux tout effacer et repartir de zéro"

Frequent commands

# Annuler le dernier commit (garder les modifications)
git reset --soft HEAD~1

# Retirer un fichier du staging
git reset HEAD fichier.txt

# Annuler toutes les modifications locales
git reset --hard HEAD

# Synchroniser avec le remote
git reset --hard origin/main

🔝 Back to table of contents