In the post Undoing Changes in Git: restore, reset, revert, we learned that Git provides multiple ways to undo changes: restore, reset, and revert.
In the post Undoing Changes with git restore, we practiced using git restore to undo changes that were not yet committed.
In this post, we will practice using git reset, which allows us to undo commits and move our repository back to an earlier state.
Unlike git restore, git reset can change commit history, so it should be used carefully.
Before We Begin
Run the commands in this guide inside a terminal and within a Git repository folder.
- Windows: Open Git Bash, PowerShell, or Windows Terminal
- macOS / Linux: Open the Terminal
1. When Do We Use git reset?
We use git reset when we want to undo commits that exist only in our local repository.
Typical scenarios include:
- We committed something by mistake.
- Our commit message is wrong and we want to redo the commit.
- We want to combine or rewrite recent commits.
- We want to move our branch back to a previous commit.
Important:
git resetmoves the branch pointer (HEAD) to a different commit.
Because it rewrites history, it is safe only for commits that have not been pushed to a shared repository.
2. Setting Up a Practice Repository
Create a repository for practice.
mkdir reset-demo
cd reset-demo
git init
Create a file:
echo "Version 1" > notes.txt
Commit it:
git add notes.txt
git commit -m "First commit"
Make another change:
echo "Version 2" >> notes.txt
git add notes.txt
git commit -m "Second commit"
Add one more change:
echo "Version 3" >> notes.txt
git add notes.txt
git commit -m "Third commit"
Now check the commit history:
git log --oneline
You should see something like:
a3c8f2c Third commit
b1d4e6a Second commit
c9f2d11 First commit
3. Understanding What git reset Changes
Git has three important areas:
Working Directory → Staging Area → Repository (commits)
Different types of git reset affect these areas differently.
| Reset Type | Working Directory | Staging Area | Commit History |
|---|---|---|---|
| soft | unchanged | unchanged | moved |
| mixed (default) | unchanged | cleared | moved |
| hard | overwritten | cleared | moved |
4. Scenario 1 — Soft Reset
A soft reset moves the branch back to an earlier commit but keeps all changes staged.
Run:
git reset --soft HEAD~1
Now check the status:
git status
You will see that the changes from the last commit are still staged.
This is useful when:
- You want to rewrite the last commit
- You want to combine commits
5. Scenario 2 — Mixed Reset (Default)
The mixed reset moves the branch back but keeps the changes in the working directory.
Run:
git reset HEAD~1
Check the status:
git status
Now the changes appear as modified but not staged.
This is useful when:
- You want to redo a commit
- You want to modify files before committing again
6. Scenario 3 — Hard Reset
A hard reset completely discards commits and file changes.
Run:
git reset --hard HEAD~1
Now check the history:
git log --oneline
The last commit will be gone.
Also check the file:
cat notes.txt
The file will match the earlier commit.
Important warning:
git reset --hardpermanently deletes uncommitted changes.
7. Resetting to a Specific Commit
First view the commit history:
git log --oneline
Copy a commit ID.
Then reset to that commit:
git reset --hard <commit-id>
Your repository will now match the state of that commit.
8. Visualizing git reset
Think of git reset as moving the branch pointer backward.
Before reset:Commit1 ← Commit2 ← Commit3 (HEAD)After reset:Commit1 ← Commit2 (HEAD)
The branch now points to an earlier commit.
9. Quick Command Reference
Soft reset:
git reset --soft HEAD~1
Mixed reset:
git reset HEAD~1
Hard reset:
git reset --hard HEAD~1
Reset to a specific commit:
git reset --hard <commit-id>
10. Summary
git reset is used to move a branch back to an earlier commit.
It is helpful when:
- fixing mistakes in recent commits
- rewriting local commit history
- reorganizing commits before pushing
Key takeaway:
- soft reset keeps changes staged
- mixed reset keeps changes but unstaged
- hard reset removes commits and file changes
Because it rewrites history, git reset should be used only for commits that have not been pushed to a shared repository.