Undoing Changes in Git
Undoing Changes in Git
Section titled โUndoing Changes in GitโGit gives you multiple tools for undoing changes. Choose the right one based on whether the commit is local or shared, and how far back you need to go.
Before You Commit
Section titled โBefore You Commitโ# Discard all changes in working tree (cannot be recovered)git restore .git restore path/to/file.ts
# Unstage a file (keep changes in working tree)git restore --staged path/to/file.ts
# Unstage everythinggit restore --staged .Amending the Last Commit
Section titled โAmending the Last CommitโFix the most recent commit โ message, files, or both:
# Change the commit messagegit commit --amend -m "Better commit message"
# Add a forgotten file to the last commitgit add forgotten-file.tsgit commit --amend --no-edit
# Change both files and messagegit add fixed-file.tsgit commit --amend -m "Correct message and files"Only amend commits that have not been pushed โ amending rewrites history.
git revert (Safe for Shared History)
Section titled โgit revert (Safe for Shared History)โCreates a new commit that undoes the changes from a previous commit. Safe because it doesnโt rewrite history:
# Revert the last commitgit revert HEAD
# Revert a specific commitgit revert abc1234
# Revert without automatically committing (preview changes first)git revert -n abc1234git revert --no-commit abc1234
# Revert a range of commitsgit revert abc1234..ghi9012Use revert when the commit has been pushed to a shared branch.
git reset (For Local History Only)
Section titled โgit reset (For Local History Only)โgit reset moves HEAD (and the branch pointer) to a different commit. Three modes:
# --soft: keeps staged changes and working treegit reset --soft HEAD~1 # undo last commit, keep changes staged
# --mixed (default): unstages changes, keeps working treegit reset HEAD~1 # undo last commit, changes in working treegit reset --mixed HEAD~1 # same
# --hard: discards staged and working tree changesgit reset --hard HEAD~1 # undo last commit, LOSE all changesgit reset --hard origin/main # match remote exactlyNever use --hard unless youโre certain you donโt need those changes.
Recovering with reflog
Section titled โRecovering with reflogโgit reflog records every change to HEAD โ even after reset or rebase:
git reflog# abc1234 HEAD@{0}: reset: moving to HEAD~1# def5678 HEAD@{1}: commit: Add user profile page# ...
# Recover the lost commitgit reset --hard def5678# or create a branch at itgit switch -c recovery-branch def5678The reflog is local only and entries expire after 90 days (default).
Removing a File from Tracking
Section titled โRemoving a File from Trackingโ# Stop tracking a file but keep it on diskgit rm --cached secrets.env
# Stop tracking a directorygit rm --cached -r config/local/
# Then add to .gitignore to prevent re-trackingCleaning Untracked Files
Section titled โCleaning Untracked Filesโ# Preview what would be deletedgit clean -n
# Delete untracked filesgit clean -f
# Delete untracked files and directoriesgit clean -fd
# Delete files including ignored onesgit clean -fxdCheckout vs Restore vs Reset
Section titled โCheckout vs Restore vs Resetโ| Command | What it does |
|---|---|
git restore <file> | Discard working tree changes |
git restore --staged <file> | Unstage file |
git revert <commit> | Create new commit undoing changes (safe) |
git reset --soft HEAD~n | Undo commits, keep changes staged |
git reset --mixed HEAD~n | Undo commits, changes go to working tree |
git reset --hard HEAD~n | Undo commits, discard all changes |
Summary Decision Tree
Section titled โSummary Decision TreeโDid you push the commit to a shared branch?โโโ YES โ git revert (creates a new "undo" commit)โโโ NO โ What do you want to undo? โโโ Just the commit message โ git commit --amend โโโ Last commit (keep changes) โ git reset --soft HEAD~1 โโโ Last commit + changes โ git reset --hard HEAD~1