Ignoring files with Git
By Maxime Bréhin • Published on 10 April 2023
• 3 min
When working with Git, you rarely want to version all the files in a project. Whether we’re talking about files related to the operating system, technical files related to an editor/IDE, sensitive files (security keys, configuration, etc.) or simply locally generated files (logs, temporary files, etc.), you want to avoid sharing them.
Git has a mechanism to ignore them. An ignored file will not be added to the project and will not appear among the files listed by Git (see the git status
command).
# If I try to add an ignored file, Git balks 😅
$git add log/development.log
The following paths are ignored by one of your .gitignore files:
log/development.log
hint: Use -f if you really want to add them.
hint: Turn this message off by running
hint: "git config advice.addIgnoredFile false"
Several ways to ignore files
The best way to do this is to create a .gitignore
file at the root of the project.
This file must be versioned / added to the project so that its rules apply to all project contributors.
There are alternatives, but we think they are bad ideas:
- several
.gitignore
files in the project (one per directory, for example); - one global file for your user account, via configuration, and thus not shared through the repo;
- the
.git/info/exclude
file, not shared either.
Let’s dive a bit deeper into why we dislike these approaches.
1. Multiple .gitignore
files
Why create multiple files when you can have only one at the project root, which is easier to maintain?
2. A global / user account file
It’s tempting to define global rules for our user account, applicable to all our projects (in addition to the local rules for each project), except that…
- these rules will not be shared with coworkers;
- our coworkers might commit files that we would have ignored on our side;
If you really want to try this, you can look at the following command:
git config --global core.excludesfile <global-exclusion-file-path>
You’ve been warned 😉.
3. The .git/info/exclude
local file
Same point as before: not shared with coworkers, so what’s the point?
Syntax
We can use a time-honored, solid syntax: globs. You can specify specific file or directory paths, as well as patterns. You can even specify negations (what you don’t want to ignore), which is useful when you want to make exceptions to a more general pattern.
# Any file with the name `.env`, including in subdirectories
.env
# All files with the `.tmp` extension.
*.tmp
# If you want to restrict to the current directory
/config.sample
# The `tmp` directory and its content
/tmp
# An exception is allowed for the log directory: the `.keep` file.
# To do this, you must allow the `log` directory
!/log
# However, you don't allow the files it contains, nor its subdirectories
/log/*
# …except for the `.keep` file
!/log/.keep
My files were already versioned
You may one day face the odd situation where you want to ignore files that are already versioned. Adding the rule to the .gitignore
is not enough, your changes still appear, available to add 😨. You need to “remove” the file from version control. Of course, Git has a command for that:
git rm --cached file-to-remove-from-git
Git records the deletion of the file, but leaves it in the working directory (that’s the whole point of the --cached
option). So you keep your file, but now it’s considered excluded (if you added the rule in the .gitignore
).
Be aware that the entire history of the file remains in Git. You just stop versioning it from now on. If you want to purge it entirely from the repo’s history, my advice is:
- ask yourself whether it is really useful?
- If so, then use a tool to rebuild the entire project history: filter-repo.
I want to add an ignored file
You have two options:
- Either you change the ignored patterns in the
.gitignore
file, possibly using a negation (as seen in the example syntax); - Or you force the addition with a
git add --force
.
As I explained before, if a file is versioned, the .gitignore
no longer impacts it. So by forcing the add once, you don’t have to worry about missing out on later changes.
.gitignore
templates
You can imagine that we generally use the same project bases, editors, operating systems. It follows that you will find the same patterns to ignore from one project to another.
There are ways to easily compile relevant ignore pattern lists. We explain it all in this complementary protip.
Want more tips and tricks?
We’ve got a whole bunch of existing articles and more to come. Also check out our 🔥 killer Git training course: 360° Git!