Table of Contents

Introduction

git restore --staged <file> is the undo for git add. You staged a file, you've changed your mind about including it in the next commit, and you want it back in the working directory as an ordinary edit. The --staged flag is doing a lot of work in that command: without it, git restore discards your edit instead.

In this article, we'll:

  1. Watch git restore --staged README.md unstage one file
  2. Confirm the edit is still on disk
  3. Keep restore --staged and plain restore clearly apart

What is git restore --staged?

git restore --staged <file> copies the HEAD version of <file> into the staging area, overwriting the staged version. The working directory isn't touched, so your edit remains as an unstaged modification. It is the same operation as the older git reset HEAD <file>.

Watch it happen

Our sample repo has one file staged by mistake. Here's git restore --staged README.md:

  1. Before: README.md is staged, its edit added to the index.
  2. Git resets README.md in the index to its version in HEAD, so the edit is unstaged again.
  3. The branch and every commit stay put, and the file on disk still has your edit. Unstaging never moves HEAD.

Before and after

git status --short before:

M  README.md

and after:

 M README.md

One column over. The commit graph is unchanged:

The raw git output, if you want to read along in text

git log --oneline --graph --all

before

* 1117a34 (feature) Add search tests
* e5869f0 Fix typo in search box
* fc19889 Add search box
| * 8c02d5b (HEAD -> main) Update dependencies
| * a0b2db3 Add user settings page
|/  
* 96c4fc2 Fix header layout
* ae65976 Add login page
* 3e1ffe4 Add project skeleton
* 4114b2c Initial commit

after

* 1117a34 (feature) Add search tests
* e5869f0 Fix typo in search box
* fc19889 Add search box
| * 8c02d5b (HEAD -> main) Update dependencies
| * a0b2db3 Add user settings page
|/  
* 96c4fc2 Fix header layout
* ae65976 Add login page
* 3e1ffe4 Add project skeleton
* 4114b2c Initial commit

Two restores

The flag decides which direction the copy goes (the git restore documentation covers --worktree too):

  • git restore --staged <file> copies from HEAD into the staging area. Your working copy is untouched. Harmless.
  • git restore <file> copies from the staging area into the working directory. Your edit is overwritten. Not recoverable.

Both are "restore", and the second one is on its own page because it deserves a warning of its own. Here it is on the same repo, so the two sit side by side:

I'd have preferred two differently named commands here. unstage would have been a fine verb. As it is, I've trained myself to type --staged first and the file name second, so the dangerous form is never a partial version of what I meant to type.

Is it safe?

Safe git-sim pre-flight

Unstages changes; working tree files keep their content.

The staged version is replaced by the committed one, and your working copy keeps the edit. Nothing is lost.

How to undo it

git add README.md

Try it on your repository

pip install git-sim
git-sim restore --staged README.md

git-sim shows the file moving out of the staging area with the working directory unchanged.

Common questions

What does git restore --staged do?

It unstages the named files, copying the HEAD version into the staging area while leaving your working copy alone.

What is the difference between git restore and git restore --staged?

--staged unstages and keeps your edit. Without it, restore overwrites your working copy and discards the edit.

Is git restore --staged the same as git reset HEAD file?

Yes. restore --staged is the newer spelling, added in Git 2.23.

How do I unstage everything?

git restore --staged .

Summary

In this article, we watched git restore --staged move a file out of the staging area while the edit stayed on disk, and drew the line between it and plain git restore, which discards edits.

Next steps

git restore covers the other direction. git add is the command this undoes.