Git忽略目录和目录/ *有什么区别?

时间:2014-09-08 00:03:33

标签: git gitignore notation dotfiles

我对在git中忽略目录内容的正确方法感到困惑。

假设我有以下目录结构:

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

将这个:

之间的区别是什么?
www

这个?

www/*

我提出这个问题的原因是:在git中,如果目录为空,git不会在存储库中包含这样的空目录。所以我正在尝试在目录下添加一个额外的.gitkeep文件的解决方案,这样它就不会是空的。当我尝试该解决方案时,如果在.gitignore文件中,我写的如下:

www
!*.gitkeep

它不起作用(我的意图是忽略www下的所有内容但保留目录)。但是,如果我尝试以下内容:

www/* 
!*.gitkeep

然后它的作品!所以我认为这两种方法之间必然存在一些差异。

4 个答案:

答案 0 :(得分:196)

wwwwww/www/*之间存在差异。

基本上从documentation和我自己的测试www找到与文件或目录的匹配项,www/只匹配一个目录,而www/*匹配www内的目录和文件。

我将在此讨论www/www/*之间的差异,因为wwwwww/之间的差异很明显。

对于www/,git会忽略目录www本身,这意味着git甚至不会查看内部。但是对于www/*,git会检查www中的所有文件/文件夹,并使用模式*忽略所有文件/文件夹。它似乎导致相同的结果,因为如果忽略所有子文件/文件夹,git将不会跟踪空文件夹www。事实上,对于www/www/*独立的OP案例,结果无差异。但如果它与其他规则相结合,它确实会产生差异。

例如,如果我们只想包含www/1.txt但忽略www内的所有其他内容会怎样?

以下.gitignore无效。

www/
!www/1.txt

以下.gitignore有效,为什么?

www/*
!www/1.txt

对于前者,git只会忽略目录www,甚至不会再查看内容以再次包含www/1.txt。第一个规则排除了父目录www,但不排除www/1.txt,因此www/1.txt不能再次包含“ ”。

但是对于后者,git首先忽略www下的所有文件/ folers,然后再次包含其中一个www/1.txt

对于此示例,文档中的以下行可能会有所帮助:

  

可选前缀“!”否定了这种模式;任何匹配的文件   被先前模式排除的将被再次包括在内。它不是   如果该文件的父目录是,则可以重新包含文件   排除。

答案 1 :(得分:8)

我只是解析文档,据我所知,他们只是在更高级的模式上有所不同,例如。

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

进行了上述测试,如果您将!/foo替换为!/foo/*,确实会得到不同的结果。

请注意

foo

将排除任何文件foo,但

foo/

只会排除名为foo的目录。

答案 2 :(得分:3)

除了您已经获得的完美答案外,您应该注意到项目中的任何地方都可以.gitignore,包括子文件夹。

因此,如果您要忽略www内的所有文件,但要对www文件夹进行版本控制,而不是使用空的.gitkeep.dummy或其他任何名称你选择,为什么不在那里使用.gitignore,告诉忽略所有文件?

/
|- .gitignore   (a)
\- www
    |- .gitignore   (b)
    |- 1.jpg
    \- 2.jpg

在根.gitignore(a)中,您没有说明www文件夹或其内容。

www/.gitignore(b)中,您提出以下内容:

# ignore all files in this folder except this .gitignore
*
!.gitignore

这样一切看起来都更有条理(至少对我来说)。

答案 3 :(得分:1)

要忽略除dotfiles之外的目录中的所有内容,您可以在.gitignore中使用以下glob-pattern:

www/[^.]*

因此无需额外.gitignore,只需将.keep文件添加到www目录即可。