Undoing local Git commits you haven’t pushed (safely)

Made a few local commits and realized they aren’t quite right—and nothing’s been pushed yet? This guide shows exactly how to unwind safely. Choose to discard everything, keep your changes unstaged, or keep them staged for a clean recommit, with copy-pasteable git reset commands for each path. We also cover peeling back the last N commits, aborting merges/rebases, and using git reflog as a safety net. Quick checks (git log, git status, git diff) help you verify before and after.

Table of Contents

You made a few commits, realized they’re not quite right, and nothing has been pushed yet. Good news: you have several clean ways to unwind without breaking shared history. This guide shows each option, what it does, and exact commands.

TL;DR: Decide whether you want to discard the work, keep it unstaged, or keep it staged—then pick the matching reset mode below.


Quick safety net (recommended)

Before doing anything destructive, create a throwaway backup branch so you can recover with reflog or by checking out this branch.


Option A — Throw away local commits and changes

Use when: You want your local branch to exactly match the remote, losing all local commits and file changes.

Effect:

  • Local commits are discarded.
  • Working tree and index are reset to the remote branch.

Recovery: Possible via git reflog, but assume the work is gone.


Option B — Drop the commits, keep changes unstaged

Use when: You want to rework the commits or split them up before recommitting.

Effect:

  • Commits are removed.
  • All diffs land in your working directory as unstaged changes.

Option C — Drop the commits, keep changes staged

Use when: You want to immediately recommit in one or few commits.

Effect:

  • Commits are removed.
  • All diffs move to the staging area.

Option D — Just peel back the last N commits

Use when: You know how many commits you want to undo from HEAD and you may want to keep (or drop) the changes.

Replace N with the number of commits to remove, e.g., HEAD~2.


In-progress operations

If you’re mid‑operation, bail out cleanly first:

Then apply the appropriate reset option above.


Verify before and after

See the local commits that are ahead of the remote:

Check workspace status:

Show what’s staged vs. unstaged:


Common scenarios

“I committed to the wrong branch, nothing pushed.”

“I only want to drop the very last commit message (contents fine).”

“I need to surgically keep or drop parts of a commit.”


Safety notes

  • Prefer git revert <sha> for commits that have already been pushed and shared.
  • git reset --hard is destructive. Make a backup branch and confirm with git log and git status before running it.
  • git reflog can often rescue lost work:


Cheatsheet

  • Discard everything: git reset --hard origin/<branch>
  • Keep changes (unstaged): git reset origin/<branch>
  • Keep changes (staged): git reset --soft origin/<branch>
  • Undo last N commits: git reset [--soft|--hard] HEAD~N
  • Abort merge/rebase: git merge --abort / git rebase --abort
  • Inspect ahead-of-remote: git log --oneline origin/<branch>..HEAD

Have a twist on this scenario (worktrees, detached HEAD, or rebasing gone wild)? Drop a comment—we’ll add it to this guide.

Have a project or a problem?

Talk with a senior engineer for practical recommendations—no obligation.

Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts

Categories

Get a free consultation from Reliable Penguin

Submit the form—or for immediate service call 866-649-7984.