If you’ve worked with Git at all as a developer, you’ll understand the basic concept of committing and pushing code to a remote git repository. You clone the repo, make changes, commit them, and then push those changes up to the remote repository.

Maybe there are some files, however, that you don’t want to commit to version control because:

They hold secure information, such as API keys/secrets, or perhaps some username/password config data. Local settings, scripts or other configuration files that are specific to your local development environment. Generated files, including installed dependencies (lookin’ at you, node_modules/ …) that would not make sense to keep in version control. This includes things like log files. Boring system files that don’t belong in the project repository (lookin’ at you, useless .DS_Store files…) For other reasons…? Like maybe you’ve been working on some top-secret coding project that you want to keep locally for the time being or something like that…? ¯\_(ツ)_/¯

Regardless of your reason for keeping files out of Git, the standard procedure is normally to simply add them to a .gitignore file. It’s usually located at the root of your project, but you can also have a global one that is common to your whole system.

This pattern has taken shape in other places as well; for instance Javascript developers who publish code on NPM may be familiar with usage of an .npmignore which will keep specified files out when you npm publish .

You still have to commit .gitignore 👎

.gitignore works great, but at the end of the day it is still a file who’s changes must then be committed & pushed to the remote repository. Okay, so you could technically just keep it locally, however generally you’d want the same files to be excluded from all contributors’ code, so it would probably be pushed like any other committed file in the repo.

This is fine for 99% of circumstances, however I ran into a use case the other day where I needed something excluded but did not wish to commit changes to our .gitignore , which has already been crafted to handle everything in our (large) repository very well.

I occasionally do SQL dumps of my local/dev database, and store them in a directory within one of our project repos. Not everyone in our team does this, and not everyone stores them in the same place, so I can’t just add that directory to the .gitignore t. If I did, the whole team’s ignore configuration will be affected when this really only concerns me.

As stated, this isn’t a huge deal for a one-off thing like this. If I committed that .gitignore , nothing would blow up, just maybe some other devs might ask me what I changed about it. But what happens when the rest of the team needs to start adding in their own quirky little things to .gitignore ? The situation could get ugly pretty quick.

Let’s say 🐶 from the devops team needs to add some custom scripts to .gitignore , then a few months later 🐶 decides to leave the company. A few months after that, someone reading the now-lengthy ignore file is confused about why certain files/paths are being excluded from the repository, and no one knows what implications removing them will have. We should never have hired that 🐶 guy…

A better way

Ever peek inside that .git/ directory that gets created when you clone/create a git repo? Turns out there’s a whole world in there! I know this isn’t that huge of a discovery for most people, but hey #juniordevforlife

My co-worker pointed me to the .git/info/exclude file which, much like a .gitignore file, allows you to ignore files from being staged. This keeps things nice and clean, and the best part is that you don’t commit anything in the .git/ directory, so it’s like your own personal .gitignore that no one else can see or touch!

I see you, exclude file… 👁️

I love this. For example, I oftentimes find myself creating little todo.md lists for myself in project directories, only to have to delete/ignore them when committing/pushing. Now I can keep one and just keep editing it, without accidentally committing it, and have my coworkers see it… 👀😱