The Rescue Playbook
the messes everyone actually makes, and the exact way out of each - drill by drill
Every drill below starts the same way: stop typing. Panic commands turn one mistake into three. Then ask the chapter-6 question - what was actually touched? - and pick the drill. Nothing here needs memorizing; it needs recognizing.
$ git reflog -5 # top entries:
7a879c4 HEAD@{0}: reset: moving to HEAD~2
c939e70 HEAD@{1}: revert: Revert "raise th...
$ git reset --hard HEAD@{1}
HEAD is now at c939e70 Revert "raise the f...Drill one: the bad hard reset. You reset and commits you still wanted are gone from git log. If they were committed, the reflog - the local reference log - still lists where HEAD stood, for as long as its entries live. Check the desk is clean first (stash if not), confirm the entry with git show, then walk back.
Drill two: commits made on a detached HEAD. You visited an old commit, made new work there, and git switch main warns your commits will be left behind. No name points at them - so give them one before you leave: git switch -c rescue puts a branch under your feet where you stand (the HEAD card drew this exact escape). Left already? The ledger still lists the abandoned commit - drill one applies.
Drill three: committed on the wrong branch. The work is safe - it is committed, just under the wrong name. Create a branch on it where it stands (git branch take-this-work), then walk the wrong branch back one step with git reset --hard HEAD~1 (clean desk first) - the commit stays reachable through the NEW name. Switch to the right branch and merge the work in (merge = bring another branch's commits into yours - the Timelines chapter owns it) or carry it over.
Notice the playbook pattern: in git, saving work usually means naming it - a branch is a name that keeps a commit reachable for as long as the name exists.
Drill four: staged but never committed, then a hard reset. The working-directory copy is gone - but git add had written those bytes into the object store as a nameless blob. git fsck --lost-found can surface such dangling content IF the blob still exists (pruning eventually removes unreferenced objects): bytes without a filename - better than nothing, worse than a commit. (Not executed in this chapter's repo - the command and its limits are the lesson.)
And the drill that beats every drill: stay on the safe side of the boundary. Before a risky reset or a big cleanup: commit - the only durable save. (git add is a temporary net: uncommitted blobs can be pruned later. A stash - the sharp-tools drawer that records your working directory before clearing it - skips untracked files unless you ask with -u.) One command, and every rescue in this playbook works.