Version Control
Git
File Management
Discard Changes
Code Workflow

How can I discard modified files?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Discarding modified files in Git is simple once you separate three different states: unstaged changes, staged changes, and untracked files. Most mistakes happen when people use a destructive command before checking which state the file is in.

Start by Inspecting the Repository State

Before discarding anything, confirm exactly what Git sees:

bash
git status
git diff
git diff --staged

git status shows whether a file is modified, staged, or untracked. git diff shows working tree changes, and git diff --staged shows what is already in the index. This matters because discarding staged changes and discarding unstaged changes are different operations.

If you skip this step, you can easily delete the wrong thing. A file may look "modified" in an editor while Git sees both staged and unstaged edits in the same file.

Discard Unstaged Changes in Tracked Files

If you edited a tracked file and want to restore it to the version in HEAD, use git restore:

bash
git restore path/to/file

To discard unstaged changes across all tracked files:

bash
git restore .

This only affects tracked files in the working tree. It does not unstage anything, and it does not delete untracked files.

For example, suppose you changed app.js and want to throw away those edits:

bash
git status
git restore app.js
git status

After git restore app.js, the file content matches the last committed version again.

Unstage Changes Without Deleting Your Edits

If you accidentally ran git add and want to remove a file from the index while keeping its working copy edits, use:

bash
git restore --staged path/to/file

To unstage everything:

bash
git restore --staged .

This is not the same as discarding. It only moves changes out of the staging area.

A common recovery flow looks like this:

bash
git add server.py
git restore --staged server.py

After that command, server.py is still modified locally, but it is no longer part of the next commit.

Discard Both Staged and Unstaged Changes

If a tracked file has changes in both places and you want to remove everything, do it in two steps:

bash
git restore --staged path/to/file
git restore path/to/file

For the whole repository:

bash
git restore --staged .
git restore .

This sequence is explicit and readable. It avoids the confusion that older tutorials created with overloaded checkout and reset commands.

Remove Untracked Files Carefully

git restore does not affect files Git has never tracked. For those, use git clean.

Always preview first:

bash
git clean -n

If the preview looks correct, remove untracked files:

bash
git clean -f

If you also want untracked directories removed:

bash
git clean -fd

This command is intentionally strict because it deletes content permanently from the working tree. Use the preview every time unless the directory is disposable.

Safer Alternative: Stash Instead of Destroy

If you are not completely certain that the changes are useless, stash them instead of discarding them.

bash
git stash push -m "temporary save before cleanup"

You can inspect the stash list later:

bash
git stash list

And restore it if needed:

bash
git stash pop

Stashing is the right move when you are switching tasks, testing a clean build, or cleaning up a branch under time pressure.

Older Commands You Will Still See

Many answers on the web still use older syntax:

bash
git checkout -- path/to/file
git reset HEAD path/to/file

These commands still work in many cases, but modern Git favors git restore because the intent is clearer. checkout was overloaded for both branch switching and file restoration, which made it easier to make mistakes.

Common Pitfalls

  • Running git restore . and assuming it also removes staged changes or untracked files.
  • Using git clean -f without previewing with git clean -n.
  • Confusing "unstage" with "discard" and accidentally losing content.
  • Applying repository-wide commands when only one file needed to change.
  • Skipping git status and acting without verifying the current state.

Summary

  • Check the repository state first with git status, git diff, and git diff --staged.
  • Use git restore to discard unstaged changes in tracked files.
  • Use git restore --staged to unstage changes without deleting file edits.
  • Use git clean for untracked files, and preview with -n before deletion.
  • When in doubt, stash the work instead of destroying it.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.