git.tools / guides

Git commands explained in plain English

What reset, revert, rebase, cherry-pick, reflog and friends actually do — explained like a coworker would, not like a man page.

Last updated September 18, 2026 · 4 min read

Git's command names were chosen by people who already understood git. For everyone else, here's the translation. Two ideas unlock almost all of it:

  1. A commit is a snapshot of your whole project, chained to its parent.
  2. A branch is just a sticky note pointing at one commit. It moves freely.

Most "scary" commands are either moving sticky notes or rewriting the chain. Keep those two pictures in your head and the table below reads like common sense.

The cheat sheet

Command What it actually does Danger level
git commit --amend Replaces your last commit with a new version Low (until pushed)
git stash Shelves uncommitted changes on a side pile Low
git cherry-pick <sha> Copies one commit's changes onto your branch Low
git revert <sha> Adds a commit that cancels an old one Low
git merge <branch> Weaves two branches together, keeps both histories Medium
git rebase <branch> Replays your commits on top of another branch Medium
git reset --soft HEAD~1 Deletes the last commit, keeps the changes staged Medium
git reset --hard HEAD~1 Deletes the last commit and its changes High
git clean -fd Deletes untracked files. Permanently. High
git push --force Overwrites the remote branch with yours High
git rebase -i Rewrites, reorders, or drops a run of commits High
git reflog Shows everywhere HEAD has been — your undo log None (read-only)

The five that hurt people

git reset --hard — the number-one source of "I just lost my work." It moves your branch backwards and throws away everything in your working tree that isn't committed. The commits are usually recoverable via reflog or worse; uncommitted changes are simply gone.

git push --force — rewrites the branch on the server to match yours. If anyone pulled the old version, their history now disagrees with reality, and any commits of theirs you didn't have are orphaned. Use --force-with-lease, which bails out if the remote moved without you knowing.

git rebase -i — incredibly useful, but it's a history editor: drop, squash, reword, reorder. Every commit it touches gets a new identity, so never run it on commits you've already pushed to a shared branch. Squashing with it is its most common good use.

git clean -fd — deletes files git isn't tracking, which by definition means there's no copy in any commit, anywhere. There is no undo. Run git clean -nd first — the -n dry-run shows what would die.

git commit --amend — harmless and lovely for fixing a typo'd message, until the commit has been pushed. Amending rewrites the commit, so pushing afterwards requires a force push, with all the baggage above.

The commands that get you out of trouble

git reflog is the big one — git quietly logs every place HEAD pointed, so "deleted" work is usually one lookup away from being found again. It only knows your local clone, though, and entries expire. Treat it as a smoke detector, not a backup strategy.

git revert is the polite undo: instead of erasing the past, it appends a commit that cancels the bad one. Safe on any branch, no matter how many people pulled. Full walkthrough here.

git merge --abort — the one everyone forgets mid-panic. Stuck in a conflicted merge you regret? This cancels it and puts everything back.

git.tools

Skip the memorization

git.tools reads your repo's history and shows it in plain English — and every scary operation below exists as a safe, reviewed pull request instead of a command you have to get right under pressure.

Open git.tools →

A parting heuristic

If a command's description includes the words "rewrite history," the rule is always the same: fine on commits only you have, hostile on anything pushed. When in doubt, take the path that adds new history instead of rewriting old — it's almost always available, and it's the default philosophy git.tools is built on. For the rare cases where rewriting really is the answer — like purging a leaked secret — we do it with backups and guardrails, never a YOLO force push.

Common questions

What's the difference between revert and reset?

Reset moves your branch backwards and pretends commits never happened — fine locally, dangerous once pushed. Revert adds a new commit that cancels an old one, leaving history intact — the safe choice on shared branches.

Merge or rebase — which should I use?

Merge preserves true history, including the messy parallel reality of how the work happened. Rebase replays your commits on top of the target for a cleaner, linear story. Merge for shared and release branches; rebase for tidying your own unpushed work.

Is git reflog really a way to undo almost anything?

Mostly yes — reflog records every move HEAD made in your local clone for 30–90 days, so orphaned commits are usually findable. Its limits: it's local-only, it expires, and it won't have commits you never fetched.

Why does everyone say to use --force-with-lease instead of --force?

--force blindly overwrites the remote branch. --force-with-lease refuses if the remote moved since your last fetch — meaning it can't silently destroy a teammate's pushed work. It's a seatbelt that costs nothing.