hello/
ignores all folders named "hello" anywhere in my folder structure
hello/*
only ignores the folder "hello" at the top-level.
Why is this? Please point to a passage in http://git-scm.com/docs/gitignore that explains this behavior.
An asterisk " * " matches anything except a slash. The character " ? " matches any one character except " / ". The range notation, e.g. [a-zA-Z] , can be used to match one of the characters in a range.
We can also put comments in the gitignore file by just putting a # sign in front of any text that we want to be a comment in the gitignore file, maybe we want to provide the reason why we ignored something and any blank lines are simply going to be skipped.
gitignore , you can tell Git to ignore only a single file or a single folder by mentioning the name or pattern of that specific file or folder. You can also tell Git to ignore multiple files or folders using the same method.
__pycache__ is among the directories that shouldn't be pushed to remote repositories. Therefore, all you need to do is specify the directory in . gitignore file.
This may seem stange, but this allows us to match directories in multiple ways: files or directories anywhere, directories anywhere, or directories at the top level. This versatility is very useful, and can prevent having a cluttered .gitignore
.
(FYI, if you have Git 1.8.2+, you can use git check-ignore
to help debug this.)
If you put foo
, it will match all files and directories named foo
.
If you put foo/
, it will only match directories named foo
.
If the pattern ends with a slash, it is removed for the purpose of the following description, but it would only find a match with a directory. In other words, foo/ will match a directory foo and paths underneath it, but will not match a regular file or a symbolic link foo (this is consistent with the way how pathspec works in general in Git).
If you add *
, as in foo/*
, it is treated as a file glob (relative to the .gitignore
).
Otherwise, Git treats the pattern as a shell glob suitable for consumption by fnmatch(3) with the FNM_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".
Thus for foo/*
, Git will ignore all files and directories in the top-level directory foo
. It will ignore foo/dir
, foo/file.txt
, etc. (Technically, this will not ignore foo
itself, but it will ignore its children. However, since Git does not track directories, it has the same effect.)
FYI, foo/**
would have the same behavior.
My recommendation:
If you want to ignore a directory foo
at the top level, IMO it is most clear to use this rule:
A leading slash matches the beginning of the pathname. For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c".
So you can write /foo/
, and it will ignore the directory foo
at the top-level, but nowhere else.
The relevant passage is:
Git treats the pattern as a shell glob suitable for consumption by
fnmatch
, with:
*
' for the top files**
' everything inside, with infinite depthfnmatch is a function which checks whether the string argument matches the pattern argument, which is a shell wildcard pattern.
That is useful when excluding subfolders from an ignore rule, as I mention in "How to INCLUDE lib
files inside [/Libs/x64/Release]
folder in a Git repository"
Libs/**/*
!Libs/x64/Release/
That ignores everything except Libs/x64/Release
folder.
In any case, the command git check-ignore -v
is very useful to check which .gitignore
rule applies for any particular file.
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