The Hook (The "Byte-Sized" Intro)
You just spent 20 minutes going down the wrong path. The function is worse than when you started. You want to scream "undo!" — and git restore is exactly that. It discards your changes and brings back the last committed version. No history rewriting, no drama, just a clean "never mind."
📖 What is git restore?
git restore discards changes in the working tree or unstages files from the staging area. It was introduced in Git 2.23 as a clearer alternative to git checkout for file-level operations. It does not modify commit history.
Conceptual Clarity
git restore operates in two modes:
| Mode | Command | What It Does |
|---|---|---|
| Discard changes | git restore <file> | Overwrites the working tree file with the staged version (or last commit if not staged) |
| Unstage | git restore --staged <file> | Removes the file from the staging area, keeping working tree changes intact |
Important distinctions:
git restore <file>is destructive — it throws away working tree changes permanentlygit restore --staged <file>is safe — it moves changes from staging back to working tree (nothing is lost)- You can restore from any commit using
--source:git restore --source=HEAD~3 file.txt git restorereplaced the confusing dual-purposegit checkout -- <file>
Real-Life Analogy
git restore file.txt= Throwing away your pencil sketch and starting fresh from the last traced outlinegit restore --staged file.txt= Taking an item out of your shopping cart and putting it back on the shelf (the item still exists — you just decided not to buy it yet)
Visual Architecture
Why It Matters
- Quick recovery: Discard a bad experiment in one command without affecting anything else.
- Undo staging mistakes: Accidentally staged something? Unstage it without losing the changes.
- Targeted undo: Restore one specific file without touching the rest of your work.
- Safer than checkout:
git restorehas a single clear purpose, unlike the overloadedgit checkout.
Code
# ─── Scenario 1: Discard working tree changes ───
# You edited app.js but want to go back to the last committed version
git restore app.js
# ⚠️ Working tree changes are GONE — this is irreversible!
# ─── Scenario 2: Unstage a file ───
# You accidentally staged debug.log
git add debug.log
git restore --staged debug.log
# debug.log is back in the working tree (changes preserved, just unstaged)
# ─── Scenario 3: Discard ALL working tree changes ───
git restore .
# ⚠️ Every modified tracked file reverts to the staging/committed version
# ─── Scenario 4: Restore a file from a specific commit ───
git restore --source=HEAD~3 app.js
# Brings back the version of app.js from 3 commits ago
# ─── Scenario 5: Restore from a specific branch ───
git restore --source=main config.json
# Gets the version of config.json from the main branch
# ─── Scenario 6: Unstage everything ───
git restore --staged .
# ─── Before vs after comparison ───
git status # Check what's modified
git diff app.js # See what changed
git restore app.js # Discard changes
git status # Confirm it's cleangit restore vs Legacy Commands
| Task | Modern (Git 2.23+) | Legacy |
|---|---|---|
| Discard working tree changes | git restore file.txt | git checkout -- file.txt |
| Unstage a file | git restore --staged file.txt | git reset HEAD file.txt |
| Restore from a commit | git restore --source=abc123 file.txt | git checkout abc123 -- file.txt |
Use
git restorefor clarity. The legacy commands still work but are harder to remember.
Key Takeaways
git restore <file>discards working tree changes — irreversible.git restore --staged <file>unstages changes — safe (changes stay in working tree).- Use
--sourceto restore a file from any commit or branch. git restorereplaced the confusinggit checkout -- <file>syntax in Git 2.23.
Interview Prep
-
Q: What is the difference between
git restoreandgit restore --staged? A:git restore <file>discards changes in the working tree (irreversible).git restore --staged <file>removes the file from the staging area but preserves the changes in the working tree (safe). -
Q: How do you restore a file from 3 commits ago? A: Use
git restore --source=HEAD~3 <file>. This replaces the working tree copy with the version from that commit without modifying history. -
Q: Why was
git restoreintroduced whengit checkoutalready existed? A:git checkoutwas overloaded — it handled both branch switching and file restoration, which confused beginners. Git 2.23 split it intogit switch(for branches) andgit restore(for files) for clarity.