In software development, managing changes efficiently is key to maintaining the integrity and progress of your projects. Git offers various ways to handle modifications made to your codebase, and one such capability is discarding changes. This guide will walk you through how to safely discard changes in Git, covering different scenarios where you might need to revert modifications, whether they're unwanted, erroneous, or simply unnecessary for your current task. Discarding changes can help you maintain a clean and orderly code repository, ensuring that only the best iterations of your work are preserved.
Understanding the working directory, staging area, and commits
Before diving into the commands, let's clarify the main areas of Git:
- Working directory: The Git working directory, also known as the working area, is the space on your local filesystem where the actual files and directories of your project are stored and modified before being committed to the remote repository.
- Staging area (index): This is where you prepare and organize changes before committing them to the remote repository. It acts as a middle ground between your local machine and the repository stored on a remote server.
- Commits: These are records of your past code changes, which are stored in the project history.
Discarding changes using git checkout
The git checkout
command is one of the most common ways to revert changes:
Discard changes in the working directory: To revert a specific file to the last committed state, use:
Terminalgit checkout <file>Replace
<file>
with the name of the file you want to revert.Discard all changes in the working directory: If you want to discard changes from all files in the working directory:
Terminalgit checkout .
This will revert all of your tracked files back to the state they were in at the last commit. However, this will not affect "untracked" files, new files that have been created locally but not committed yet, or other files that are auto-generated and shouldn't be committed to the repository like build artifacts, compiled binaries, log files etc.
Using git restore
(since Git 2.23)
Git 2.23 introduced a more straightforward command called git restore
, designed to make it easier to work with changes:
Discard changes to a specific file:
Terminalgit restore <file>Discard changes to all files in the working directory:
Terminalgit restore .
This command is versatile and can also be used to restore files from a specific branch or commit.
Removing untracked files with git clean
For files that are not tracked by Git (new files or automatically generated files that are not in your .gitignore
), you can use the git clean
command to clean your working directory:
Discard untracked files:
Terminalgit clean -fDiscard untracked directories:
Terminalgit clean -fd
This command will remove all files and directories that are not under version control, so use it with caution as these changes cannot be undone.
Both of the above commands will leave files explicitly ignored by Git (i.e. files listed in the .gitignore
file) intact. To delete ignored files in addition to all of the other untracked files, you can add the -x
flag:
git clean -fx
Hard reset with git reset
If you need to discard all staged and unstaged changes, you can use git reset
:
Discard all changes (staged and unstaged):
Terminalgit reset --hard
This command resets your working directory and staging area to match the last commit. It's a powerful command that should be used carefully, as it will permanently erase all changes. However, untracked files will be untouched by this command.
Specific scenarios
Here are a few more specific use cases and how to handle them:
Discard changes in one file that are staged:
If you have added changes to the staging area (with
git add
) and want to remove them from there, you can use:Terminalgit restore --staged <file>If you also want to discard these changes in the working directory, after restoring the file run:
Terminalgit checkout <file>
For further reading see the official Git documentation.