Choose between git reset --soft, --mixed, and --hard
Understand which reset mode changes HEAD, the index, and the working tree, then choose how to keep or discard a local commit’s changes.
For the commit-moving form of git reset, all three modes move the current branch to the selected commit. --soft leaves the index and working tree alone; --mixed resets the index; --hard resets both the index and tracked working-tree contents.
| Mode | Branch tip | Index | Working tree |
|---|---|---|---|
--soft |
Moves to target | Unchanged | Unchanged |
--mixed (default) |
Moves to target | Matches target | Unchanged |
--hard |
Moves to target | Matches target | Tracked paths match target |
In detached HEAD, the operation moves HEAD without moving a branch. Path-based reset is a different form: it can update selected index entries without moving HEAD.
Undo a local commit and keep its work
Suppose the history is A--B--C, with a clean checkout at C. To move back to B while leaving the changes from C staged:
git reset --soft HEAD~1
git diff --cached
git commit -m "Describe the revised change"
The clean-checkout assumption matters. Any staged or unstaged work already present remains in its existing location under --soft; the command does not isolate the last commit's patch for you.
To split the last commit into smaller pieces, use mixed reset:
git reset HEAD~1
git add -p
git commit -m "First part of the change"
Continue staging and committing the remaining work. New files may need explicit staging before patch selection. The parent expression requires an existing parent, so it cannot remove a repository's only root commit this way.
Discard the tracked changes
git reset --hard HEAD~1
This discards current staged and unstaged changes in the affected tracked paths. It can also delete untracked paths that obstruct writing tracked files, though unrelated untracked files are not generally cleaned. Save needed work first.
The old commit may remain recoverable through a reflog or another ref. That does not mean arbitrary unstaged edits have been saved. If recovery matters, create a backup branch and save uncommitted work before the reset.
FAQ
What does plain git reset do?
With no target or paths, it performs a mixed reset to HEAD: the index matches the current commit while working-tree edits remain. It does not move the branch to an earlier commit.
Can I name an older commit directly?
Yes: git reset --soft COMMIT or another selected mode. Inspect the commit first and replace COMMIT with its real ID or ref.
When should I use revert instead?
Use git revert when you want a new commit that reverses an earlier change while retaining shared history. Reset is useful for local history editing; publishing a reset branch that rewinds shared history requires explicit coordination and a non-fast-forward update.
See git-reset, git-reflog, and git-revert.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan