我对在git中忽略目录内容的正确方法感到困惑。
假设我有以下目录结构:
my_project
|--www
|--1.txt
|--2.txt
|--.gitignore
将这个:
之间的区别是什么?www
这个?
www/*
我提出这个问题的原因是:在git中,如果目录为空,git不会在存储库中包含这样的空目录。所以我正在尝试在目录下添加一个额外的.gitkeep文件的解决方案,这样它就不会是空的。当我尝试该解决方案时,如果在.gitignore文件中,我写的如下:
www
!*.gitkeep
它不起作用(我的意图是忽略www下的所有内容但保留目录)。但是,如果我尝试以下内容:
www/*
!*.gitkeep
然后它的作品!所以我认为这两种方法之间必然存在一些差异。
答案 0 :(得分:196)
www
,www/
和www/*
之间存在差异。
基本上从documentation和我自己的测试www
找到与文件或目录的匹配项,www/
只匹配一个目录,而www/*
匹配www
内的目录和文件。
我将在此讨论www/
和www/*
之间的差异,因为www
和www/
之间的差异很明显。
对于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
目录即可。