Git Reset vs. Git Restore
git reset
-
Undo commits (keep changes staged):
git reset --soft HEAD~ # Move HEAD but keep changes staged git reset --soft <commit> # Move to specific commit, keep changes staged -
Unstage changes (keep changes in working directory):
git reset HEAD~ # Reset --mixed (default), move HEAD and unstage changes git reset <commit> # Reset --mixed, move to specific commit and unstage changes git reset HEAD <file> # Unstage a specific file -
Discard commits and changes (destructive):
git reset --hard HEAD~1 # Discard commits and changes permanently
git restore
-
Discard working directory changes:
git restore <file> # Revert file to its state in the last commit -
Unstage changes:
git restore --staged <file> # Move changes from staging area to working directory -
Restore a file from a specific commit:
git restore --source=<commit> <file> # Restore file from a specific commit
Key differences
| Command | Branch pointer | Staging area | Working directory |
|---|---|---|---|
git reset <commit> |
Moves | Resets (unstages) | Unchanged |
git reset --soft <commit> |
Moves | Unchanged | Unchanged |
git restore <file> |
Unchanged | Unchanged | Resets file |
git restore --staged <file> |
Unchanged | Resets (unstages) | Unchanged |
When to use?
-
git reset:- Move branch pointers or undo commits.
- Unstage changes (though
git restore --stagedis more intuitive).
-
git restore:- Discard changes in the working directory.
- Unstage changes (modern alternative to
git reset HEAD <file>).
Pro tips
- Recover from a hard reset:
Use
git reflogto find the lost commit and reset back:
git reflog
git reset --hard <hash>
- Combine
git resetandgit restore: Reset to a specific commit but keep changes in the working directory:
git reset <commit>
git restore .
- Avoid
--hardunless necessary: Use--softor--mixedto preserve changes.