Git Course 0%

Decision guide: which undo do I need?

Intermediate Core Git ≈ 5 min

Before this lesson

What you will learn

  • The two questions that pick the command every time
  • A symptom-to-command table for the whole section

After this lesson you can

  • I can find the right undo in under a minute, under pressure

Why this matters

The rest of this section explains why. This page is for the moment when you need the answer, not the reasoning. Bookmark it; it is the page to open first when something has gone wrong. The reference section carries the same guide beside its siblings (Decision guides).

The flowchart

Decision guide: I want to undo something. Which command? A flowchart. Start by running git status and git log. First question: is the thing you want to undo committed? If no, and it is staged, git restore --staged the file; if it is only edited, git restore the file, which is permanent; if you just want to park it, git stash. If yes, it is committed, second question: has it been pushed where others can see it? If yes, git revert the hash, which adds an undo commit and is the only safe choice. If no, third question: is it the most recent commit and only the message or a missing file is wrong? If yes, git commit --amend. If no, git reset, choosing soft to keep the change staged, mixed to keep it in the files, or hard to discard it. A final note says if you cannot see the commit at all, run git reflog first. git status · git log Is it committed? check git status no — not committed git restore --staged <f> to unstage, keeping the edit git restore <f> (permanent) just parking it? git stash back with git stash pop Has it been pushed? can anyone else see it? yes — pushed git revert <hash> adds an undo commit; the only safe choice here Latest commit, and only the message or a file is wrong? yes git commit --amend stage the file first no — move the branch back git reset <mode> <target> --soft keeps the change staged, ready to re-commit --mixed keeps the change in your files (the default) --hard discards it; check git status first no or yes no no Cannot see the commit at all? Run git reflog first: it lists every position HEAD has held. Everything on the amber path rewrites history, so it is only for commits you have not pushed.
Two questions decide almost everything: is it committed, and has it been pushed?

The same thing as a table

What happened Command
I edited a file and want the committed version back git restore <file> — permanent, check git diff first
I staged the wrong thing git restore --staged <file> — the edit is kept
I need to park this and do something else git stash, later git stash pop
My last commit has a bad message, not pushed git commit --amend -m "…"
I forgot a file in the last commit, not pushed git add <file> then git commit --amend --no-edit
My last three commits should be one, not pushed git reset --soft HEAD~3, then commit again
I want to drop the last commit and its changes, not pushed git reset --hard HEAD~1 — check git status first
The commit is pushed and it is wrong git revert <hash>, then push
I committed to main by mistake, not pushed git branch <name> then git reset --hard origin/main
I have uncommitted work on the wrong branch git stash, git switch -c <name>, git stash pop
I need this commit on another branch too git switch <other> then git cherry-pick <hash>
A merge is half-done and conflicting git merge --abort
A rebase is half-done and conflicting git rebase --abort
The merge is committed but not pushed git reset --hard ORIG_HEAD
The merge is pushed git revert -m 1 <merge hash>
I deleted a branch I needed git switch -c <name> <hash> from the delete message or git reflog
I deleted a file in a commit git restore --source=<commit>~1 <path>, then add and commit
My commit vanished after a reset git reflog, then git reset --hard <hash>
I am in detached HEAD with commits git branch <name> <hash>
I dropped a stash git stash apply <hash from the "Dropped" line>
My push is rejected after amending git push --force-with-lease, on your own branch only
Someone force-pushed over my commit git branch rescue/x <hash from your reflog>, then cherry-pick it back
I have no idea what I did git reflog and read it before typing anything else

The two questions, once more

Is it committed? If not, you are dealing with files: restore, restore --staged, stash. The reflog cannot help, because Git never saw the work.

Has it been pushed? If yes, add a commit that undoes it: revert. If no, you may rewrite freely: amend, reset, rebase.

Everything else in this section is detail hanging off those two.

Before you type anything

  1. Stop. More commands make the state harder to describe, not easier.
  2. git status — which branch, what is staged, is an operation in progress.
  3. git log --oneline -5 — what the history actually looks like.
  4. git reflog if something is missing.
  5. Then choose from the table.

Thirty seconds of reading beats any command typed from memory, and the two commands in steps 2 and 3 change nothing.

What cannot be undone

Four things, all of them work Git never recorded (lesson 12.9):

  • Uncommitted edits, after git restore or git reset --hard.
  • Untracked files, after git clean -fd.
  • Anything at all, in a repository folder you deleted.
  • A commit older than the reflog's expiry, once Git has collected it.

Everything else on this page is a lookup, not a loss.

How to do it

The three commands that precede every fix:

Terminal
$ git status
$ git log --oneline -5
$ git reflog

Then one command from the table. If the fix does not do what you expected, git reflog again: your attempt is in it too.

Common mistakes

  • Typing a remembered command before reading git status.
  • Reaching for reset on pushed work where revert is the answer.
  • Deleting the repository folder and re-cloning, which loses everything unpushed and is almost never necessary.
  • Not copying the folder before an experiment on work that matters.
  • Waiting. The reflog expires; recover today.

Try it yourself

Goal: rehearse the first thirty seconds.

  1. Put your practice repository into an odd state on purpose: start a merge that conflicts and leave it.
  2. Without looking at this page, run git status and write down what state you are in and what it suggests.
  3. Check your answer against the table above.
  4. Apply the fix and confirm with git log --oneline -3 and git status.
  5. Repeat with a different mistake: commit to main, or amend a pushed commit.

Expected result: you found the right command from git status alone, which is the skill this page exists to make unnecessary.

Show solution

Step 2 is the exercise; the table is the safety net. Git's status output names the operation in progress and lists the commands that end it, so most of this page is a restatement of something Git already told you. Reading that output is the habit that makes the rest of the section rarely needed.

Check yourself

1. Which two questions determine the right undo?
2. What should you run first when something has gone wrong?
3. Which of these is genuinely unrecoverable?

Key terms

Restore Revert Reflog Rewriting history