By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
git restore
git reset
git revert
git clean
A Hyper-Practical, Zero-Fluff Study Guide
You’re working on a feature branch, and you accidentally: - Overwrite a critical config file (config.yml) with a bad merge.- Commit sensitive data (API keys, passwords) and push it to main.- Delete a directory full of untracked test files you thought were backed up.- Break the build with a bad commit, and now CI/CD is failing for the whole team.
config.yml
main
Git’s undo tools (restore, reset, revert, clean) are your time machine, eraser, and safety net—but they’re also dangerous if misused. In production: - git reset --hard can permanently delete uncommitted work (no recovery).- git revert is the only safe way to undo commits in shared branches (like main).- git clean -fd can wipe untracked files (including backups, logs, or local configs).
restore
reset
revert
clean
git reset --hard
git clean -fd
Real-world scenario:You’re a DevOps engineer deploying a Kubernetes cluster. A teammate merges a bad Helm chart into main, breaking deployments. You need to: 1. Undo the bad commit without rewriting history (since others have pulled it).2. Restore a deleted values.yaml file that wasn’t committed.3. Clean up leftover .tmp files cluttering the repo.
values.yaml
.tmp
This guide will teach you exactly which tool to use—and when to avoid them.
git checkout -- <file>
HEAD
--soft
--mixed
--hard
master
-n
-fd
.git
git checkout <commit-hash>
git checkout -b new-branch
reset --hard
merge
git reset ORIG_HEAD
git add
git commit
git status
clean -fd
Scenario: You modified app.js but haven’t staged/committed it. The changes are bad—discard them.
app.js
Check the damage: bash git status Output: Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: app.js
bash git status
Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: app.js
Discard changes in app.js: bash git restore app.js
bash git restore app.js
Alternative (older Git versions): bash git checkout -- app.js
bash git checkout -- app.js
Verify: bash git status Output should show no changes.
git restore --staged
Scenario: You accidentally staged secrets.txt (contains API keys). Unstage it without discarding changes.
secrets.txt
Check status: bash git status Output: Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: secrets.txt
Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: secrets.txt
Unstage secrets.txt: bash git restore --staged secrets.txt
bash git restore --staged secrets.txt
Alternative: bash git reset HEAD secrets.txt
bash git reset HEAD secrets.txt
Verify: bash git status Output should show secrets.txt as "untracked."
Scenario: You committed a buggy change to your local branch (feature/login). Undo it.
feature/login
Check commit history: bash git log --oneline Output: abc1234 (HEAD -> feature/login) Fix login bug def5678 Add login form
bash git log --oneline
abc1234 (HEAD -> feature/login) Fix login bug def5678 Add login form
Undo the last commit but keep changes staged: bash git reset --soft HEAD~1
bash git reset --soft HEAD~1
Verify: bash git status Output should show the changes from abc1234 as staged.
abc1234
Undo the last commit and unstage changes: bash git reset HEAD~1 (Same as git reset --mixed HEAD~1.)
bash git reset HEAD~1
git reset --mixed HEAD~1
Verify: bash git status Output should show the changes as unstaged.
⚠️ Danger! This permanently deletes uncommitted changes. bash git reset --hard HEAD~1
bash git reset --hard HEAD~1
Verify: bash git log --oneline Output should show def5678 as the latest commit.
def5678
Scenario: A bad commit (abc1234) was pushed to main. You need to undo it without rewriting history.
Check the commit to revert: bash git log --oneline Output: abc1234 (HEAD -> main) Add broken feature def5678 Fix login form
abc1234 (HEAD -> main) Add broken feature def5678 Fix login form
Revert the commit: bash git revert abc1234
bash git revert abc1234
Git opens an editor to confirm the revert message. Save and close.
Push the revert commit: bash git push origin main
bash git push origin main
Verify: bash git log --oneline Output should show a new commit (e.g., 123defg Revert "Add broken feature").
123defg Revert "Add broken feature"
Scenario: Your repo is cluttered with .tmp files and node_modules. Clean them up.
node_modules
Dry run first! (Shows what will be deleted): bash git clean -n Output: Would remove .tmp/ Would remove node_modules/
bash git clean -n
Would remove .tmp/ Would remove node_modules/
Delete untracked files and directories (force): bash git clean -fd
bash git clean -fd
Verify: bash git status Output should show a clean working directory.
git clean -n
.gitignore
git-secrets
git tag v1.0
git revert abc1234 -m "Revert broken login API"
develop
bash git reflog git reset --hard HEAD@{1} # Restore to previous state
git fsck
.env
-m
git revert -m 1 <commit>
git restore <file>
--soft/--mixed/--hard
git restore --staged secrets.txt
❌ git clean -fd (deletes untracked files)
"A bad commit was pushed to main. How do you undo it safely?"
git revert <commit>
git reset --hard HEAD~1
❌ git checkout -- <file> (only works for unstaged changes)
"You want to undo the last commit but keep the changes staged. Which command?"
git reset --soft HEAD~1
git reset HEAD~1
git revert HEAD
git reset --soft
You’re working on a branch feature/payment. You: 1. Modified payment.js (unstaged).2. Staged config.yml (but it’s wrong).3. Committed a buggy change (git commit -m "WIP").4. Created a .tmp directory with test files.
feature/payment
payment.js
git commit -m "WIP"
Your tasks:1. Discard the unstaged changes in payment.js.2. Unstage config.yml without losing changes.3. Undo the last commit but keep the changes unstaged.4. Delete the .tmp directory.
Solution:
# 1. Discard unstaged changes in payment.js git restore payment.js # 2. Unstage config.yml git restore --staged config.yml # 3. Undo commit, keep changes unstaged git reset HEAD~1 # 4. Delete .tmp directory git clean -fd
Why it works:- restore targets working dir/staging area.- reset HEAD~1 (default --mixed) unstages changes.- clean -fd removes untracked files/dirs.
reset HEAD~1
git restore app.js
git restore --staged <file>
git revert abc1234
git reflog
Final Pro Tip:
"Git’s undo tools are like a chainsaw—powerful, but you’ll lose a limb if you’re not careful. Always git status before and after, and use git reflog as your safety net."
Now go break something (in a test repo) and fix it! ?
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.