Git Beyond the Basics: Rebase, Reflog, and Recovering Anything
Once commit, push, and pull are muscle memory, a handful of commands change how you actually work with Git — interactive rebase for clean history, and the reflog, which means you can almost never truly lose work.
Most people learn just enough Git to survive: add, commit, push, pull, and panic. That's genuinely enough to ship. But a few commands past the basics change the relationship — from "I'm scared to touch history" to "history is mine to shape, and I can undo anything." Here are the ones worth the investment.
The mental model that unlocks all of it: a commit is a snapshot, and a branch is just a movable pointer to one. Almost every "advanced" command is moving pointers around. Nothing is as fragile as it feels.
Rebase: replay your work on a new base
Merge and rebase both combine branches; they produce different histories. Merge preserves exactly what happened, creating a merge commit and a branching graph. Rebase rewrites your commits as if you'd started from the latest main — a straight line.
git switch feature
git rebase main # replay feature's commits on top of current mainI rebase feature branches before opening a PR so the history reads as a clean sequence instead of a tangle of merge commits. The reviewer sees a linear story.
Interactive rebase: edit history on purpose
This is the one I use most. Interactive rebase lets you rewrite the last N commits — squash noise, reorder, reword messages, drop mistakes.
git rebase -i HEAD~4 # edit the last 4 commitsYou get an editor listing them, and you change the verb next to each:
pick a1b2c3 Add submission endpoint
squash d4e5f6 fix typo ← fold into the commit above
squash 7a8b9c actually fix it ← fold in too
reword 0d1e2f Add validation ← change this messageThose three "fix typo, wip, actually fix it" commits become one clean commit. The history that lands on main tells the story of what changed, not the story of you fumbling toward it. That's a gift to whoever reads it later — often you.
The reflog: your safety net
Here's the command that removes the fear. Git records every place HEAD has ever pointed — every commit, checkout, reset, rebase — in the reflog, even commits that are no longer on any branch.
git reflog
# a1b2c3 HEAD@{0}: reset: moving to HEAD~3
# 9f8e7d HEAD@{1}: commit: the work I just "lost" ← still hereRan a reset --hard and deleted three commits of work? They're not gone. Find them in the reflog and come back:
git reset --hard HEAD@{1} # restore to right before the bad resetThis is why I tell people to stop being scared of Git. As long as you'd committed the work, it lives in the reflog for weeks — a botched rebase, a bad reset, a deleted branch, all recoverable. The reflog is the closest thing to an undo button for your entire repository.
Two more that pay off
git stash — shelve half-finished work to switch context, then bring it back:
git stash # tuck away uncommitted changes
git switch main # go deal with the urgent thing
git stash pop # ...and get your work backgit bisect — binary-search your history to find the commit that introduced a bug. You mark a known-good and known-bad commit, and Git checks out the midpoints for you to test:
git bisect start
git bisect bad # current commit is broken
git bisect good v1.2.0 # this old one worked
# git checks out the middle; you test and mark good/bad until it names the culpritOn a long history this turns "which of 200 commits broke this?" from a day of guessing into a few tests.
The shift
The basics treat Git as a place to store snapshots. These commands treat it as a tool to shape them — clean history you author deliberately, and a safety net that means work you committed is almost never truly lost. That combination is what makes Git go from something you tolerate to something you use with confidence.