Git Restore All Unstaged and Untracked Files Back to their Latest Commit
Sometimes you want to experiment and revert the changes you've made to their last known good state or dispose of files.
When you run a git status
you can see a combination of files and directories
to help answer the following questions:
- Have they changed since their latest commit?
- Are they currently staged or unstaged to be commit?
- Which files and directories aren’t in version control yet?
In this post we’re going to answer the following questions you might have:
- How can I unstage and revert all changes of 1 file back to its latest commit?
- How can I revert all unstaged changes back to their latest committed state?
- How can I delete all files and directories that aren’t tracked?
Most of these questions revolve around the topic of you made some changes, haven’t commit anything yet and now you want to roll them back.
# Solving 3 Problems with Git Restore and Git Clean
WARNING: Most of the commands we’re going to run are destructive in the sense that you will lose your uncommitted changes in the working directory.
Let’s start answering some of the questions from before. The demo
video covers more detail around showing the results of git status
and more. But here’s a quick reference guide in text form:
Unstage and Revert 1 File
We need to do 2 things which is to first unstage it from being commit. Then we can restore the file back to its latest committed state. The second command is destructive.
git restore --staged <file>
git restore <file>
If you want to get fancy you can do: git restore --stage <file> && git restore "$_"
. That will chain both commands together and $_
is a reference to the
last argument of the previous command. It avoids duplicating the file name or
path.
If your file isn’t already staged then you only need to run git restore <file>
.
Revert All Tracked Files Back to Their Latest Committed State
This is exactly the same as above except you can replace <file>
with .
to
act on all files and directories. This will recursively do it too.
git restore --staged .
git restore .
Again, if the files aren’t staged you only need to run git restore .
.
If you need to revert a bunch of files in a specific directory but you don’t
want to operate on every file you can run git restore --staged mydir/
.
Basically you can take advantage of git’s ability to filter files and
directories as needed.
Delete All Untracked Files and Directories
This is where it gets different. We can’t run git resore
because there’s
nothing to restore.
We have a couple of options depending on what we want to do:
# Only perform a dry run.
git clean --dry-run|-n
# Include directories.
git clean --dry-run|-n -d
# Perform an interactive delete.
git clean --interactive|-i -d
# Force delete everything.
git clean --force|-f -d
# Force delete files that are only ignored by git.
git clean --force|-f -X
IMO that handles most use cases. You can run git clean --help
to see what
else exists.
The demo video below goes over these commands in a bit more detail as we run them against a demo git repo.
# Demo Video
Timestamps
- 0:56 – Creating a demo git directory
- 1:52 – Staging and unstaging 1 specific file
- 3:16 – Restoring 1 file back to its latest commit
- 4:06 – Doing the same thing but on all or multiple files
- 6:03 – You only need to run both commands if you have to unstage first
- 6:27 – Using your shell to reduce duplication
- 7:21 – Getting rid of untracked files and directories
- 8:30 – Performing a clean dry run
- 9:00 – Adding the recursive directory flag
- 10:00 – Performing an interactive delete
- 10:45 – Force deleting, similar to the rm command
- 11:08 – Using the -X flag to only delete gitignored files
References
What’s your favorite way to handle these use cases? Let me know below.