Git: undo (almost) anything
Undo unstaged changes
You changed a file and want to go back to the last committed version. ⚠️ git restore overwrites your changes with no way back — check with git diff that you're not throwing away anything important.
git diff # relis ce que tu vas perdre / re-read what you're about to lose
git restore <fichier> # ⚠️ écrase les modifs du fichier / discards the file's changes
git restore . # ⚠️ écrase TOUTES les modifs / discards ALL changesUnstage a file
Ran git add on too much? restore --staged removes the file from the staging area without touching its content. No risk here: your changes stay in the file.
git restore --staged <fichier>
git restore --staged . # dé-stage tout / unstage everythingFix the last commit
Bad message, forgotten file? --amend replaces the last commit with a new one. ⚠️ It rewrites history: only do it if the commit has not been pushed yet. If it's already on the remote, use revert (next section).
git commit --amend -m "meilleur message" # corrige le message / fix the message
git add fichier-oublie && git commit --amend --no-edit # ajoute un fichier / add a fileUndo a pushed commit
The commit is already on the remote, others may have pulled it: don't rewrite anything. git revert creates a new commit that applies the inverse — history stays intact and everyone stays in sync. It's THE safe method on a shared branch.
git revert <commit> # annule ce commit par un commit inverse / undo via an inverse commit
git pushRoll back locally
git reset moves your branch to an earlier commit. Three modes, from gentlest to most destructive:
--soft: changes from the undone commits stay staged (great for re-splitting).--mixed(default): they stay in your files, unstaged.- ⚠️
--hard: everything is wiped, commits AND pending changes. Local use only, and only when you're sure of yourgit status.
git reset --soft HEAD~1 # annule le commit, garde tout stagé / undo commit, keep staged
git reset HEAD~1 # annule le commit, garde les fichiers / undo commit, keep files
git reset --hard HEAD~1 # ⚠️ efface commit ET modifs / wipes commit AND changesRecover a "lost" commit
One reset --hard too many, deleted a branch? Breathe: a commit is almost never truly lost. git reflog journals every move of HEAD for ~90 days. Find the hash from before the mistake, and start again from there.
git reflog # historique des positions de HEAD / history of HEAD positions
git switch -c secours <hash> # nouvelle branche sur le commit retrouvé / new branch on the recovered commitpush --force: the real danger
⚠️ Never git push --force on a shared branch: you silently overwrite commits your teammates may have pushed in the meantime. If you really must force (after rebasing YOUR feature branch), use --force-with-lease: it refuses to push if the remote moved since you last fetched.
git push --force-with-lease # force "poli" : échoue si le distant a changé / "polite" force: fails if remote changed