Restore a single file to how it was in an older commit
How do I revert just one file to a previous version?
Short answer
git restore --source=<commit> -- <path> rewrites one file to its state at that commit and leaves everything else alone. The classic equivalent is git checkout <commit> -- <path>. Neither moves your branch or affects any other file.
git restore --source=HEAD~3 -- src/config.ts
Rewinds one file to how it looked three commits ago
Does this match your situation?
- One file was broken by a recent change but the rest of the commit was fine.
- You want to compare against or return to an older version of a single file.
- Reverting the whole commit would undo too much.
Step-by-step fix
Find the version you want
List the commits that touched the file and inspect the candidate before restoring, so you know exactly what you're getting.
step 1git log --oneline -- src/config.ts git show a1b2c3d:src/config.tsRestore the file
This overwrites your working copy of that one path with the version from the chosen commit. Nothing else in the tree changes and your branch does not move.
step 2git restore --source=a1b2c3d -- src/config.ts # classic equivalent (also stages it): git checkout a1b2c3d -- src/config.tsThis discards your current uncommitted changes to that file — stash first if you might want them.
Restore relative to now instead of a hash
For recent changes it's easier to count backwards than to look up a hash. HEAD~n means n commits ago.
step 3git restore --source=HEAD~1 -- src/config.ts # as of one commit ago git restore --source=HEAD~5 -- src/ # a whole directoryCheck the difference, then commit
Review what changed before committing, so an unintended rollback doesn't slip in alongside it.
step 4git diff git add src/config.ts git commit -m "Revert config to the working version from a1b2c3d"To undo one file from one specific commit
If you want to reverse a single commit's effect on a single file rather than jump to an old version, restore from that commit's parent.
step 5git restore --source=a1b2c3d^ -- src/config.ts
Why this works
Every commit stores a complete tree, so any individual path can be read out of any commit independently. Restoring a path is therefore a local file operation rather than a history operation: your branch pointer doesn't move, no commit is created or removed, and the change simply appears as an ordinary modification in git status. That's what makes it so much more surgical than git revert, which undoes an entire commit across every file it touched.
How to stop it happening again
- Keep commits focused so reverting one doesn't drag unrelated files along.
- Tag known-good states so 'the version that worked' has a name.
- Review with git diff --staged before committing.
Commands used in this guide
git restoreThrow away working-directory changes or unstage files (the modern, clearer replacement for checkout).
git checkoutThe old all-in-one: switch branches, restore files, or detach HEAD.
git showDisplay a single commit, tag or file-at-a-commit in full.
git logBrowse commit history with as much or as little detail as you want.
Still stuck?
Search the full command reference and every other rescue guide — there are 56 of them, covering everything from detached HEAD to force-push disasters.
Browse all guides →Frequently asked questions
How do I revert a single file to a previous commit?
git restore --source=<commit> -- path/to/file, or the classic git checkout <commit> -- path/to/file. Both overwrite just that file with its content at that commit, leaving your branch and every other file untouched.
What's the difference between restoring a file and git revert?
Restoring a file changes one path in your working directory and creates no commit by itself. git revert creates a new commit that undoes an entire earlier commit across every file it touched. Restore is surgical; revert is wholesale.
How do I see an old version of a file without changing anything?
git show <commit>:path/to/file prints the file's contents at that commit straight to the terminal. Redirect it to compare side by side: git show HEAD~3:src/config.ts > /tmp/old-config.ts.
Related rescue guides
A file was deleted months ago — how do I find and restore it?
git log --all --full-history -- "**/filename" finds every commit that ever touched the file, including the one that deleted it. Restore it from the commit before the deletion with git checkout <hash>^ -- <path>.
Read the fix →Rarely recoverable by GitHow do I throw away all my local changes in Git?
git restore . discards edits to tracked files and git clean -fd deletes untracked ones. Both are irreversible for anything that was never staged or committed, so run git stash first if there's any doubt — it takes a second and makes the whole operation undoable.
Read the fix →Always fixableHow do I undo a commit that's already on the remote?
On a shared branch, use git revert <hash> — it adds a new commit that reverses the change, so nobody else has to do anything. Rewriting with reset plus a force-push is only appropriate on a branch you're certain nobody else has pulled.
Read the fix →Always fixableHow do I undo the last commit but keep my work?
git reset --soft HEAD~1 removes the commit and leaves every change staged, ready to recommit. Use --mixed (the default) if you also want the changes unstaged, and only use --hard if you genuinely want the work destroyed. If the commit is already pushed, revert it instead of resetting.
Read the fix →