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:
|**/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.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:
debug0.log debug1.log #but not debug10.log
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 #*.log #!debug.log 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>