Here is the content of my current directory.
$ ls
foo.foo
$ ls -a
. .. .bar.foo .foo foo.foo .gitignore
Then I turn this directory into a git repository.
$ git init
Initialized empty Git repository in /home/lone/foo/.git/
$ ls -a
. .. .bar.foo .foo foo.foo .git .gitignore
Here is the content of .gitignore
.
$ cat .gitignore
*.foo
I see that the pattern in .gitignore
behaves differently from the same pattern in shell. In the shell *.foo
matches only non-hidden files, i.e. filenames that do not begin with a period.
$ echo *.foo
foo.foo
But *.foo
in .gitignore
seems to match any files, hidden or non-hidden, that ends with .foo
.
$ git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
nothing added to commit but untracked files present (use "git add" to track)
Where can I learn more about the precise definition of the patterns that .gitignore follows, so that I can understand where and why its behaviour differs from that of the shell glob patterns?
gitignore
use of '*
' follows the glob convention:
Git treats the pattern as a shell glob suitable for consumption by
fnmatch
(3) with theFNM_PATHNAME
flag: wildcards in the pattern will not match a/
in the pathname.For example, "
Documentation/*.html
" matches "Documentation/git.html
" but not "Documentation/ppc/ppc.html
" or "tools/perf/Documentation/perf.html
".
The OP Lone Learner asks in the comments:
Does the shell also use
fnmatch
(3) to process glob patterns?
In that case why does*
not match zero characters before. (i.e. hidden files) but gitignore does?
Because that is a shell configuration choice.
Type (using shopt
, which is specific to bash):
shopt -s dotglob
echo *.foo
.foo foo.foo
That is using dotglob
If set, Bash includes filenames beginning with a '
.
' in the results of filename expansion. (for pattern matching)
.gitignore
simply contains entries for the pattern you wish to tell git not to track (wildcards support).
This configuration is stored at a folder level.
In there you can specify which file to ignore.
This file will apply to all the subfolders inside in a recursive way.
.gitignore
is collecting information in a commutative way:System level - (Global) for example if you are a unix user and you wish to ignore all the *.so
files for all your projects you will place it in the global file
Local - Usually will be at a project level applying for all the content of the given project.
Per folder - specific definitions for the given folder (for example - ignore password file, log file etc or any other resource you wish to ignore)
There is also a configuration property core.excludesfile
which allow you to set an ignored file to use as well.
git config --global core.excludesfile ~/.gitignore
You can also specify which files not to ignore by adding the !
before the file so it will not be ignored (read more below about the wildcards whic can be used).
To learn about the syntax you can read about it here.
You can use 3rd part tools to generate this file for you gitignore.io.
I couldn't find what in the page explains that
*
matches zero or more characters and matches hidden files too
Each line in the file can contain any pattern with the following wildcards:
?
= Matches zero or one occurrence of the given patterns.*
= Matches zero or more occurrences of the given patterns.+
= Matches one or more occurrences of the given patterns.@
= Matches one of the given patterns.!
= Matches anything except one of the given patterns.
In your comment you asked for information about the * pattern.
Here you can see that the *
ignore all files. Git doesn't care if its a hidden file or not. its simply looking for the matched pattern.
As explained above git try to match the pattern you supply in the .gitignore
file so if you wish to ignore files in an inner folder you will have to specify the inner folder. Here is a demo of the folder content and how to ignore inner files. You can see that the inner folder aa
contain file inside but since the ignore file contains the **/
pattern it will ignore all the inner folders and files.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With