When to use leading slash in gitignore

GitGitignore

Git 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:

  1. 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.
  2. 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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionswahneeView Question on Stackoverflow
Solution 1 - Gitsolstice333View Answer on Stackoverflow
Solution 2 - GittneView Answer on Stackoverflow