When you’re making commits to a GitHub repository, you select which files to stage and commit them using an add command. But what if there are certain files you don’t want committed to the repository?
Gitignore tells your Git repository on GitHub that it should ignore those files and not track them.
Step #1: Understand How Gitignore Works
Before we dive deeper into the action steps for this process, it’s important that you have a full understanding of how Gitignore works. Once you grasp the concept, the application will be much easier.
GitHub views all files as:
- Tracked — Git files that have already been staged or committed to a repo.
- Untracked — Git files that have not yet been staged or committed to a repo.
- Ignored — Files that GitHub has been specifically told to ignore.
Ignored files get tracked via Gitignore files, which are commonly placed at the root folder of a repository. Gitignore files are plain text files. Each line in the file has a pattern that tells GitHub what to ignore.
While Gitignore files are usually placed in the root, they can also be placed into any folder within the repository. It’s also possible to have multiple Gitignore files.
An ignored file usually builds artifacts from a repository source that shouldn’t be committed.
Gitignore uses glob patterns that match against different file names. Globs expand wildcard patterns with a list of path names to match specific patterns. You can construct patterns in GitHub using various symbols.
Here are some common examples of Gitignore patterns:
- **/logs — A double asterisk matches directories anywhere in a repository.
- **/logs/debug.log — This pattern matches files using both a file name and the name of the file’s parent directory.
- *.log — Using a single asterisk is for a wildcard with zero or more characters.
- *.log !important.log — Adding an exclamation point to a pattern negates it. If a file matches a pattern and a negating pattern that gets defined later in the file, the negating pattern will not be ignored. But any patterns defined after a negating pattern will ignore files that were previously negated.
- /debug.log — Preceding slashes in a pattern will only match files in the root file of the repository.
- debug.log — This pattern will match with files in any directory.
- debug?.log — Adding a question mark will match exactly one character (so debug0.log and debugg.log would both be ignored, but debug.11.log would not).
- debug[1-9].log — You can use square brackets to match with single characters within a specified range.
- debug[!05].log — Using an exclamation point within square brackets will ignore all characters except for the one succeeding the exclamation.
- debug[a-z].log — The square brackets can also be used for alphabetic ranges.
- logs — Omitting a slash from the pattern will ignore both files and directories that match the name.
- logs/ — An appending slash ignores all of the contents in a directory, including both subdirectories and all files.
All of the patterns and examples above assume that your Gitignore file is placed at the top level of a directory within a repository.
Step #2: Decide What Type of Files to Ignore in GitHub
Next, you need to figure out which files should be ignored.
Since GitHub is used to track changes, it should always be your goal to keep your commit history as clean as possible. Keeping the commits clean means you should never add files that could create unnecessary confusion or problems. Excluding files that aren’t needed specifically for the project is also a good idea.
Obviously, the Gitignore files will vary from project to project. But here’s a good rule of thumb to help you decide which type of files should be added to Gitignore:
- Any file that is not needed for the project
- Any file that is not needed by other people on your team
- Any file that was generated through another process
With this in mind, let’s take a closer look at some common file types that fall into these categories:
- Operating System Files — System operating files for Mac, Linux, or Windows are used for display purposes for your own computer. Things like .DS_Store or Thumbs.db files do not have any impact on your project, and everyone on your team already has OS files on their own computers. Committing OS files to your GitHub project ends up adding unnecessary changes to your commit history, which is why it’s best to ignore them.
- Application Files — Similar to system files, application files for the apps installed on your computer are not required for GitHub projects. It’s very unlikely that anyone on your team would need these files either to collaborate on the project.
- Framework and Language Files — This refers to any file that is generated or required by the frameworks and languages you’re using on your project. These are not required for you or by anyone on your team for functional project use. They can be ignored.
- Package Manager Files — Frontend package managers like npm and Bower make it possible for you to quickly download libraries from the web. Since these files can also be downloaded quickly and easily by anyone else with a single command, you typically do not need to include them in your GitHub commits.
- Credential Files — Always ignore credential files like usernames and passwords. Otherwise, you could have your credentials for WordPress databases or similar resources with sensitive information get committed to a public GitHub repository.
These are somewhat broad categories for what you should ignore. To get a bit more specific, GitHub has a resource of recommended files for Gitignore:
You can refer to this resource for other recommendations or check your file types against this list if you’re on the fence about what to do with them.
It’s also important to understand that you shouldn’t just add Gitignore rules that benefit yourself. Think about the other users in the repository. If the Gitignore patterns don’t benefit your teammates, you probably shouldn’t add those patterns to the Gitignore file.
Step #3: Add Ignored Files to Your Repository Settings
One easy way to add files to Gitignore on GitHub is directly through your repository settings.
From your GitHub Desktop application, navigate to the Repository menu at the top of the page. Then select Repository Settings to continue.
Click on the Ignored Files tab, and add the files you want to ignore.
From here, you can simply add file names, directory names, or the Gitignore patterns based on your goals.
If this is your first time adding ignored files to your repository settings, you’ll see a change staged for the repository. That’s because a Gitignore file did not exist until now. You still need to commit these changes to your repository to ensure GitHub knows to continue ignoring those files from your previous commits and commits moving forward.
You can also create a Gitignore file using the command line. Just navigate to the local of your Git repository in your terminal, then enter the following command: $ touch .gitignore
A successful command entry will not yield any output in the terminal.
If you want to ignore files that have already been checked in, you need to untrack the file before adding rules to ignore it.
Step #4: Configuring the Global Gitignore File
Global Gitignore files contain all the rules to ignore Git repositories on your computer. This is the best location to ignore operating system files and application files.
You can create a global Gitignore file using this command: $ touch ~/.gitignore_global
Then open the newly created file using this command: $ open ~/.gitignore_global
From here, you can paste your Gitignore pattern rules for OS files and application files.
Now you just need to process the Gitignore global file using your GitHub configuration.
Step #5: Configuring the Local Gitignore File
Local Gitignore files live in the root of your project folder. This contains all of the Gitignore rules for other categories, like framework files, language files, package manager files, credential files, and more.
You can add these files in .git/info/exclude for your local repositories.
It’s also worth noting that many people don’t know about the global Gitignore file. So you’ll sometimes see application files and OS files there. If that’s the case, it’s in your best interest to remove them from the local file to keep those out of your project.
You can continue to edit your local Gitignore file as needed throughout the project. Each new line entry in this file will list files and folders that you want GitHub to ignore in your repository.
Common Problems When Adding a File to Gitignore On GitHub
Adding files to Gitignore on GitHub is fairly straightforward. With that said, some of these ignore patterns can get complex at scale, especially if you’re working with a larger team and everyone is adding files to Gitignore.
We’ll take a look at some of the most common problems and pain points with this process, along with simple tips for troubleshooting them.
Problem #1: Staying Organized
Not every developer is super familiar with Gitignore patterns. If you fall into this category, you may not understand exactly what your Gitignore commands mean at first glance.
If there are only one or two patterns in the file, then you’ll likely remember what you added and why you added it. But what if you have 15 or 25 lines? This could be tough to track at scale and lead to a messy commit history.
Rather than having to refer back to a Gitignore pattern cheatsheet every time you look at the file, you can simply add comments to the Gitignore file that explains what you’re doing in plain English.
For example, you could add a note using # in Gitignore that looks like this:
# Ignore Mac OS Files
This is a fairly simple example. But you can always reference your notes when you’re looking at the Gitignore file to see exactly what you’re ignoring and why.
Problem #2: Excluding Local Files Without Creating a Gitignore File
In some cases, you may not want to share a Gitignore file with other people on your team. But you can still ignore local files without a shared Gitignore file in GitHub.
You just need to create rules without committing them to your repository.
Open your text editor and find the following file in the root of your Git repository: .git/info/exclude
Any rules added here will not be checked in. This will only ignore files in your local repository, and won’t be added to a Gigignore file.
Problem #3: Ignoring Nested Files
Let’s say you have a directory structure that looks like this:
You want to ignore everything in .standings/data but not .standings/plots.
If there are just two subfolders in the directory, you can just add the one you want to ignore to your Gitignore file. But if there are dozens, doing this for each one doesn’t make much sense.
Instead, you’re better off using exception patterns, with an exclamation point.
So you could add *.standings to your Gitignore file. But then add another line for !final.standings.
This would tell GitHub to ignore all standings data, except for your final standings subfolder.
Problem #4: Order of Rules
You must pay close attention to the order of your rules when you’re adding patterns to your Gitignore file. Certain patterns will negate previously ignored files.
Let’s look at a basic example.
The first entry tells GitHub to ignore all of your .data/results files. But the second entry negates it.
Now none of the .data/results files will be ignored. This is fairly obvious when the two patterns are listed consecutively. But if they are spread far apart within the Gitignore file, you might accidentally negate previous rules with a new pattern.
This is another reason why it’s very helpful to add comments using # whenever you’re making changes to the Gitignore file. Then you can quickly refer to those comments before making new changes, ensuring that you’re not accidentally negating something that should be ignored.