Sometimes you don’t want git to track files in a repository. Maybe you’re working on a Java project and you want Git to silently ignore all files ending in .class. Or maybe it’s a C program and you want Git to ignore *.o. Either way, there are two ways to accomplish this.

The gitignore file

Git has a few special files that you can use to affect how Git operates. One of these is the .gitignore file. A .gitignore file can be placed in any directory in your repository. It will affect all files which reside in that directory.

The .gitignore file should be committed to the repository. It will affect everyone, since it is part of the repository itself.

Most repositories only have a single .gitignore file in the project root.

Syntax

Inside the .gitignore file is a list of patterns which describe files to ignore. The full pattern format is listed in the gitignore(5) manual page.

Example 1

Here’s a very short example gitignore:

*.class
*.jar
!/lib/*.jar

This file is for a Java project. Its purpose is to ignore generated files (i.e. files produced by a compiler which are not part of the code).

The first line ignores all files ending in .class.
The second line ignores all files ending in .jar.
Finally, the third line un-ignores all files in the lib directory which end in .jar. Since the line starts with an exclamation mark (!), it has the opposite effect, allowing the files instead of ignoring them.

However, the third line does not allow .jar files in subdirectories of the lib directory. So lib/myawesomelib.jar would be seen by Git, but lib/net/httplibrary.jar would be ignored.
If you want to allow all .jar files in all subdirectories of lib as well, you’d need to use the following rule:

!/lib/**.jar

Two consecutive asterisks (**) means it matches anything, even slashes, which represent directory separators. A single asterisk (*) matches everything except separators.

Example 2

Below is another gitignore file. It’s designed to be used in a C project.

*.o
*.a
/*.so
*.dll
*.out
*.exe
# This is a comment
/build

It ignores lots of file extensions.

However, you may have noticed that the line containing *.so begins with a slash (/). Why is that?

Well, if there’s a slash anywhere except the end of a line, it means to treat that line relative to the directory the .gitignore file is in. So if this gitignore file is in the project root, it would ignore test.so, but not lib/test.so.

The .git/info/exclude file

Sometimes you’ll want to ignore some files that are specific to your workflow, but you don’t want to add them to the project’s gitignore file. What should you do?

Git has a special file for that. It is located at .git/info/exclude.

This file uses the same syntax as a gitignore file, but is local to your repository only. It doesn’t get committed or shared.