Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gitignore: Understanding "hello/" vs. "hello/*"

Tags:

git

gitignore

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.

like image 300
stackoverflowuser Avatar asked May 25 '14 15:05

stackoverflowuser


People also ask

What does asterisk mean in Gitignore?

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.

Can Gitignore have comments?

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.

What should I ignore in Gitignore?

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.

Should Pycache be in Gitignore?

__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.


2 Answers

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.

like image 66
Paul Draper Avatar answered Sep 23 '22 15:09

Paul Draper


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 depth

fnmatch 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.

like image 42
VonC Avatar answered Sep 22 '22 15:09

VonC