Last Updated: May 1, 2025
Reset Modes
| Mode | HEAD | Index (Staging) | Working Directory | Safe? |
|---|---|---|---|---|
| --soft | Moves | Unchanged | Unchanged | Very safe — changes stay staged |
| --mixed (default) | Moves | Reset to HEAD | Unchanged | Safe — changes become unstaged |
| --hard | Moves | Reset to HEAD | Reset to HEAD | Dangerous — all changes lost! |
| --merge | Moves | Resets merged files | Keeps unmerged | Safer than --hard |
| --keep | Moves | Unchanged | Reset files with changes | Aborts if local changes exist |
Practical Reset Commands
git reset HEAD~1Mixed: undo last commit, keep changes unstaged
git reset --soft HEAD~1Soft: undo last commit, keep changes staged
git reset --hard HEAD~1Hard: undo last commit AND discard all changes
git reset HEAD fileUnstage a specific file (keep changes)
git reset -- fileAlternative: unstage file (keep changes)
git reset --soft origin/mainUndo all local commits, keep work staged
git reset --hard origin/mainReset to remote state — discard ALL local work
git reset --soft HEAD~3 && git commitSquash last 3 commits into one
When to Use Each Mode
| Item | Description |
|---|---|
--soft | Undo commits but keep all changes staged — ready to re-commit |
--mixed | Undo commits, put changes back in working tree for re-staging |
--hard | Nuclear option — complete reset to a known state. Reflog is your backup |
HEAD~N | Reset back N commits; combine with mode flags |
File-Level Reset | git reset file or git restore --staged file to unstage |
Remote Reset | Reset local to match remote: git fetch && git reset --hard origin/main |
Squash Workflow | Reset --soft followed by a new commit = manual squash |
Recover After Reset | git reflog → find lost commit → git reset --hard HEAD@{n} |
Reset vs Other Commands
| Item | Description |
|---|---|
reset vs revert | Reset removes history; revert creates new undo commit (safer for shared branches) |
reset vs restore | git restore discards working changes; reset moves HEAD |
reset vs checkout | checkout switches branches; reset --hard with a file discards its changes |
reset vs clean | git clean removes untracked files; reset works on tracked files |
--merge vs --hard | --merge is safer — it won't delete unmerged changes |
Pro Tip: Think twice before `git reset --hard`. There's no undo except reflog. Prefer `--soft` or `--mixed` when you might need the changes back.