Restoring files (git restore, git checkout —)
git restore (Git 2.23+) discards changes or unstages files at the file level, replacing the overloaded git checkout -- <file> with a clearer, safer verb.
Why it matters
The two most common “undo” needs are “throw away my edits to this file” and “unstage this file” — and for years both were spelled git checkout, the same word used to switch branches. git restore (and its sibling git switch) split those jobs into dedicated commands, removing a notorious footgun where a stray argument blew away work or detached HEAD.
How it works
git restore copies content from a source (default: the index) into a destination (default: the working tree). The flags choose source and destination.
| Goal | restore | old checkout |
|---|---|---|
| Discard unstaged edits to a file | git restore <f> | git checkout -- <f> |
| Unstage (keep edits) | git restore --staged <f> | git reset HEAD <f> |
| Discard staged and unstaged | git restore -SW <f> | git checkout HEAD -- <f> |
| Get a file from another commit | git restore -s <rev> <f> | git checkout <rev> -- <f> |
- Destinations —
--worktree/-W(default) hits your files;--staged/-Shits the index. Combine-SWto reset both to the source. - Source —
--source/-s <tree>pulls from any commit/tree; without it,-Sdefaults toHEADand-Wdefaults to the index. - Interactive/partial —
git restore -p <f>discards hunk-by-hunk, the inverse ofgit add -p. git checkout -- <f>still works and is identical togit restore -W; new scripts should preferrestorefor clarity.
Example
$ git restore config.yml # drop unstaged edits to one file
$ git restore --staged secret.env # unstage, but keep my edits
$ git restore -s HEAD~1 -- app.js # bring back yesterday's app.js into the tree
$ git restore . # discard ALL unstaged changes (no undo!)
Pitfalls
- Working-tree restore is unrecoverable — discarded unstaged edits were never committed, so reflog can’t bring them back. Confirm with
git difffirst. git restore .is silent and total — no prompt, no stash; it wipes every unstaged change in the path. Many peoplegit stashinstead as a safety net.--stagedalone keeps file edits — it only unstages; to also revert the file content you need-SW(or a secondgit restore <f>).- It won’t touch untracked files — restore only knows tracked content; brand-new files need git clean.