Removing Ignored Files From a Git Repository
Earlier this week I was asked to review a few pull requests on an older project. The project maintainer wasn’t available and the client was anxious to have the changes deployed. A cursory glance at the pull requests revealed conflicts. All on files generated by the build process.
The project was started after we had only recently made the transition from Subversion to Git. Whoever created the project was new to Git and didn’t properly understand how to use the .gitignore
file.
Starting Out
When you initialise an empty Git repository using git init
the newly created repository will contain no .gitignore
file. That’s not so bad for simple projects. However if any part of your project will be compiled then you’ll most likely need to create one.
Templates
GitHub’s gitignore repository provides an extensive collection of templates targeting various languages and environments. It provides an easy way to get started and is updated often.
This repository populates the add .gitignore drop down list on GitHub’s create a new repository page so you may already be familiar with it.
Documentation
Having a good starting point is useful but what about knowing how and when to update it? Only basic projects will be covered entirely by a template.
If you’re unfamiliar with how .gitignore
files work there is detailed documentation available.
Stop Tracking
Git will continue to track changes to files which have previously been committed. Even if your new .gitignore
file excludes them. There are a few steps to correct this.
Remove Files From Index
To stop Git tracking the unwanted files we must remove them from the index. There are a number of ways we can approach this.
Individualy
You can stop tracking an individual file by using the following command.
git rm --cached <file>
The --cached
option causes the file to be removed from the index but not from the working tree.
Rebuild the Index
This approach involves removing everything from the index and then adding everything again while respecting the .gitignore
file. A drawback of this method is that any untracked files will also be added.
git rm -r --cached .
The -r
option means that files and folders will be removed recursively. The .
represents the current working directory. After executing this command the index will be empty.
git add .
Adding the current working directory will cause git to re-add all the files which are not excluded by the .gitignore
file.
I read about this approach from an answer by Matt Frear on Stack Overflow.
List and Remove
My preferred method is to list all the files which the updated .gitignore
file would exclude and then remove those files from the index. Quick and precise.
git ls-files --ignored --exclude-standard | xargs git rm --cached
When combined with the --ignored
and --exclude-standard
options git ls-files
will list files which are excluded by the .gitignore
file or any other Git exclusions.
The xargs
command passes each listed file to git rm --cached
which removes it from the index.
I learnt this from an answer by thSoft on Stack Overflow.
Check and Commit
Whichever approach you find most suitable you can use git status
to list all the files that have been removed from the index prior to committing. Files which have been removed from the index will be marked as deleted
. Once you’re happy, commit your changes.
You’re all done. Be aware that when other developers pull this change their working tree will be modified.