Git Reset, Revert, and Checkout — What's the Difference?
In this tutorial, you'll learn about Git Reset, Revert, and Checkout. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
What You'll Learn
Understand the three Git commands for undoing changes — reset, revert, checkout — and when to use each without losing work or breaking team history.
Why It Matters
Misusing these commands can destroy work or mess up shared history. Knowing the difference keeps you safe and productive.
The Big Picture
| Command | Scope | Effect | Safe for shared history? |
|---|---|---|---|
| checkout | File or branch | Switch branches or restore files | Yes (files only) |
| reset | Commit | Move branch pointer, optionally modify index/worktree | No (rewrites history) |
| revert | Commit | Create new commit that undoes a previous change | Yes |
Git Reset — Dangerous but Powerful
Reset moves the current branch pointer backward in history:
# BEFORE reset (HEAD → feature, pointing to C)
A---B---C (HEAD → feature)
# git reset --soft HEAD~1
A---B (HEAD → feature)
└── C (staged, ready to commit)
# git reset --mixed HEAD~1 (default)
A---B (HEAD → feature)
└── C (unstaged, changes kept)
# git reset --hard HEAD~1
A---B (HEAD → feature)
└── C (changes DISCARDED forever)
Three Levels
| Level | HEAD | Staging | Working Directory |
|---|---|---|---|
--soft |
Moves | Keeps | Keeps |
--mixed (default) |
Moves | Resets | Keeps |
--hard |
Moves | Resets | Resets |
Git Revert — Safe Undo
Revert creates a new commit that undoes an old commit:
# BEFORE
A---B---C (HEAD)
# git revert C
A---B---C---C' (HEAD)
└── C' undoes C's changes
# This is safe because we added, not removed, history
When to Use Revert
# Undo a specific commit from last week
git log --oneline
# a1b2c3 Add login feature <- want to undo this
# d4e5f6 Fix typo
# g7h8i9 Initial commit
git revert a1b2c3
# Opens editor for commit message
# Creates a new commit that reverses all changes from a1b2c3
# Undo last 3 commits
git revert HEAD~3..HEAD
# Undo a merge commit
git revert -m 1 <merge-commit-hash>
Git Checkout — Switch and Restore
Checkout has two distinct modes:
Switch Branches
git checkout feature # Switch to feature branch
git checkout -b new-branch # Create and switch
git checkout main # Back to main
Restore Files
# Restore a file to its last committed state
git checkout -- file.txt
# Restore a file from a specific commit
git checkout a1b2c3 -- file.txt
# Restore file from another branch
git checkout feature -- database.py
Note: In Git 2.23+, use git switch for branches and git restore for files — clearer separation.
Decision Tree
Need to undo a change?
├── Is the commit shared (pushed to remote)?
│ ├── YES → git revert (safe)
│ └── NO → git reset or git revert
│
├── Is the change in the working directory (uncommitted)?
│ ├── Discard completely → git restore file.txt
│ └── Keep for later → git stash
│
├── Is the change staged (git add)?
│ └── Unstage it → git restore --staged file.txt
│
└── Need to undo last commit (local only)?
├── Keep changes → git reset --soft HEAD~1
└── Discard changes → git reset --hard HEAD~1
Real-World Scenarios
# "I committed to the wrong branch"
git revert HEAD # Undo (safe since pushed)
git checkout correct-branch
git cherry-pick <revert-of-revert> # Move the changes
# "I want to discard my local changes"
git restore .
# "I want to go back 3 commits but keep the changes"
git reset --soft HEAD~3
# "I want to undo my last commit (haven't pushed)"
git reset --soft HEAD~1
# Changes are staged, ready to recommit properly
# "I want to permanently remove a file from history"
git filter-branch --tree-filter 'rm -f passwords.txt' HEAD
# ⚠️ This rewrites history — force push needed
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro