Undo a changeAlways fixable

Unstage a file you added by mistake

How do I undo git add without losing my changes?

Short answer

git restore --staged <file> removes a file from the staging area and leaves your edits completely untouched. The older equivalent is git reset HEAD <file>. Neither one touches the contents of your file, so this is a zero-risk operation.

quick fix
git restore --staged path/to/file.ts

Unstages the file, keeping every edit you made

Does this match your situation?

  • You ran git add . and swept in files you didn't mean to commit.
  • A .env, build folder or large binary is now staged.
  • You want to commit only part of your work.

Step-by-step fix

  1. See what's currently staged

    git status separates staged from unstaged clearly, and git diff --staged shows the exact content you're about to commit. Check before you unstage so you know what you're aiming at.

    step 1
    git status -sb
    git diff --staged --stat
    
  2. Unstage one file, several files, or everything

    restore --staged is the modern spelling and reads clearly. The reset form does exactly the same thing and still appears in most older tutorials, so both are worth recognising.

    step 2
    git restore --staged .env            # one file
    git restore --staged src/ assets/    # several paths
    git restore --staged .                # everything
    
    # classic equivalent:
    git reset HEAD .env
    

    Neither command modifies your working files — only the staging area changes.

  3. If the file should never be tracked, ignore it properly

    Unstaging is a one-time fix. If it's a secret file or build output, add it to .gitignore so it can't be staged again by an absent-minded git add .

    step 3
    echo ".env" >> .gitignore
    git add .gitignore
    git commit -m "Ignore local environment file"
    
  4. If you already committed it, that's a different fix

    Unstaging only helps before the commit exists. Once committed, you need to amend or reset — and if the file contains a secret and it's been pushed, treat it as leaked.

    step 4
    git reset --soft HEAD~1              # undo the commit, keep changes staged
    git restore --staged .env             # then unstage the offending file
    git commit -m "Commit without the env file"
    

Why this works

Git has three places a file can live: your working directory, the index (staging area) and the repository. git add copies working-directory content into the index; committing turns the index into a permanent snapshot. Unstaging simply rewrites the index entry for that path back to whatever HEAD has, which is why your working file is never touched. It's the clearest illustration of why the index exists at all: it lets you compose a commit deliberately instead of recording whatever happens to be on disk.

How to stop it happening again

  • Maintain a real .gitignore from day one — use gitignore.io or GitHub's templates for your stack.
  • Prefer git add -p over git add . so every hunk is a conscious decision.
  • Run git status before every commit; it takes a second and catches almost everything.

Commands used in this guide

git restore

Throw away working-directory changes or unstage files (the modern, clearer replacement for checkout).

git reset

Move the current branch pointer, optionally rewriting the index and your files.

git status

Show what's changed, what's staged, and what Git is ignoring.

git add

Stage changes so they go into your next commit.

Still stuck?

Search the full command reference and every other rescue guide — there are 56 of them, covering everything from detached HEAD to force-push disasters.

Browse all guides →

Frequently asked questions

How do I undo git add?

git restore --staged <file> unstages it while leaving your edits intact. The equivalent older command is git reset HEAD <file>. Neither modifies the file's contents, so there is no risk of losing work.

What's the difference between git restore and git restore --staged?

A big and dangerous one. git restore --staged <file> only unstages, keeping your edits. git restore <file> without --staged overwrites your working file with the committed version, permanently discarding your uncommitted changes.

How do I unstage everything at once?

git restore --staged . unstages every path under the current directory, or git reset with no arguments unstages everything in the repository. Both keep your working-directory changes exactly as they are.

Related rescue guides

← All Git Rescue guides