What is the difference between git reset --soft, --mixed, and --hard?
Understand the difference between git reset --soft, --mixed, and --hard, how each affects HEAD, the index, and the working tree, with examples.
Expected Interview Answer
git reset moves the current branch pointer to a target commit; --soft moves only the branch and keeps changes staged, --mixed (the default) also resets the staging area but keeps changes in the working directory, and --hard resets branch, staging area, and working directory, discarding all changes.
All three rewind HEAD to the specified commit, but they differ in how far the reset reaches. --soft touches only HEAD, --mixed touches HEAD and the index, and --hard touches HEAD, the index, and the working tree. Because --hard permanently discards uncommitted work, it is the only destructive one; the others preserve your changes in different states.
- --soft lets you recommit or amend while keeping work staged
- --mixed unstages changes for reselecting what to commit
- --hard gives a completely clean rollback
- All three rewrite the branch pointer locally
- Understanding them prevents accidental data loss
AI Mentor Explanation
Think of undoing an over three ways. Soft: you cancel the runs on the board but keep the balls lined up ready to re-bowl. Mixed: you cancel the runs and put the balls back in the bowler's hand, undecided. Hard: you wipe the runs, take the balls away, and reset the pitch as if the over never happened. git reset's three modes rewind by different amounts, from bookkeeping-only to erasing everything.
Step-by-Step Explanation
Step 1
Pick a target commit
Choose where HEAD should move, such as HEAD~1 to undo the last commit or a specific SHA.
Step 2
Choose --soft to keep everything staged
git reset --soft HEAD~1 moves the branch back but leaves changes staged, ready to recommit or amend.
Step 3
Choose --mixed to unstage
git reset --mixed HEAD~1 (the default) also clears the index, so changes remain in the working tree but unstaged.
Step 4
Choose --hard to discard
git reset --hard HEAD~1 resets HEAD, index, and working tree, permanently discarding uncommitted changes.
Step 5
Verify state
Run git status and git log to confirm the branch pointer and working directory are where you expect.
What Interviewer Expects
- Knows reset moves the branch pointer plus optionally index and working tree
- Correctly maps each flag to HEAD, index, and working directory
- Identifies --mixed as the default
- Warns that --hard is destructive
- Mentions reflog as a recovery option for reset mistakes
Common Mistakes
- Confusing which flag keeps changes staged versus unstaged
- Thinking --soft discards changes
- Using --hard without realizing it destroys uncommitted work
- Confusing git reset with git revert on shared history
- Forgetting --mixed is the default when no flag is given
Best Answer (HR Friendly)
“All three rewind your project to an earlier point, but they differ in what they keep. --soft keeps your changes ready to recommit, --mixed keeps them but unstaged, and --hard throws them away completely for a clean slate.”
Code Example
# Move branch back one commit, keep changes STAGED
git reset --soft HEAD~1
# Default: move back, keep changes in working tree, UNSTAGED
git reset --mixed HEAD~1
git reset HEAD~1 # same thing, --mixed is default
# Move back and DISCARD all uncommitted changes
git reset --hard HEAD~1
# Recover a bad reset via the reflog
git reflog
git reset --hard HEAD@{1}Follow-up Questions
- What is the difference between git reset and git revert?
- How can you recover work after an accidental git reset --hard?
- Why is rewriting history with reset dangerous on shared branches?
- What does git reset with a path (git reset HEAD file) do?
- How does git reset differ from git checkout for undoing changes?
MCQ Practice
1. Which git reset mode keeps changes staged in the index?
git reset --soft moves only the branch pointer, leaving the index and working directory untouched, so changes stay staged.
2. What is the default mode when you run git reset without a flag?
--mixed is the default: it moves HEAD and resets the index but preserves changes in the working directory as unstaged edits.
3. Which mode permanently discards uncommitted working-directory changes?
git reset --hard resets HEAD, the index, and the working tree, discarding any uncommitted changes irreversibly (short of the reflog).
Flash Cards
git reset --soft does what? — Moves the branch pointer only; changes stay staged in the index.
git reset --mixed does what? — Default mode: moves HEAD and resets the index; changes remain in the working tree, unstaged.
git reset --hard does what? — Moves HEAD and resets both index and working tree, discarding all uncommitted changes.
How to recover a bad reset? — Use git reflog to find the previous HEAD and git reset --hard back to it.