■ the answer first

One command answers the whole family — git reset --soft HEAD~1 steps the branch label back one commit and hands your work back staged.

Undo, cancel, revert are not three git features. Two of them are the same reset in different accents; revert is the odd one out because it adds history instead of rewinding it.

Already pushed? Revert, never rewrite — anyone who pulled is holding the old commits.

git reset --soft HEAD~1 is the answer to every keep-changes spelling: the branch label steps back one commit and your work comes back staged, ready to re-commit. Pushed the commit already? Use git revert HEAD instead — it adds an inverse commit and rewrites nothing.

THE VERB TABLE

Every word people type, what git actually does, and whether the work survives:

Verb people typeWhat git actually doesKeeps the work?The command
"undo"Branch label moves back one commit; the changes return stagedYes — in the indexgit reset --soft HEAD~1
"cancel"Default reset: label moves back, changes return but unstagedYes — in the working treegit reset HEAD~1
"revert"A new commit is added that undoes the old one; history is never rewrittenYes — as an inverse diffgit revert HEAD
"unstage"Paths leave the index; file contents are untouchedYes — nothing left the working treegit restore --staged file.txt
"shelve it for now"Work is boxed and put on a shelf you can pop laterYes — on the stash stackgit stash push -m "wip"

The only decision that matters: did anyone pull it?

No — it's still yours: git reset --soft HEAD~1. The label steps back, your work returns staged. Yes — someone pulled it: git revert HEAD. History grows an inverse commit; nothing anyone pulled is rewritten. Either way the work survives — the choice is only about whose copy of history stays true. And if the flag that scares you is --hard: it is the only member of the family that deletes work, and it is never required for keeping changes. You found this page precisely so you never have to type it.

What does --soft actually keep?

Everything, staged. The commit leaves the branch, the diff comes back into the index exactly as it was committed, and git status reads "changes to be committed". Fix what you meant to fix and re-commit — or fold in more work first. It is one step short of --amend: amend rewrites the last commit in place; soft undoes it and waits for you.

Is amend an undo?

A small one, for the last commit only. git commit --amend --no-edit folds staged changes into the commit you just made — perfect for the forgotten file. The rule from the pushed-commit section still applies: amending a pushed commit rewrites history, so on a shared branch, revert instead.

When is --hard actually the right answer?

When you want the working tree to match a commit exactly, and you have looked at what will be lost. git reset --hard HEAD~1 discards the commit and the uncommitted edits in one motion — git will not ask twice. The safety ritual is one line: git branch backup-before-reset first; branches are free. And if you already ran it, git reflog remembers where HEAD was for about 90 days — git reset --hard HEAD@{1} walks it back.

How do I throw away edits in one file only?

git restore file.txt — the modern spelling of the old git checkout -- file. It discards the working-tree edits for that one path and touches nothing else: no branch movement, no staging change. For getting a file back to a specific commit: git restore --source <sha> file.txt.

Where does stash fit in the family?

Stash is the only verb that boxes work away instead of repositioning it. git stash push -m "wip" shelves your edits and hands you a clean tree; git stash pop brings them back. It's the right tool when you need to switch branches mid-task — and it takes a pathspec, so one file can be shelved while the rest stays dirty.

I already ran the wrong command. Is the work gone?

Almost never. Reset moves a label; revert adds a commit; neither deletes objects. git reflog lists every place HEAD has been for ~90 days — find the pre-mistake entry and git reset --hard HEAD@{n} returns you there. The genuinely unrecoverable set is narrow: untracked files deleted by git clean -f, and reflog entries past their clock.

■ honest stamp Tested on: git 2.30+ semantics · record: official git docs + this site's search ledger. Recorded 2026-10-11. Every command above keeps the work unless its name is --hard; the 73-impressions line is this site's own search board, printed because the fear is measurable. The answers are git's documented behaviour, not forum folklore.

end of the verb family · nothing fetched · everything local