The Hook (The "Byte-Sized" Intro)
You broke one file in a codebase of 200. You don't need to reset the whole branch — just restore that one file. git restore is the scalpel to git reset's sledgehammer. Discard changes in one file, unstage one file, or pull a specific file from any commit in history — all without touching anything else.
📖 What is Restore Specific Paths?
git restore targets individual files or directories instead of the entire working tree. You can discard uncommitted changes, unstage files, or restore files from specific commits — all with surgical precision.
Conceptual Clarity
The restore operations:
| Goal | Command | What Changes |
|---|---|---|
| Discard working tree changes | git restore file.js | Working tree ← HEAD |
| Unstage a file | git restore --staged file.js | Staging ← HEAD (working tree unchanged) |
| Restore from a specific commit | git restore --source=abc123 file.js | Working tree ← commit abc123 |
| Discard all changes in a directory | git restore src/ | Restores everything under src/ |
| Unstage everything | git restore --staged . | Clears entire staging area |
restore vs reset vs checkout (legacy):
| Command | Scope | Modern? |
|---|---|---|
git restore <path> | File-level undo | ✅ Modern (Git 2.23+) |
git restore --staged <path> | Unstage files | ✅ Modern |
git checkout -- <path> | Same as restore (legacy) | ❌ Old syntax |
git reset HEAD <path> | Same as --staged (legacy) | ❌ Old syntax |
Real-Life Analogy
git restore is like the undo button in a text editor — but for specific files. You can undo changes to one paragraph without reverting the entire document. And with --source, you can pull a paragraph from a previous version of the document.
Visual Architecture
Why It Matters
- Precision: Fix one file without affecting the rest of the codebase.
- Modern syntax:
git restorereplaced the confusing dual-purposegit checkoutfor files. - Non-destructive unstaging:
--stagedremoves from staging without discarding your edits. - History access:
--sourcelets you grab any file from any commit.
Code
# ─── Discard changes to a specific file ───
git restore src/app.js
# src/app.js is now back to HEAD version
# ⚠️ Working tree changes are permanently lost!
# ─── Unstage a file (keep edits in working tree) ───
git restore --staged src/app.js
# File is unstaged, but your changes are still there
# ─── Restore from a specific commit ───
git restore --source=abc1234 src/app.js
# Gets the version of app.js from commit abc1234
# The file appears as a modification in your working tree
# ─── Restore from a branch ───
git restore --source=main src/config.js
# Gets config.js as it appears on main branch
# ─── Discard all changes in a directory ───
git restore src/components/
# ─── Unstage everything ───
git restore --staged .
# ─── Interactive restore (choose hunks) ───
git restore -p src/app.js
# Choose which changes to discard, keep othersKey Takeaways
git restore filediscards uncommitted changes to that file (⚠️ permanent!).git restore --staged fileunstages without losing working tree edits.git restore --source=SHA fileretrieves any file from any commit in history.- Use
git restore -pfor interactive, hunk-by-hunk restoration.
Interview Prep
-
Q: What is the difference between
git restoreandgit checkout -- file? A: They do the same thing — both discard working tree changes for a file.git restore(Git 2.23+) is the modern replacement that separates file restoration from branch switching.git checkoutwas confusing because it did both. -
Q: How do you unstage a file without losing your changes? A:
git restore --staged <file>. This moves the file from the staging area back to the working tree as unstaged, but preserves all your edits. -
Q: How do you get a specific file from a previous commit? A:
git restore --source=<commit-sha> <file>. This replaces the file in your working tree with the version from that commit. The change appears as a modification you can review before committing.