How to Undo Git Add: Unstaging Files Before You Commit

Running git add is one of the most routine actions in a Git workflow — but it's also one of the easiest to do too broadly or too early. Whether you staged the wrong file, included changes you're not ready to commit, or simply want to reorganize what goes into your next commit, Git gives you straightforward tools to undo a git add without touching your actual file contents.

What git add Actually Does

Before undoing anything, it helps to understand what staging means in Git's model.

Git uses a three-stage structure:

  • Working directory — your files as they exist on disk
  • Staging area (index) — a snapshot of what will go into your next commit
  • Repository — the committed history

When you run git add <file>, you're copying the current state of that file into the staging area. You haven't committed anything yet. Undoing git add means removing a file from that staging area — returning it to an "unstaged" state — while leaving the file itself completely untouched on disk.

The Standard Way: git restore --staged

For most users on Git 2.23 or newer, the cleanest command to unstage a file is:

git restore --staged <filename> 

To unstage everything you've added:

git restore --staged . 

This command was introduced specifically to separate two jobs that used to be handled by the overloaded git checkout command. It only affects the staging area. Your working directory file remains exactly as it is.

The Older Method: git reset HEAD

If you're working with an older Git version — or in an environment where git restore isn't available — the equivalent command is:

git reset HEAD <filename> 

Or to unstage all staged files:

git reset HEAD 

Both git restore --staged and git reset HEAD accomplish the same result in this context: the file is removed from the staging area and returned to "modified but unstaged" status. Neither command modifies the content of the file.

Checking What's Staged

Before and after running either command, git status is your best tool for confirming what's staged and what isn't:

git status 

Files listed under "Changes to be committed" are staged. Files under "Changes not staged for commit" are modified but not yet added. After a successful unstage, a file moves from the first group to the second.

Key Scenarios and What to Use

SituationCommand to Use
Unstage one filegit restore --staged <file>
Unstage all staged filesgit restore --staged .
Using Git older than 2.23git reset HEAD <file>
Unstage and discard file changesgit restore <file>(different — removes edits too)
Undo a commit entirelygit reset HEAD~1(moves beyond just staging)

⚠️ One important distinction in the table above: git restore <file>without--staged will discard your working directory changes too. That's a different operation — only use it if you want to throw away edits entirely, not just unstage them.

What Doesn't Change When You Unstage

Understanding what isn't affected helps build confidence when using these commands:

  • Your file content is preserved. Every edit you made remains in the file.
  • Your commit history is untouched. Unstaging operates only on the index, not on any committed work.
  • Other staged files are unaffected. If you unstage one file with a specific path, everything else you've staged stays staged.

This makes unstaging a low-risk operation in most cases — it's reversible, and it doesn't rewrite anything.

🔄 When Unstaging Gets More Complicated

The scenarios above cover the common case: you've made changes, ran git add, and want to back that out before committing. But a few situations add nuance:

New (untracked) files staged with git add behave slightly differently. After unstaging, they return to "untracked" status rather than "modified." The file still exists — it just appears under "Untracked files" in git status again.

Partially staged files — where you used git add -p to stage only some chunks of a file — can be selectively unstaged using the same -p patch mode with git restore --staged -p <file>. This gives you line-level control over what stays staged.

Team environments and shared branches don't change the mechanics of unstaging locally, but they do affect the downstream thinking. What you choose to commit — and therefore what you don't stage — can matter for code review, CI pipelines, and collaborative history.

Variables That Affect Your Approach

The right command for a given moment depends on a few things specific to your setup:

  • Git versiongit restore requires 2.23+; older environments fall back to git reset HEAD
  • IDE or GUI tools — Many editors (VS Code, IntelliJ, GitKraken) have staging interfaces that visually represent the index, making it easy to unstage with a click rather than the command line
  • Workflow conventions — Some teams stage and commit frequently in small chunks; others batch larger changes, which affects how often selective unstaging is needed
  • Whether you're mid-rebase or in a merge conflict — the staging area behaves differently during these states, and unstaging decisions interact with how conflicts get resolved

The mechanics of git restore --staged and git reset HEAD are consistent and reliable — but how and when to apply them depends on what you're building toward in your next commit, and how your project's history is meant to read.