tags:

views:

2614

answers:

5

I've been using git but still having confusion about the .gitignore file paths.

So, what is the difference between the following two paths in .gitignore file?

tmp/*
public/documents/**/*

I can understand that tmp/* will ignore all the files and folders inside it. Am I right? But does that second line path means?

+6  A: 

If you're using a shell such as Bash 4, then ** is essentially a recursive version of *, which will match any number of subdirectories.

This makes more sense if you add a file extension to your examples. To match log files immediately inside tmp, you would type:

/tmp/*.log

To match log files anywhere in any subdirectory of tmp, you would type:

/tmp/**/*.log

But testing with git version 1.6.0.4 and bash version 3.2.17(1)-release, it appears that git does not support ** globs at all. The most recent man page for gitignore doesn't mention **, either, so this is either (1) very new, (2) unsupported, or (3) somehow dependent on your system's implementation of globbing.

Also, there's something subtle going on in your examples. This expression:

tmp/*

...actually means "ignore any file inside a tmp directory, anywhere in the source tree, but don't ignore the tmp directories themselves". Under normal circumstances, you'd probably just write:

/tmp

...which would ignore a single top-level tmp directory. If you do need to keep the tmp directories around, while ignoring their contents, you should place an empty .gitignore file in each tmp directory to make sure that git actually creates the directory.

emk
The answer is (3): the manpage clearly says that the glob will be passed un-altered to the system's fnmatch library function. Therefore the behavior of gitignore globs is system dependent.
Jörg W Mittag
You're right--the man page does suggest case (3) is the right answer. But I've encountered quite a few cases where the git man pages are slightly out of date, so I'm not going to commit to a specific answer without reading the code.
emk
+5  A: 

This depends on the behavior of your shell. Git doesn't do any work to determine how to expand these. In general, * matches any single file or folder:

/a/*/z
 matches        /a/b/z
 matches        /a/c/z
 doesn't match  /a/b/c/z

** matches any string of folders:

/a/**/z
 matches        /a/b/z
 matches        /a/b/c/z
 matches        /a/b/c/d/e/f/g/h/i/z
 doesn't match  /a/b/c/z/d.pr0n

Combine ** with * to match files in an entire folder tree:

/a/**/z/*.pr0n
 matches        /a/b/c/z/d.pr0n
 matches        /a/b/z/foo.pr0n
 doesn't match  /a/b/z/bar.txt
John Feminella
+1  A: 

** doesn't work for me.

But you could create a new .gitignore in that subdirectory :

tmp/*/.log

can be replaced by a .gitignore in tmp :

*.log

sebastien
A: 

Just wrote post about function in git everyone wants - http://constantinz.wordpress.com/2009/08/20/git-gitignore-file-missunderstanding/

A: 

Just wrote post about function in git everyone wants - http://constantinz.wordpress.com/2009/08/20/git-gitignore-file-missunderstanding/