If you’ve ever typed git reset, hit enter, and then stared at your terminal wondering whether you just fixed your mistake or made a much worse one, you’re not alone. Most explanations of --soft, --mixed, and --hard just show you a table and move on — without ever explaining what those three modes are actually operating on. Once you understand the three places Git keeps your work, the differences stop being something you memorize and start being something you just know.
Quick answer
git reset always moves where your branch (HEAD) points. What changes is how much of your staging area and working directory get pulled along with it: --soft touches nothing else, --mixed (the default) resets staging but leaves your files alone, and --hard resets everything — including overwriting your actual files.
The 3 Places Git Keeps Your Work
Every git reset mode is really just answering one question: how far back do we roll each of these three areas?
| Area | What it is | Where you see it |
|---|---|---|
| Working Directory | The actual files on your disk — what’s open in your editor right now. | git status under “Changes not staged” |
| Staging Area (Index) | A snapshot of what will go into your next commit, built with git add. | git status under “Changes to be committed” |
| Commit History (HEAD) | The permanent record of commits your branch pointer is currently sitting on. | git log |
Three separate areas, three separate things that can be “reset.” That’s the whole trick.
Try It Yourself: Git Reset Visualizer
Scenario: you made a bad commit and want to undo it
Commit History
Staging Area
Working Directory
What Each Reset Mode Actually Does
git reset –soft
Moves HEAD (and your branch pointer) to the target commit. That’s it. The staging area and working directory are left completely untouched — so all the changes from the commit(s) you just “undid” are sitting there, fully staged and ready to be committed again.
- Use it when: you want to squash the last few commits into one, or you committed too early and just want another shot at writing the commit.
- Nothing is lost. This is the safest of the three.
git reset --soft HEAD~1
# your changes are now staged, ready to re-commit
git reset –mixed (the default)
Moves HEAD, and also resets the staging area to match the target commit. Your working directory files are left alone — so your edits are still there, just no longer staged. This is what runs when you type git reset with no flag at all.
- Use it when: you staged something with
git addby mistake, or you want to “unstage everything and start the staging process over” without losing any edits. - Nothing is lost — your files are unchanged, just unstaged.
git reset HEAD~1
# same as: git reset --mixed HEAD~1
git reset –hard
Moves HEAD, resets the staging area, and overwrites your working directory files to match the target commit. Any uncommitted work — staged or not — is gone from your working copy.
This one can destroy uncommitted work
There’s no confirmation prompt. If you have edits that were never committed anywhere, --hard deletes them from your files immediately. Always run git status first, and consider git stash if you’re not 100% sure.
git reset --hard HEAD~1
# working directory now exactly matches the target commit
Quick Comparison Table
| Mode | Moves HEAD | Resets Staging Area | Resets Working Directory | Risk |
|---|---|---|---|---|
--soft | Yes | No | No | Safe |
--mixed (default) | Yes | Yes | No | Safe |
--hard | Yes | Yes | Yes | Destructive |
When to Use Each One
- Squashing your last 3 commits into 1:
git reset --soft HEAD~3, then commit once. - You ran
git add .by accident:git reset(mixed) unstages everything, keeps your edits. - You want to completely throw away a broken local experiment:
git reset --hard HEAD~1— only if nothing in there is worth keeping. - You want to undo a merge that hasn’t been pushed:
git reset --hardto the commit before the merge. - You already pushed the commit to a shared branch: don’t reset — use
git revertinstead (see below).
“I Ran git reset –hard and Lost My Work” — Recovery Steps
Before you panic: Git rarely deletes commit data immediately. Even after a hard reset, the commit you reset away from usually still exists internally until Git’s garbage collector eventually cleans it up (typically 30+ days later by default). Here’s how to get it back:
- Run
git reflog— this shows a log of every place HEAD has pointed to recently, including the commit you just reset away from. - Find the commit hash from before your reset (look for the entry just above your
resetaction in the list). - Run
git reset --hardto move your branch back to it, orgit checkoutif you just want to inspect it first. - If you only need one file back rather than the whole commit, use
git checkoutinstead.-- path/to/file
What reflog can’t save
Reflog only helps with committed work. If your files were never staged or committed at all, there’s no Git record of them — this is why git stash before a risky reset is worth the five seconds it takes.
git reset vs git revert vs git checkout
These three get lumped together constantly, but they solve different problems:
| Command | What it does | Rewrites history? | Safe on shared branches? |
|---|---|---|---|
git reset | Moves your branch pointer backward, optionally changing staged/working files | Yes | No |
git revert | Creates a new commit that undoes a previous one | No | Yes |
git checkout / git switch | Moves you to a different commit or branch to look around, without changing branch history | No | Yes |
The rule of thumb: if the commit has already been pushed and someone else might have pulled it, use revert. If it’s still local and only yours, reset is fine.
FAQ
Does git reset delete files?
Only git reset --hard changes your actual files. --soft and --mixed never touch your working directory.
Can I undo a git reset –hard?
Usually yes, as long as the work was committed at some point — use git reflog to find and restore the lost commit. Uncommitted, unstaged work generally cannot be recovered.
What’s the default git reset mode?
Running git reset with no flag is the same as git reset --mixed.
Is it safe to use git reset on a branch others are working on?
No. Resetting rewrites your branch’s history, which causes conflicts for anyone who already pulled the commits you removed. Use git revert for shared or pushed branches instead.
Does git reset affect other branches?
No — it only moves the branch you currently have checked out. Other branches are unaffected.

