When first setting up and configuring Git, I sometimes see fellow engineers overlook — or even under appreciate — the value of your Git ignore file. Today, I want to talk about your Git ignore file both in terms of global and local configuration, the file path on your machine, and what to put in it.
Let’s start by looking at the Git’s
documentation which states you can use
core.excludesFile to configure where your ignore file is
Specifies the pathname to the file that contains patterns to describe paths that are not meant to be tracked, in addition to
.git/info/exclude. Defaults to
$XDG_CONFIG_HOMEis either not set or empty,
$HOME/.config/git/ignoreis used instead. See gitignore.
This means, by default, you can define what you want to ignore via the following files:
# Global default as specified by the XDG specification. $HOME/.config/git/ignore # Local and unique per project <your project path>/.gitignore # Local and unique per project <your project path>/.git/info/exclude
My recommendation is to put as much as you can into your global Git ignore file so you can define common directories and files in one place while reducing the maintenance burden of maintaining the same configuration across multiple projects. This can ruffle some feathers of inexperienced engineers new to your project because they might complain about multiple files showing up in their Git diff when trying to commit new changes for the first time. I look at this as an opportunity to educate and train these engineers in more of the advanced techniques of Git rather than pollute your project’s local Git ignore file. I’ll illustrate and expand upon this more in a moment. For now, let’s talk about your global ignore file first and then move on to discussing your per-project local ignore file.
As documented above, the default path of your global Git ignore is going to be located here:
The file location adheres to the XDG specification for organizing configuration files. This is a powerful specification and I encourage you to read more about XDG if you are not familiar already. I also maintain the XDG gem (same link) which allows you to leverage the XDG specification within your own Ruby code. 🎉
Should you not want to use the XDG specification — again, I would strongly discourage you from
doing this — you can always specify a custom path via the
core.excludesFile setting in your
global (or local) Git configuration.
As for what to put in your global ignore file, here’s what I use in case it’s of interest:
# Archives *.7z *.bzip *.dmg *.gz *.iso *.jar *.rar *.tar *.tar.gz *.zip # Bundler .bundle # CTags .tags .tags_sorted_by_file /tags # Databases *.dump # Environments *.env* # Logs *.log # macOS .DS_Store # SimpleCov coverage # Temp Directories tmp
As for your local ignore configuration, you have two options as stated earlier:
<your project path>/.gitignore <your project path>/.git/info/exclude
Most projects use
.gitignore because it’s safe to commit to your repository and easy for anyone
working on the same project to discover what is ignored or add to it.
You can also use
.git/info/exclude but anything you add here won’t be shared across the team as a
whole. This can be valuable when you want to ignore something that is unique to the project,
specific to you, and doesn’t effect the team. I’ve never had a need for this — yet — but your
mileage may vary.
As for what to put in your local Git ignore, that definitely depends and will evolve over time. For
example, when using Rubysmith to build a new Ruby project, you’ll see the following in your
…but if you opted to build a Ruby gem using Gemsmith, you’d get a slightly different
*.gem .bundle Gemfile.lock pkg tmp
While the above is specific to Ruby, patterns will differ per programming language used and project requirements. The one rule of thumb is that if you find you are repeating yourself, pattern-wise, then consider extracting what you have defined locally into your global ignore file.
You’ll also notice there is some duplication between what I presented in the global ignore example earlier. This was originally done to appease people new to Ruby projects but will eventually be moved to the global Git ignore configuration to improve multi-project maintenance. If nothing else, this does provide a good example of patterns ripe for deduplication.
With all of the above in mind, here are a few guidelines for you to follow:
Default to the XDG specification.
Extract common patterns to your global ignore file when possible.
When you have specific files or folders unique to you, don’t force ignoring all of these files onto the team. Use your global configuration or even
.git/info/excludewithin the project you are working on itself. This’ll empower you to be productive without adding unnecessary maintenance burden upon the team. A good example of this is IDE specific local folders like Visual Studio Code’s
As of right now, the ability to lint and encourage common patterns isn’t provided via the Git Lint gem — another gem I maintain — but I’m thinking about how to improve upon this and encourage better practices. If you have thoughts or ideas, please reach out.
I hope this dive into global and local Git ignore files has been of help to you. If you let Git do all of the heavy lifting for you, you’ll be more productive with less of a maintenance burden to boot. Enjoy!