Undoing things safely
The right undo depends on how far the change got (the four places). Before
pushing, you can rewrite freely. After pushing, don't rewrite. Add a new commit that reverses it (revert).
And almost nothing committed is ever truly lost: reflog remembers.
Match the undo to the place
| Mistake is in… | Undo | Effect |
|---|---|---|
| Working tree (unsaved-to-git edit) | git restore File.cpp | Throws the edit away. Can't be undone, so be sure |
| Staging (added by mistake) | git restore --staged File.cpp | Unstages it; your edit stays in the file |
| Last commit, not pushed | git commit --amend | Fix the message or add forgotten files to it |
| Recent commits, not pushed | git reset HEAD~1 | Un-commits, keeping the changes in your files |
| A commit that's already pushed | git revert abc1234 | Makes a new commit that does the opposite. History stays intact. The team-safe one. |
revert vs reset: the one that matters in a team
resetmoves your branch label backwards, erasing commits from history. If teammates already pulled them, your histories no longer match, and pushing needs--force(never on shared branches).revertmoves forward: a new commit that undoes the old one. Everyone just pulls it. Nothing is rewritten.
Rule: pushed means revert. Only yours and unpushed means amend or reset are fine.
git reset --hard resets the branch and wipes uncommitted changes in your files. Committed work is
recoverable (see below); uncommitted work is not. Run git status first, or git stash to keep things
safe.
The safety net: reflog
git reflog
7a3d5fc HEAD@{0}: reset: moving to HEAD~2
9f12ab3 HEAD@{1}: commit: Add unequip axe ability ← "lost" commit, still here
...
git switch -c rescue 9f12ab3 # get it back on a branch
The reflog records every place HEAD has been, locally, for about 90 days. A bad reset or a deleted branch is
almost always recoverable from it.
Quiz yourself
You staged a file by mistake. Undo without losing the edit?
git restore --staged File.
Typo in your last commit message, not pushed yet. Fix?
git commit --amend.
A commit that broke the build is already on GitHub's main. Undo how?
git revert <hash>: a new commit reversing it. Push that. Don't reset shared history.
revert vs reset, in one line each?
Revert adds a new opposite commit (safe after pushing). Reset moves the branch back, erasing commits (only for unpushed work).
What can git reset --hard destroy permanently?
Uncommitted changes in your working tree. Committed work can still be recovered via the reflog.
You reset away a commit and regret it. Where do you find it?
git reflog. Then branch or reset back to its hash.