When to use leading slash in gitignore
GitGitignoreGit Problem Overview
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:
- If the pattern does not contain a slash (or it contains only a trailing slash, which means that it should match a directory), the search is performed inside the entire directory tree. For example, the pattern
dir/
will match<root>/dir
,<root>/a/dir
,<root>/a/b/c/.../dir
, etc., where<root>
is the location of the.gitignore
file. - If the pattern contains a slash, which is not in the trailing position (it's not the last character), then it is matched only with pathnames relative to the
.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.
Git Solutions
Solution 1 - Git
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
Solution 2 - Git
You've answered your own question entirely. If you look at the github/gitignore repo more closely, you'll see most files use inconsistent rules about how patterns are written; it's very likely most were contributed by people who didn't bother to read the documentation nor test things out as you did.
So if that helps: You're right, be confident.
If you see mistakes in collaborative projects such as this, don't hesitate to contribute your knowledge. There's even some precedent if you need to build up your confidence further.