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.
The Problem
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.
Common mistakes developers make with this:
Using `--hard` when you meant `--soft`, discarding uncommitted work
Running `git reset` on a pushed commit and force-pushing, breaking teammates' history
Not knowing how to recover from an accidental `--hard` reset
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.
What is Reset: Undo Changes at Any Stage?
`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).
Step-by-Step Guide
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.
bash
git reset HEAD src/config.ts
# or with modern Git:
git restore --staged src/config.ts
This doesn't change the file contents — it just removes it from the staging area.
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.
bash
git reset --soft HEAD~1
# Your changes are still staged — just re-commit:
git commit -m "better message this time"
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.
bash
git reset HEAD~1
# equivalent to:
git reset --mixed HEAD~1
This is the safest way to undo a commit — you lose nothing, you just need to re-stage and re-commit.
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.
bash
git reset --hard HEAD~1
`--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.
See this workflow in Gitoryx. Right-click any commit in the graph to reset to it
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.
Everything in this tutorial is faster and clearer with a visual Git client. Gitoryx is free, runs natively on macOS, Windows, and Linux, and built for developers who want to move fast without breaking things.