- Readers who want to uncommit, unstage, or move back to an earlier point
Command Reference
git reset Tutorial
Explains how git reset moves HEAD, updates the index, and optionally overwrites the working tree through soft, mixed, and hard modes.
- A three-layer model of HEAD, index, and worktree
- A habit of creating a rescue branch first
- Using `--hard` and overwriting local file state
- Moving history before checking the sharing boundary
The short version
git reset moves the current reference and, depending on the mode, may also update the index and working tree.
The three layers to remember
- commit history
- staging area
- working tree
Understanding reset means understanding which layers are affected.
Use this diagram as a quick pre-flight check. The moment you move from the first two columns to --hard, you are no longer just rewriting history expression, you are allowing the working tree to be overwritten.
The three modes that matter most
--soft
Moves the reference only.
--mixed
Moves the reference and resets the index, while keeping working tree changes.
--hard
Moves the reference, resets the index, and overwrites working tree changes.
Re-reading reset through the three-layer model
Reset becomes much easier if you ask three questions:
- should HEAD / the current branch move
- should the index be reset
- should the working tree be overwritten
Three common use cases
Undo the last commit but keep the changes
git reset --soft HEAD~1
Unstage a file
git reset HEAD path/to/file
Move all the way back to a safe commit
git reset --hard <commit>
A safer operating order
Before a risky reset, a better sequence is:
git statusgit log --oneline --decorate -5git reflog- create a backup branch if needed
- only then run reset
If you still feel unsure about hard reset, compare the command you want with the figure above. If what you really want is “undo the commit but keep my file changes,” then --hard is probably not the right choice.
Common examples
git reset --soft HEAD~1
git reset HEAD path/to/file
git reset --hard <commit>
Safety note
Before destructive reset operations, check git status, inspect git reflog, or create a rescue branch first.
reset vs restore vs revert
reset: move references and optionally reset index / working treerestore: recover file content more directlyrevert: create a new commit that undoes an older one
If the history is already shared with others, revert is often safer than rewriting it with reset.
Why git reset HEAD <file> confuses people
It often looks like “restore the file,” but in practice its most common role is “unstage this file while keeping my working-tree edits.”
Extra caution cases
Be especially careful if:
- you are on a shared branch
- you are not sure whether some of the current work should survive
Another common misconception
Reset does not always permanently destroy commits right away. Often the obvious ref is gone before the underlying objects are actually unrecoverable.
What problem this command solves in a workflow
git reset directly affects history shape, ref position, or relationships between commits. The first decision is whether you are organizing private local history or touching history that is already shared with others.
Typical use cases
- Use
git resetwhen integrating branches, undoing changes, selecting commits, or reshaping a sequence of commits. - Put
git resetinside a “backup first, mutate second, verify last” flow so higher-risk history operations stay recoverable. - Use
git resetto understand ancestry, recovery paths, and commit causality during conflict resolution or post-incident analysis.
Diagram view
Special cases and boundaries
- The most expensive failure mode in history commands is rewriting or moving commits that other people already depend on.
- If the operation might affect team flow, run
git status,git log --oneline --graph, andgit reflogfirst so the recovery path is visible. - When in doubt, create a backup branch before continuing so you preserve an obvious way back.
- Any
--hardreset should trigger a pause to verify whether the working tree still contains important unbacked-up changes.
Try it yourself
This drill is really about watching HEAD, the index, and the working tree change independently.
git switch -c lab/reset-demo # make two commits # then edit a file and stage it with git addTry it
- Run `git reset --soft HEAD~1` and inspect `git status`.
- Repeat the experiment with `git reset --mixed HEAD~1`.
- Only in a disposable repo, try `git reset --hard HEAD~1` once and compare the result.
- `--soft` keeps staged and working-tree changes in place.
- `--mixed` moves staged changes back into the working tree.
- `--hard` realigns HEAD, index, and working tree to the target commit.
- If the real goal is “undo the commit but keep the changes,” `--hard` is usually the wrong choice.
- If the commits are already shared, evaluate `revert` before rewriting with reset.
- If you do not know the recovery path yet, inspect `git reflog` before continuing.