I'm trying to understand more clearly the .gitignore
syntax, and in particular as far as https://github.com/github/gitignore gitignores are concerned.
I see that the leading slash is used to match only pathnames relative to the location of the .gitignore
file (from http://git-scm.com/docs/gitignore):
A leading slash matches the beginning of the pathname. For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c".
But what happens when i remove the leading slash? As far as what i understood, there are two cases:
dir/
will match <root>/dir
, <root>/a/dir
, <root>/a/b/c/.../dir
, etc., where <root>
is the location of the .gitignore
file..gitignore
file location.These are the examples i made to check this behaviour:
# Directory structure:
<root>
├─ dir/
│ └─ test
├─ src/
│ ├─ dir/
│ │ └─ test
test file is there only because Git does not track empty directories.
First test:
# .gitignore
dir/
# git status
nothing to commit
So Git is ignoring both dir
directories. This is consistent with case number 1: the pattern has no slashes (except for the trailing one), so Git is watching the entire directory tree, ignoring everything that matches the pattern.
Second test:
# .gitignore
/dir/
# git status
Untracked files:
src/
Here, Git is ignoring only the dir
directory directly beneath the root directory, thanks to the leading slash in the pattern.
Third test:
# .gitignore
dir/*
# git status
Untracked files:
src/
This is consistent with the case number 2: the pattern has some slash inside it, so it is considered as a pathname starting from the root directory.
Now it's time for the real question. Let's consider this gitignore file: when they ignore the directory downloader/
, for example, aren't they actually ignoring every single downloader
directory found in the entire directory tree? This is what i'm driven to think since what i saw about Git's workings before.
So if i happen to have a custom module with a downloader
directory inside of it, will it be unexpectedly ignored as well as the regular one in the root of Magento? This is a bit of a rethorical question because it actually already happened to me, producing a really hard to find bug.
So, in the Magento .gitignore
file (which i'm referring to only as an example, btw) a lot of the patterns contain slashes, so they are correctly matched against pathnames starting from the root, but there are a few cases, like downloader/
or errors/
that, if i'm not mistaken, are potentially dangerous, and which should probably be changed to /downloader/
and /errors/
.
As a more general question, should i always use the leading slash for patterns not containing slashes (except for the trailing one) when i want to select a pathname explicitly starting from root, and not to use it for patterns containing slashes, or should i always use the leading slash for clarity? What do you think about it?
Thank you for reading and sorry for the long post.
Just wanted to summarize for possible quick future reference -- the leading slash anchors the match to the root. Thus, in the example below, without the slash, the wildcard would also exclude everything within foo because it would take *
and move recursively down the tree. However, with /*
, it excludes everything except folder foo and its contents:
$ cat .gitignore
/*
!/foo