Every developer makes mistakes—editing the wrong function, introducing unintended syntax errors, or staging files prematurely. Git provides powerful, surgical mechanisms to undo mistakes at every level of the three-tree lifecycle. In Git 2.23+, the dedicated git restore command makes this process clear and safe.
If you modified a file in your editor but haven't run git add yet, and you want to throw away all your edits and return the file to the exact state of the latest commit:
# Discard changes to a single file:
$ git restore src/app.js
# Discard changes to multiple specific files:
$ git restore styles.css index.html
# Discard all unstaged changes across your entire project:
$ git restore .
Unlike committed snapshots, uncommitted edits in your working directory exist only in your operating system's filesystem RAM/disk. Once you run git restore . on unstaged files, those edits are permanently erased!
git restore --staged)If you ran git add on a file by mistake, but you still want to keep your edits in your working directory, simply unstage the file:
# Unstage a single file (moves it from Index back to Working Directory):
$ git restore --staged package.json
# Unstage all staged files:
$ git restore --staged .
After running this, package.json remains modified on your disk, but it is no longer marked for the next commit snapshot.
git cleangit restore only operates on files that Git already tracks. If you created 10 new experimental files, generated log files, or downloaded build artifacts that are untracked, use git clean to purge them:
# Step 1: ALWAYS run a dry run first to see what WILL be deleted:
$ git clean -dn
Would remove test_draft.js
Would remove temp_output.json
# Step 2: Delete untracked files permanently:
$ git clean -df
# -d = include untracked directories
# -f = force deletion
| What do you want to undo? | Where are the changes? | Command to Run |
|---|---|---|
| Discard file edits and reset to HEAD | Working Directory (Unstaged) | git restore filename |
| Unstage a file, keeping edits on disk | Staging Area (Index) | git restore --staged filename |
| Delete all newly created untracked files | Working Directory (Untracked) | git clean -df |
| Revert an entire commit recorded in history | Local Repository (Committed) | git revert [commit-hash] |
git restore?Historically, Git overloaded the git checkout command to perform two completely different tasks: switching branches (git checkout branch-name) and discarding file changes (git checkout -- filename). Beginners frequently confused the two and accidentally wiped out their uncommitted work. Starting in Git version 2.23 (released August 2019), Git split these responsibilities into two dedicated, unambiguous commands: git switch (for branches) and git restore (for files).
Strengthen your version control mastery by studying these connected classes:
Understand when to rewrite local history vs when to emit safe public reverts.
Quickly patch accidental commits without creating messy follow-up fix commits.
Shelve half-written code instead of discarding changes with git restore.
Restore commits and branches discarded by mistaken resets or clean operations.
Advance your software engineering skills with the next topic in our synchronized curriculum.
Continue to git reset vs git revert → Previous: ← .gitignore Mastery | Full Syllabus