Back
GitoryxGitoryx

Git Reset: Undo Changes at Any Stage

git reset is one of Git's most powerful, and most misunderstood, commands. This guide explains the three modes (--soft, --mixed, --hard), when each is safe to use, and how to recover if you go too far.

Beginner10 min readUpdated

On this page

What is git reset?

git reset moves the current branch pointer (HEAD) to a different commit, optionally changing the staging area and working directory. The three modes are: --soft (moves HEAD only), --mixed (default, also clears the staging area), and --hard (also discards working directory changes).

Aspect--soft--hard
Moves HEADyesyes
Staging areakept as iscleared
Working directorykept as isall changes discarded

Why it matters

You committed too early, staged the wrong file, or want to throw away some changes entirely, but you're scared to touch git reset because you've heard it can destroy work.

git reset is one of the most useful undoing tools in Git. The key is understanding which of its three modes moves what: the commit pointer (HEAD), the staging area (index), and the working directory. Once you understand that, it stops being scary.

Where it usually goes wrong

  • Using --hard when you meant --soft, discarding uncommitted work
  • Running git reset on a pushed commit and force-pushing, breaking teammates' history
  • Confusing git reset <file> (unstage) with git reset HEAD~1 (undo commit)
  • Not knowing how to recover from an accidental --hard reset

Git reset, step by step

  1. Step 1: Unstage a file (reset the index for one file)

    The most common everyday use: you staged something by accident and want to unstage it without changing the file.

    Terminal
    git reset HEAD src/config.ts# or with modern Git:git restore --staged src/config.ts

    Tip: This doesn't change the file contents. It just removes it from the staging area.

  2. Step 2: Undo the last commit, keep changes staged (--soft)

    --soft moves HEAD back by one commit but leaves all changes staged. Useful when you want to rewrite the commit message or split the commit.

    Terminal
    git reset --soft HEAD~1# Your changes are still staged - just re-commit:git commit -m "better message this time"
  3. Step 3: Undo the last commit, keep changes unstaged (--mixed)

    --mixed (the default) moves HEAD back and unstages the changes. The files are still modified in your working directory.

    Terminal
    git reset HEAD~1# equivalent to:git reset --mixed HEAD~1

    Tip: This is the safest way to undo a commit: you lose nothing, you just need to re-stage and re-commit.

  4. Step 4: Undo the last commit AND discard all changes (--hard)

    --hard moves HEAD back and discards all changes in the staging area and working directory. The files are reverted to exactly the state they were in at the target commit.

    Terminal
    git reset --hard HEAD~1

    Careful: --hard permanently discards uncommitted changes. There is no undo, unless you have the original SHA and use git reflog to recover it. Use with extreme caution.

    In Gitoryx: Right-click any commit in the graph to reset to itHow it works
  5. Step 5: Reset to a specific commit

    Instead of HEAD~1, you can target any commit by its SHA.

    Terminal
    git log --oneline# a3f2c1d add login form# 9b1e4fa init projectgit reset --soft 9b1e4fa
  6. Step 6: Recover from an accidental --hard reset

    If you ran --hard by mistake, your commits are still in Git's reflog for 30 days. Find the SHA and reset back to it.

    Terminal
    git reflog# HEAD@{1}: reset: moving to HEAD~1# a3f2c1d HEAD@{2}: commit: add login form  ← this is what we lostgit reset --hard a3f2c1d

Mistakes to avoid with git reset

Using --hard instead of --soft or --mixed
Most of the time you want to undo a commit but keep the code. --hard throws the code away too.
Fix: Default to --soft or --mixed. Only use --hard when you're certain you want to discard the changes.
Resetting a pushed commit and force-pushing
This rewrites shared history. Teammates whose branches are based on the old commit will have a diverged history and will be forced to reconcile it.
Fix: Use git revert for commits already pushed to a shared branch. It creates a new commit that undoes the changes, without rewriting history.
Resetting too many commits back
Using HEAD~5 when you meant HEAD~1 undoes more history than intended.
Fix: Use git log --oneline to count commits carefully, or use the exact SHA instead of HEAD~N.

Git reset in Gitoryx

Gitoryx lets you right-click any commit in the graph and choose Reset to here (soft, mixed, or hard), with a clear description of what each mode will do before you confirm.

  • Right-click any commit in the graph to reset to it
  • Choose soft, mixed, or hard from a clear dropdown with descriptions
  • The reflog is accessible in Gitoryx to recover from accidental resets
  • Gitoryx warns you before a --hard reset that would discard changes

Free plan · no account required · macOS, Windows and Linux

Git reset: frequently asked questions

What is the difference between git reset and git revert?
git reset moves the branch pointer backwards, rewriting history. git revert creates a new commit that undoes a previous commit's changes, preserving history. Use reset for local commits; use revert for pushed commits.
Can I recover from a git reset --hard?
Yes, if you act quickly. Run git reflog to find the SHA of the commit you lost, then git reset --hard <sha> to restore it. Git keeps reflog entries for 30 days by default.
What does git reset HEAD~1 do?
It moves the current branch back by one commit (--mixed by default). The changes from that commit are kept in your working directory but are no longer staged.
How do I unstage a file without undoing a commit?
Run git reset HEAD <file> or git restore --staged <file> (Git 2.23+). This removes the file from the staging area while keeping your changes intact.
All Git tutorials →
Gitoryx

Stop fighting Git. Start shipping.

Download the fast, native Git client that developers actually enjoy using.

v1.1.0 · macOS 12+ (Apple Silicon or Intel) · Windows 10+ · Linux x86_64