Git Restore
git restore is a modern Git command (introduced in Git 2.23) that provides a clear way to restore files in your working tree and staging area. It's the recommended alternative to git checkout and git reset for file operations.
Why Git Restore?
Before Git 2.23, git checkout was used for:
- Switching branches
- Restoring files
- Creating branches
This was confusing! Git 2.23 introduced:
git switch- for switching/creating branchesgit restore- for restoring files
Basic Restore Commands
Discard Changes in Working Directory
Restore file to last committed state:
git restore <file>Example:
# Discard changes in file.txt
git restore file.txt
# Discard changes in multiple files
git restore file1.txt file2.txt
# Discard all changes
git restore .⚠️ Warning: This permanently discards uncommitted changes!
Before and After
# Before
$ git status
Changes not staged for commit:
modified: file.txt
# Restore
$ git restore file.txt
# After
$ git status
nothing to commit, working tree cleanUnstaging Files
Unstage Staged Changes
git restore --staged <file>This moves changes from staging area back to working directory without losing changes.
Example:
# Stage a file
$ git add file.txt
# Unstage it
$ git restore --staged file.txt
# Changes still in working directory
$ git status
Changes not staged for commit:
modified: file.txtUnstage All Files
# Unstage everything
git restore --staged .Unstage and Discard
# Unstage file
git restore --staged file.txt
# Then discard changes
git restore file.txt
# Or do both at once
git restore --staged --worktree file.txt
# or shorthand
git restore -SW file.txtAdvanced Restore Options
Restore from Specific Commit
# Restore file from specific commit
git restore --source=<commit> <file>
# Shorthand
git restore -s <commit> <file>Example:
# Restore from previous commit
git restore --source=HEAD~1 file.txt
# Restore from specific commit
git restore --source=abc123 file.txt
# Restore from different branch
git restore --source=main file.txtRestore from Stash
# Restore file from stash
git restore --source=stash@{0} file.txtRestore Specific Paths
# Restore entire directory
git restore src/
# Restore by pattern
git restore '*.js'
# Restore all files with extension
git restore **/*.cssWorking Tree and Staging Area
Working Tree Operations
# Restore working tree (default)
git restore --worktree <file>
# or shorthand
git restore -W <file>
# Same as
git restore <file>Staging Area Operations
# Restore staging area only
git restore --staged <file>
# or shorthand
git restore -S <file>Both Working Tree and Staging
# Restore both
git restore --staged --worktree <file>
# or shorthand
git restore -SW <file>
# This completely reverts file to last commitInteractive Restore
Patch Mode
# Interactively restore hunks
git restore --patch <file>
# or
git restore -p <file>This lets you selectively discard changes chunk by chunk.
Example:
$ git restore -p file.txt
diff --git a/file.txt b/file.txt
index 1234567..abcdefg 100644
--- a/file.txt
+++ b/file.txt
@@ -1,3 +1,4 @@
Line 1
+Line 2 (added)
Line 3
Discard this hunk from worktree [y,n,q,a,d,e,?]?Options:
y- discard this hunkn- keep this hunkq- quita- discard this and all remainingd- keep this and all remaininge- manually edit?- help
Patch Unstaging
# Interactively unstage hunks
git restore --staged --patch <file>
# or
git restore -Sp <file>Common Workflows
Workflow 1: Undo Unwanted Changes
# Made mistake, discard changes
git restore file.txt
# Or discard all changes
git restore .Workflow 2: Unstage Files
# Added too much
git add .
# Unstage specific file
git restore --staged unwanted-file.txt
# Commit only what you want
git commit -m "Focused commit"Workflow 3: Get File from Another Branch
# Get version of file from main branch
git restore --source=main config.js
# Keep your current changes in other filesWorkflow 4: Restore Deleted File
# Accidentally deleted file
rm important.txt
# Restore it
git restore important.txtWorkflow 5: Partial File Restore
# Some changes are good, some bad
git restore -p file.txt
# Selectively discard bad changesRestore vs Other Commands
Restore vs Checkout
Old way (git checkout):
git checkout -- file.txt
git checkout HEAD file.txtNew way (git restore):
git restore file.txt
git restore --source=HEAD file.txtRestore vs Reset
git reset:
- Moves branch pointer
- Can change commits
- More powerful, more dangerous
git restore:
- Only affects files
- Doesn't touch commits
- Safer for file operations
When to Use Each
Use git restore when:
- Discarding file changes
- Unstaging files
- Getting file from different commit
- Working with files only
Use git reset when:
- Moving branch pointer
- Undoing commits
- Changing commit history
Use git checkout (old) when:
- Switching branches (use
git switchinstead) - Creating branches (use
git switch -cinstead)
Examples by Scenario
Scenario 1: Discard All Changes
# Discard all unstaged changes
git restore .Scenario 2: Unstage Everything
# Unstage all staged files
git restore --staged .Scenario 3: Completely Revert File
# Revert file completely (staged + working)
git restore -SW file.txtScenario 4: Get File from Last Commit
# Restore file from HEAD
git restore --source=HEAD file.txtScenario 5: Get File from Previous Commit
# Restore from 3 commits ago
git restore --source=HEAD~3 file.txtScenario 6: Undo Git Add
# Staged file by mistake
git add secret.env
# Unstage it
git restore --staged secret.envScenario 7: Restore Directory
# Discard changes in entire directory
git restore src/Scenario 8: Restore Multiple Files
# Restore specific files
git restore file1.txt file2.js style.cssSafety and Recovery
Check Before Restoring
# See what will be discarded
git diff file.txt
# Then restore
git restore file.txtCan't Undo Restore!
⚠️ Important: git restore discards changes permanently. They cannot be recovered.
Best practice:
# Not sure? Create temporary commit first
git stash
# Or create temp branch
git stash branch temp-safetyRecover After Accidental Restore
If you restored by mistake:
- Check reflog (for committed changes):
git reflog- Check stash (if you stashed):
git stash list
git stash pop- IDE recovery (some IDEs have local history):
- VSCode: Local History extension
- IntelliJ: Local History built-in
- Vim: undo files
Unfortunately, unstaged changes cannot be recovered after restore!
Best Practices
1. Review Before Restoring
# See what you're about to lose
git diff file.txt
# Then restore
git restore file.txt2. Use Patch Mode for Precision
# Selective restoration
git restore -p file.txt3. Stash If Unsure
# Not sure if you need changes?
git stash
# Work on something else
# Decide later
git stash pop # or git stash drop4. Commit Often
# Commit frequently to avoid losing work
git add .
git commit -m "WIP: work in progress"
# Amend later if needed
git commit --amend5. Use Descriptive Sources
# Be explicit about source
git restore --source=main file.txt
# Not just
git restore file.txtConfiguration
Set Restore Defaults
# No special configuration needed
# git restore works out of the boxAliases for Common Operations
# Discard changes
git config --global alias.discard 'restore'
# Unstage
git config --global alias.unstage 'restore --staged'
# Complete revert
git config --global alias.revert-file 'restore -SW'Troubleshooting
Restore Doesn't Work
$ git restore file.txt
error: pathspec 'file.txt' did not match any filesSolution:
- Check file exists
- Check spelling
- Check current directory
- File might be untracked (use
git clean)
Can't Restore Untracked File
$ git restore new-file.txt
error: pathspec 'new-file.txt' did not match any file(s) known to gitSolution:
git restoreonly works on tracked files- For untracked files, just delete them:
rm new-file.txt - Or use:
git clean -f
Restore from Non-Existent Commit
$ git restore --source=wrong-commit file.txt
fatal: Invalid object name 'wrong-commit'Solution:
- Check commit exists:
git log - Use correct commit SHA
- Use HEAD~n for relative references
Summary
Git restore is essential for:
- ✅ Discarding unwanted changes
- ✅ Unstaging files
- ✅ Getting files from other commits
- ✅ Cleaning up working directory
- ✅ Managing staged/unstaged states
Key Commands:
git restore <file>- Discard changesgit restore --staged <file>- Unstagegit restore -SW <file>- Complete revertgit restore --source=<commit> <file>- Get from commitgit restore -p <file>- Interactive restore
Key Takeaways:
- Modern alternative to
git checkoutfor files - Clearer purpose than
git resetfor files - Cannot recover discarded unstaged changes
- Always review before restoring
- Use patch mode for precision
See Also
- Git Reset - Reset commits and branches
- Git Checkout - Switch branches (deprecated for files)
- Git Stash - Temporarily save changes
- Git Diff - View changes
- Git Add - Stage changes
- Git Status - Check repository status