Migrate to RunxBuild and earn up to $50 in hosting credit on your first deposit.

Calculate your savings
unxBuild

How to Undo git add: Unstaging Without Losing Work

Sean

Platform Writer

Aug 10, 2026
6 min read

To undo git add, run git restore --staged <file>. Your edits stay exactly where they are — only the staging is removed. The older git reset <file> does the same thing and still works everywhere. Neither touches your file contents, which is the reassurance most people are actually looking for.

How to Undo git add: Unstaging Without Losing Work

Unstaging is one of the safest operations in Git and one of the most anxiety-inducing, because the commands nearby are genuinely destructive and the names do not signal which is which. Here is what each one does, and the single flag worth being careful with.

Table of contents

The modern command

Git 2.23 introduced git restore specifically to split the overloaded git reset into commands that say what they do.

# Unstage one file, keep the changes
git restore --staged file.txt

# Unstage several
git restore --staged src/ tests/

# Unstage everything
git restore --staged .

# Interactively pick what to unstage
git restore --staged --patch file.txt

Git’s own status output suggests this now, which is why you will see it referenced in your terminal:

$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   src/app.js

The older command, which is not wrong

git reset file.txt          # unstage one file
git reset                   # unstage everything
git reset HEAD file.txt     # explicit form, identical result

git reset without --hard or --soft defaults to --mixed, which resets the index and leaves the working tree untouched. For a path argument, that is precisely unstaging.

Both commands are equally safe and neither is deprecated. restore is clearer, reset is in every tutorial written before 2019 and in a lot of muscle memory. Use whichever, and do not let anyone tell you the old one is dangerous — it is not, in this form.

Untracked files behave differently

If you staged a brand-new file, there is no previous version for Git to restore the index entry from. git restore --staged still works, but git reset HEAD on some older versions complains about an ambiguous argument on a repository with no commits.

# Works on a new file, including in a repo with zero commits
git rm --cached newfile.txt

# The file remains on disk, now untracked
git status
# Untracked files:
#         newfile.txt

git rm --cached keeps the file; git rm deletes it. That one flag is the difference between unstaging and deleting, and it is the most common way people lose a file they meant to keep.

This is also the right tool when you accidentally committed something that should have been ignored — a .env, a node_modules directory, a large binary. Remove it from tracking, add it to .gitignore, and commit.

git rm --cached -r node_modules
echo 'node_modules/' >> .gitignore
git add .gitignore
git commit -m 'Stop tracking node_modules'

Note that this stops tracking it going forward. The file is still in history, and if it was a secret, rotate the credential — removing it from the current tree does not remove it from every clone.

The commands that do destroy work

The reason unstaging feels risky is proximity to commands that are genuinely irreversible. Worth knowing them explicitly.

# DISCARDS your edits. No undo. Not the same as unstaging.
git restore file.txt
git checkout -- file.txt      # older equivalent

# DISCARDS everything: index and working tree
git reset --hard

# DELETES untracked files
git clean -fd

The dangerous pair is git restore file.txt versus git restore --staged file.txt. One word apart. The first throws away your edits; the second only unstages them. There is no confirmation prompt and no reflog entry for uncommitted work.

  • Unstage (safe): git restore --staged <file> or git reset <file>
  • Discard edits (destructive): git restore <file> or git checkout -- <file>
  • Both at once (destructive): git restore --staged --worktree <file>

Before anything destructive, git stash is a free undo: it saves both staged and unstaged changes and can be restored with git stash pop. If you are unsure which command you want, stash first and experiment.

Partial staging, which is what you probably wanted

People usually reach for unstaging because they staged too much — an unrelated fix caught by git add .. Staging selectively avoids the round trip.

# Choose hunk by hunk
git add --patch

# Within a specific file
git add -p src/app.js

# Same idea when unstaging
git restore --staged --patch

In patch mode: y stages the hunk, n skips it, s splits it smaller, e opens it for hand-editing, q quits.

git add -p is the highest-value Git habit most developers never pick up. It makes small, coherent commits the path of least resistance, and small coherent commits are what make git revert, git bisect, and code review work as designed.

That pays off directly in deployment. A commit that does exactly one thing can be reverted cleanly and rolled back without dragging unrelated changes with it — on RunxBuild, where each deploy maps to a commit with rollback to the previous one, the granularity of your commits is the granularity of your rollback. The GitHub deployment docs cover that mapping.

How this fits the rest of the stack

Unstaging is safe. git restore --staged <file> and git reset <file> both leave your edits alone, and git rm --cached handles newly added files. The command to be careful with is git restore <file> without the flag, which discards the work entirely. Stash first if you are unsure. If you are setting up deployments where each commit maps to a rollback point, the RunxBuild hosting calculator shows what the build minutes and runtime cost separately.

Useful related references:

FAQ

Does undoing git add delete my changes?

No. Both git restore —staged and git reset remove the file from the staging area while leaving your edits in the working tree. Only git restore without —staged discards changes.

What is the difference between git restore —staged and git reset?

Functionally nothing for unstaging. git restore —staged was introduced in Git 2.23 to give the operation a clearer name; git reset is the older form and works identically.

How do I unstage a newly added file?

Use git rm —cached filename. The file stays on disk and becomes untracked. Do not omit —cached, or Git deletes the file as well as untracking it.

How do I unstage everything at once?

Run git restore —staged . or plain git reset. Both clear the entire staging area and leave every change intact in the working tree.

How do I avoid staging too much in the first place?

Use git add -p to stage hunk by hunk instead of git add .. It takes a few extra seconds and produces small, coherent commits that revert and bisect cleanly.

#git cancel add#git unstage#git restore staged#git reset#git staging area