Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between Git ignoring directory and directory/*?

I'm confused about what's the correct way to ignore the contents of a directory in git.

Assume I have the following directory structure:

my_project        |--www            |--1.txt            |--2.txt      |--.gitignore 

What's the difference between putting this:

www 

And this?

www/* 

The reason I'm asking this question is: In git, if a directory is empty, git won't include such empty directory in repository. So I was trying the solution that is add an extra .gitkeep file under the directory so that it won't be empty. When I was trying that solution, if in the .gitignore file, I write like below:

www !*.gitkeep 

It doesn't work(My intention is to ignore all contents under www but keep the directory). But if I try the following:

www/*  !*.gitkeep 

Then it works! So I think it must has some differences between the two approaches.

like image 243
Aaron Shen Avatar asked Sep 08 '14 00:09

Aaron Shen


People also ask

What does it mean for Git to ignore a file?

gitignore file is a text file that tells Git which files or folders to ignore in a project. A local . gitignore file is usually placed in the root directory of a project. You can also create a global . gitignore file and any entries in that file will be ignored in all of your Git repositories.

Can you git ignore a folder?

. gitignore is a plain text file in which each line contains a pattern for files or directories to ignore. It uses globbing patterns to match filenames with wildcard characters. If you have files or directories containing a wildcard pattern, you can use a single backslash ( \ ) to escape the character.

Does Gitignore apply to subdirectories?

gitignore in every subdirectory. This way you can ignore files on a finer grained level if different folders need different rules. Moreover, you can define repository specific rules which are not committed to the Git repository, i.e. these are specific to your local copy. These rules go into the file .

Where should git ignore be placed?

gitignore is located in the root directory of your repo. / will ignore directories with the name.


2 Answers

There're differences among www, www/ and www/*.

Basically from the documentation and my own tests, www find a match with a file or a directory, www/ only matches a directory, while www/* matches directories and files inside www.

I'll only discuss on the differences between www/ and www/* here, since the differences between www and www/ are obvious.

For www/, git ignores the directory www itself, which means git won't even look inside. But for www/*, git checks all files/folders inside www, and ignores all of them with the pattern *. It seems to lead to the same results since git won't track an empty folder www if all its child files/folders are ignored. And indeed the results will be no difference for OP's case with www/ or www/* standalone. But it does make differences if it's combined with other rules.

For example, what if we want to only include www/1.txt but ignore all others inside www?

The following .gitignore won't work.

www/ !www/1.txt 

While the following .gitignore works, why?

www/* !www/1.txt 

For the former, git just ignores the directory www, and won't even look inside to include www/1.txt again. The first rule excludes the parent directory www but not www/1.txt, and as a result www/1.txt cannot be "included again".

But for the latter, git first ignores all files/folers under www, and then includes one of them again which is www/1.txt.

For this example, the follwing lines in the documentation may help:

An optional prefix "!" which negates the pattern; any matching file excluded by a previous pattern will become included again. It is not possible to re-include a file if a parent directory of that file is excluded.

like image 176
Landys Avatar answered Sep 19 '22 15:09

Landys


I'm just parsing through the documentation, and as far as I can tell they only differ in more advanced patterns, e.g.

$ cat .gitignore     # exclude everything except directory foo/bar     /*     !/foo     /foo/*     !/foo/bar 

I did test the above, and if you replace !/foo with !/foo/*, you do indeed get a different result.

Note

foo 

Will exclude any file foo, but

foo/ 

will only exclude directories named foo.

like image 35
djechlin Avatar answered Sep 20 '22 15:09

djechlin