How to remove untracked files in git
It’d be great if there were a simple command to tell Git to delete untracked files, like `git remove untracked files` or something similar, in plain English. Well... there isn’t. However, in case you just Googled this and already know what you want, here’s the solution:
Start with a dry run to see which files you’ll delete: $ git clean -n -d.
If that all looks good, run $ git clean -f -d to finish the process.
That should do the trick. Goodbye and good luck, fellow Googlers! 👋
Now, if you want some more context, let’s dive in.
I’m sure you’ve come across situations where you have a file or handful of files in your working directory that you haven’t added to Git and want to delete. Maybe you pointed your Downloads folder to your project directory on accident (I’ve definitely never done this), or you just created a couple of files for testing purposes. Either way, these files need to go away without ever seeing the light of day.
For a while, my default approach to situations like this was to open Finder (Mac OSX) or File Explorer (for Windows) and manually delete them through the GUI. Or, if I was feeling extra tech-savvy, I might have used the OS-level command rm (like `rm src/js/my-extra-js-file.js`). And yes, these approaches work. However, I’m here today to tell you that there’s a better way.
How to use the git clean command
The git clean command is a tool designed to deal with situations exactly like this, where you have a handful of files to delete and can’t be bothered to track them all down one at a time. It finds all the changes that you haven’t committed or put in staging yet and can delete them in one fell swoop.
It has several different flags, but these are the three that you’ll use most often:
-d: this flag specifies that you want to delete untracked directories too, not just files. You usually want to have this one on, especially if you aren’t clear on exactly which files you want to delete, and know that you want everything untracked gone.
-n, or --dry-run: this flag causes Git to show you which files will be affected, instead of deleting them. Again, if you’re not sure which files you want to get rid of, this is helpful to make sure you don’t accidentally delete anything you want to keep.
-f, or --force: you have to include this flag if you want any files to be deleted. Git very much errs on the side of caution and makes you pass in this extra confirmation. That’s because once a file is deleted with this method, it can’t be restored.
Why not just use git rm?
If you’re a Git command line user, you might be wondering at this point - why don’t we use git rm to delete these files? There are a couple of reasons.
First, with git rm, you need to target each file individually, whereas git clean provides “search and destroy” functionality. This is much faster because you don’t need to give a relative path for each file you want to remove.
But second, and more importantly, git rm actually only works on tracked Git files, that is, files which have already been added to source control by being committed or added to staging. (The Git docs for this command recommend using regular old OS-level rm for untracked files.)
Using git stash to delete files in a safer way
Another method of getting a clean working directory is to use git stash to stash and delete both tracked and untracked files. You can do this using the --include-untracked command, which stashes all untracked files and then runs git clean behind the scenes for us.
Pros and cons of using git stash
The great benefit of this method is that you aren’t deleting any data. It’s all stashed safely away and can be restored at any time. Re-applying the stashed files (with git stash apply) will even restore your untracked files to the state they were without adding them to Git. This is an excellent way to save a “snapshot” of uncommitted changes.
The downside to this method is that it will stash everything, including any changes made to tracked files. You can get around that by adding changes to your tracked files to staging (with git add) and then tacking on the flag --keep-index. This flag will prevent anything in staging from being stashed, so only changes to unstaged and untracked files will be cleared.
Altogether, that command looks like this:
This method is a little more work if you have both untracked files and unstaged changes in your working directory, but since you’re able to restore your files if you realize you made a mistake, it can be situationally useful.
Using .gitignore to avoid committing changes
There’s a third method that you can use to prevent staging or committing untracked files, and that is by adding them (or their parent directories) to your .gitignore file.
Whenever Git is performing operations on files, it first checks to see if those files are in your .gitignore file -- if they are, it ignores them. This is useful for when you have files that need to always be present in your working directory, such as build files or your `node_modules` directory, but shouldn’t make it into your repository.
Remember -- deleting files using the OS-level rm command, git clean, or git rm is always a permanent, irreversible operation. Make backups, use git stash wherever possible, and be careful to double-check whether or not you want to get rid of the data you are deleting before you pull the trigger!
Thanks for reading.