devutils/ATFQ/book ATFQ git

Part III · Shell and commands

30.2 Undoing things in git

alsogit undogit resetgit revertgit restoregit reflogreflogundo commitgit commit --amendamendlost commitdiscard changesgit stashstashunstage

TL;DR

  • Committed work is almost never lost: the reflog remembers every place a branch has been. Uncommitted edits are the fragile part.
  • Pick the command by what you want back: a file, a commit, or a commit others already have.
git restore --staged FILE     # unstage a file, keep the edits
git restore FILE              # drop your edits to it: gone for good
git reset --soft HEAD~1       # undo the last commit, keep its changes
git revert COMMIT             # undo a pushed commit with a new commit
git reflog                    # where HEAD has been: find lost commits

Pitfalls

Deep dive 2 questions

How can the reflog save me?

Every time HEAD moves (commit, reset, rebase, checkout), git writes the old and new positions in the reflog, for 90 days by default. A commit "lost" by a bad reset or rebase is still in the object store: find it in git reflog, then git branch rescue ID or reset to it. Only uncommitted changes are truly unrecoverable.

reset, restore, revert: which is which?

restore changes files (working tree or staging area) and never moves a branch. reset moves the current branch to another commit; --soft keeps your changes staged, the default keeps them unstaged, --hard discards them. revert creates a new commit that applies the opposite of an old one, leaving history as it was.

Commands
git
See also
30.1 How git stores your work
30.4 Remotes: fetch, pull and push