Skip to content
masterclass Buddy

Git · Command

git restore

git restore puts selected paths back to the content held in a restore source. It can undo working-tree edits, unstage changes, or bring back a file as it was in an older commit.

Last updated

How it works

The command copies content from a source to a location. The location is the working tree (-W/--worktree, used when you give neither flag), the index (-S/--staged), or both. If you don't pass --source, the source is the index when only the working tree is restored and HEAD when --staged is given. --source=<tree> lets you pick any commit, branch or tag instead. Pathspecs choose which files are affected. By default it runs in no-overlay mode, so the result matches the source exactly, and that can mean deleting files.

Syntax

git restore [<options>] [--source=<tree>] [--staged] [--worktree] [--] <pathspec>…

Parameters

NameTypeDescription
-s <tree>, --source=<tree>tree-ishTree to take content from. Defaults to HEAD when --staged is given, otherwise the index.
-W, --worktree / -S, --stagedflagWhere to restore: the working tree (the default), the index, or both.
-p, --patchflagChoose hunks interactively.
--ours / --theirsflagFor unmerged paths, take stage #2 or stage #3 from the index.
-m, --merge / --conflict=<style>flag / merge|diff3|zdiff3Recreate the conflicted merge for unmerged paths, optionally with a specific conflict style.
--overlay / --no-overlayflagWhether tracked files missing from the source are removed (no-overlay is the default).
--pathspec-from-file=<file>, --pathspec-file-nulfileRead pathspecs from a file or from stdin (-), optionally separated by NUL characters.
<pathspec>...pathspecLimits which paths are affected.

Key points

  • You usually name the source by a commit, a branch or a tag, for example --source master~2 to take a file from two commits back.
  • Writing A...B as the source means the merge base of A and B, provided there is only one. You may leave out one side, and it then defaults to HEAD.
  • --patch lets you choose, hunk by hunk, which differences between the source and the target get restored. It works the same way as the interactive mode of git add.
  • During a conflict, --ours and --theirs fill the working-tree file from stage #2 or stage #3 of the index.
  • --merge rebuilds the conflict markers in a file you had already edited. --conflict=<style> does the same but lets you pick merge, diff3 or zdiff3.
  • --ignore-unmerged stops the command from aborting when there are conflicted entries. Those paths are simply skipped.
  • Quote glob patterns such as '*.c' so Git matches them against the index rather than the shell expanding them. This way, deleted files are matched too.

Common mistakes

  • --ours, --theirs and --merge work only when restoring from the index. They can't be combined with --source.
  • No-overlay mode is the default, so tracked files that don't exist in the source are deleted. Use --overlay if you want to keep them.
  • --recurse-submodules resets the submodule to the commit the superproject recorded and throws away local changes in it.
  • -U with no number is not an error. Git silently treats it as -p.

Example: Unstage, discard and recover files

set -e
cd "$(mktemp -d)" && git init -q demo && cd demo
git config user.email you@example.com && git config user.name You
echo v1 > app.txt && git add app.txt && git commit -qm v1
echo v2 > app.txt && git commit -qam v2

# Stage an edit, then unstage it (index <- HEAD)
echo draft > app.txt && git add app.txt
git restore --staged app.txt

# Discard the working-tree edit (worktree <- index)
git restore app.txt

# Bring back the v1 content into both index and worktree
git restore --source=HEAD~1 --staged --worktree app.txt
cat app.txt   # v1
git status --short

The script unstages a change, throws away a working-tree edit, and then pulls an older version of the file into both the index and the working tree.

When to use it

Unstaging an accidental add

You staged too many files. Run git restore --staged <file> to reset the index entry to HEAD while keeping your edits in the working tree.

Recovering an older file version

A recent commit broke the Makefile. Restore just that file from master~2 without touching the rest of the code.

Redoing a conflict resolution

You got a manual merge resolution wrong. Run git restore --merge (or --conflict=zdiff3) on the file to get the conflict markers back and start over.

Partially discarding edits

Use git restore -p to drop only the debugging hunks and keep the rest of your changes.

Interview questions

QWhat is the difference between git restore <file> and git restore --staged <file>?

Without flags, only the working tree is written, and it is filled from the index, so you lose unstaged edits. With --staged, only the index is written, and the default source becomes HEAD. That unstages the file but leaves its working-tree content alone.

Follow-up: How do you discard both staged and unstaged changes to one file? Use git restore --source=HEAD --staged --worktree <file>, or the short form git restore -s@ -SW <file>.

QHow does git restore relate to git checkout and git reset for file-level operations?

The docs say git restore --staged <path> does the same as git reset on that path. Restoring the index and working tree from HEAD does the same as git checkout on that path. git restore handles only files, never branches, so it separates out the file-restoring part of checkout.

Follow-up: Why can't you use --ours with --source? Stages #2 and #3 exist only in the index while a merge is unresolved, and a tree-ish passed to --source has no such stages.

QWhy can git restore --source=<commit> <dir> delete files?

No-overlay mode is the default. In that mode, tracked files that are missing from the source tree are removed so that the location matches the source exactly. Pass --overlay if you want files that aren't in the source to stay.

Follow-up: Why quote '*.c' when running git restore? With quotes, Git matches the pattern against index entries, so files you deleted from the working tree are restored too. If the shell expanded the glob, those files would be missed.

  • git-checkout
  • git-reset
  • git-switch
  • git-add
  • git-revert
  • gitglossary

Source: Git - git-restore Documentation. Checked 2026-11-02.