GLM 4.5 Air

How to Discard Unstaged Changes in Git: Complete Guide

Learn how to safely discard unstaged changes in Git's working directory with our complete guide. Master git checkout and git restore commands to maintain a clean repository.

Question

How do I discard unstaged changes in Git that are in the working directory but not in the staging area?

GLM 4.5 Air

To discard unstaged changes in Git that are in your working directory but not in the staging area, you can use the git checkout command with the file path or git restore with the --worktree option. For example, git checkout -- filename will discard changes to a specific file, while git restore --worktree . will discard all unstaged changes in your working directory.

Contents

How to Discard Unstaged Changes for Specific Files

To discard unstaged changes for specific files in your working directory, you have two primary commands at your disposal:

Using git checkout

The traditional approach uses the git checkout command:

bash
git checkout -- path/to/your/file.txt

This command will restore the file in your working directory to match the version in the staging area. If the file isn’t staged, it will restore it to match the last commit.

Important: The double dash (--) is important as it separates file paths from potential branch names. This prevents confusion when your file name might otherwise be interpreted as a branch name.

Using git restore (Modern Git)

In Git versions 2.23 and later, you can use the more explicit git restore command:

bash
git restore --worktree path/to/your/file.txt

The --worktree flag specifically targets the working directory, which is exactly what we want when discarding unstaged changes.

Discarding Changes for Multiple Files

You can also discard changes for multiple files at once:

bash
git checkout -- file1.txt file2.txt dir/file3.txt

or with the modern command:

bash
git restore --worktree file1.txt file2.txt dir/file3.txt

How to Discard All Unstaged Changes

If you want to discard all unstaged changes across your entire working directory:

Traditional Method

bash
git checkout -- .

The . at the end refers to the current directory and all its contents.

Modern Method

bash
git restore --worktree .

Warning: Be very careful when using these commands without specifying files. They will permanently discard all changes in your working directory that haven’t been staged. There’s no “undo” button for this operation.

Interactive Approach

For a more controlled approach, you can use:

bash
git checkout -- .

This will show you a list of files that would be affected and allow you to confirm or deny each one.

Understanding the Difference Between Working Directory and Staging Area

To effectively use these commands, it’s essential to understand Git’s three main areas:

  1. Working Directory: The files on your local machine that you’re currently working on
  2. Staging Area (Index): A temporary area where you can stage changes before committing them
  3. Local Repository: Your committed changes, stored as snapshots

When you make changes to files, they exist only in your working directory. When you run git add, you’re moving those changes to the staging area. When you run git commit, you’re moving the staged changes to your local repository.

The commands we discussed (git checkout and git restore --worktree) only affect the working directory, leaving the staging area and repository untouched.

You can check the status of these areas with:

bash
git status

This will show you which files have unstaged changes (in the working directory) and which have staged changes (in the staging area).

Safety Precautions and Best Practices

Discarding changes is a potentially dangerous operation, so here are some important precautions:

Always Check Your Status First

Before discarding any changes, run:

bash
git status

This will show you exactly what changes you’re about to discard.

Consider Staging Important Changes

If you have some changes you want to keep but others you want to discard, consider:

bash
git add file-you-want-to-keep.txt
git checkout -- file-you-want-to-discard.txt

Use git stash for Temporary Storage

If you’re not sure about discarding changes but want to clean your working directory, consider stashing:

bash
git stash

This will save your unstaged changes and revert your working directory to match the HEAD commit. You can later retrieve these changes with:

bash
git stash pop

Create a Backup Branch

For significant changes, consider creating a backup branch before discarding:

bash
git branch backup-branch

This gives you a safety net if you later realize you needed those changes.

Alternatives and Related Commands

git clean for Untracked Files

If you have untracked files (not just modified ones) that you want to remove, use:

bash
git clean -n  # Shows what would be deleted (dry run)
git clean -f  # Actually deletes untracked files

The -n flag is useful to see what would be deleted without actually deleting anything.

git reset for Staged Changes

If you’ve accidentally staged changes that you want to unstage (but keep in your working directory):

bash
git reset HEAD path/to/file.txt

This moves the file from the staging area back to the working directory.

git reset --hard for Everything

If you want to discard both staged and unstaged changes and move your working directory and staging area to match the last commit:

bash
git reset --hard HEAD

Warning: This is a destructive operation that will permanently discard all changes, both staged and unstaged.


Conclusion

Discarding unstaged changes in Git is a common operation that can be performed safely with the right commands. Remember these key points:

  1. Use git checkout -- filename or git restore --worktree filename to discard unstaged changes for specific files
  2. Use git checkout -- . or git restore --worktree . to discard all unstaged changes
  3. Always check your status with git status before discarding changes
  4. Consider using git stash if you’re unsure about discarding changes
  5. Use git clean to remove untracked files, not just modified ones

By understanding these commands and when to use them, you can maintain a clean working directory while keeping your Git repository in the state you want.