iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

git restore

`git restore` is the modern command for putting files back the way they were. It replaces the confusing overloads of `git checkout` for file-level operations. The two flags to know: `--worktree` (default, restores the working tree) and `--staged` (unstages changes). Combine them to throw away changes at either layer.

restore patterns: unstage, discard, time-travel a file

EXAMPLE
# 1) Unstage a file (keep the working-tree change)
git restore --staged path/to/file
# = the modern equivalent of:  git reset HEAD path/to/file

# 2) Throw away unstaged changes in the working tree
git restore path/to/file
# = the modern equivalent of:  git checkout -- path/to/file

# 3) Throw away EVERYTHING in the working tree
git restore .                     # all tracked changes — uncommitted edits gone

# 4) Discard staged AND working changes (full revert of a file to HEAD)
git restore --staged --worktree path/to/file

# 5) Restore a file to a specific commit (time-travel)
git restore --source=v1.2.3 -- path/to/file
git restore --source=HEAD~5 -- src/app.js

# 6) Restore from another branch (lift a file across without merging)
git restore --source=main -- src/config.ts

# 7) Restore an entire directory tree to a past state
git restore --source=HEAD~1 -- src/

# 8) Restore from the index (staged version) without touching the index
git restore --staged --worktree --source=HEAD -- path/to/file

# 9) Restore deleted files
git restore path/to/deleted.txt           # if deletion is unstaged
git restore --staged --worktree path/to/deleted.txt   # if delete is staged too

# 10) Interactive — pick hunks to restore (like 'git add -p' but reverse)
git restore -p path/to/file

# 11) Difference vs git reset
# - git reset moves the BRANCH POINTER (and optionally the index/worktree).
# - git restore touches FILES only. It never moves the branch.
# Use restore for file-level fixes; use reset for branch-level operations.

# 12) The mental model
# Working tree   <- restore [--source X] -- file
# Index (staged) <- restore --staged [--source X] -- file
# HEAD (branch)  <- reset

# 13) Decision tree
# 'Whoops, I staged the wrong file'  ->  git restore --staged FILE
# 'Whoops, I made changes I want gone' ->  git restore FILE
# 'Whoops, I want the old version'     ->  git restore --source=COMMIT FILE
# 'Whoops, I committed wrong'          ->  git revert / reset (not restore)

Why it matters

Default to `git restore --staged` over the legacy `git reset HEAD --` for unstaging. The intent reads cleanly in the diff log of your shell history and the file-vs-branch boundary is explicit — exactly the confusion the new commands were designed to fix.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
git restore file.txt              # discard unstaged changes
git restore --staged file.txt     # unstage
Try it Yourself »

Discussion

Loading…