In the working copy, the files are visible to Git as one of the following: tracked, untracked and ignored.

Ignored files are the ones that Git has been told to ignore. They are considered to be build artifacts. If you want these files to be committed, first they have to be derived from the repository source. Some examples of Git ignored files are presented below:

  • Files which are generated at runtime (for example .log, .lock),
  • Hidden system files (.DS_Store,Thumbs.db),
  • Compiled code (.o, .class) and so on.

Git ignore patterns

Git ignore files are located in a file called .gitignore. They are edited and committed by hand, as a git ignore command doesn’t exist. Git ignore files contain patterns matched against file names, with the help of which you decide to ignore or not each file. These patterns are created with the help of several symbols:

Pattern Explanation
**/logs Double asterisks are used to match directories anywhere in the repository
**/logs/debug.log Double asterisks are used to match files based on their name and the name of their parent directory.
*.log An asterisk matches zero or more characters.
*.log !important.log Exclamation mark negates pattern. The file will not be ignored, if it matches not only a pattern, but also a negating pattern, that has been defined to the file later.
*.log !important/*.log trace.* Any previously negated file will be re-ignored by the patterns defined after a negating pattern .
/debug.log The slash matches files only in the repository root.
debug.log By default, patterns match files in any directory.
debug?.log The question mark matches just one character.
debug[0-9].log Square brackets are used to match a single character from a particular range.
debug[01].log Square brackets match a single character form the particular set.
debug[!01].log The exclamation mark is used to match any character except one from the particular set.
debug[a-z].log Ranges can be numeric or alphabetic.
logs The pattern will match both files and the contents of directories with that name if it isn’t used with a slash.
logs/ Using a slash points out that the pattern is a directory. The whole content of any directory with its files and subdirectories in the repository which matches that name will be ignored by Git.
logs/**/debug.log A double asterisk matches zero or more directories.
logs/*day/debug.log Asterisks can be used in directory names too.

Here is an example with one of these patterns:

#but not

Shared .gitignore files in the repository

You can define several .gitignore files in different directories in the repository. Each of the patterns is tested relative to the directory that contains that file. However, the simplest way is to define a single .gitignore file at the root of the repository.

As your .gitignore file is checked in, in your repository it is versioned like other files and is shared with your team when you push. You should only include patterns in .gitignore to benefit other users of the repository.

Personal rules for Git ignore

Personal ignore patterns can also be defined for a particular repository in a special file at .git/info/exclude. It is an appropriate place to include patterns beneficial only for you, as these are neither versioned, and nor distributed with your repository.

Global Git ignore rules

You can define the Git core.excludesFile property to additionally specify global Git ignore patterns for all repositories on your local system. This file is going to be created by yourself. You can put your global .gitignore file at your home directory to find it easily. Once you've created the file, configure its location with the git config command, like this:

touch ~/.gitignore
git config --global core.excludesFile ~/.gitignore

Ignoring a previously committed file

For ignoring a file that has been committed previously, it should be deleted from the repository. Then you should add a .gitignore rule for it. With the help of --cached option with git rm, the file will be deleted from the repo but will remain in the working directory as an ignored file. However, if you want it to be deleted from the working directory too, just leave out the --cached option.

echo debug.log >> .gitignore
git rm --cached debug.log
#rm 'debug.log'
git commit -m "Start ignoring debug.log"

Committing an ignored file

The ignored file can be committed to the repository with the combination of the -f (or --force) option with git add. However, choose this way in case you have a general pattern, such as *.log, but you want to commit a specific file:

cat .gitignore
# *.log
git add -f debug.log
git commit -m "Force adding debug.log"

If not, the simplest way is setting an exception to the general rule:

echo !debug.log >> .gitignore

cat .gitignore

git add debug.log
git commit -m "Adding debug.log"

Stashing an ignored file

The git stash command takes uncommitted both staged and unstaged changes, saves them away for further use, and then returns them from your working copy. By default, it ignores ignored files and stashes only the changes tracked by Git. But the --all option will make this command stash changes to the files that are ignored and untracked.

Debugging .gitignore files

In case of complicated .gitignore patterns, or the ones throughout multiple .gitignore files, it can be difficult to find out the reason why a particular file is being ignored. The git check-ignore command with the -v (or --verbose) option determines which pattern is causing a particular file to be ignored:

git check-ignore -v debug.log
#.gitignore:3:*.log debug.log

Here is the output:

<file containing the pattern> : <line number of the pattern> : <pattern> <file name>

Practice Your Knowledge

Which statements accurately describe the functionalities and rules of `.gitignore` files in Git?

Quiz Time: Test Your Skills!

Ready to challenge what you've learned? Dive into our interactive quizzes for a deeper understanding and a fun way to reinforce your knowledge.