Git中的白名单和子目录

110

我已为纯文本文件创建了一个白名单。

*
!*.txt

现在,我有一个未被跟踪的文本文件在子目录中 - sub/dir/file.txt,但它没有显示出来(被忽略了)。而根目录中的文本文件是可以显示的。

为什么会这样,我应该怎么解决?


1
相关链接:https://dev59.com/rHNA5IYBdhLWcg3wX8rk - johnsyweb
是的。这些文件将与我的示例中的11.1.102.55文件夹结构一样低。文件夹/产品之间的嵌套并不总是相同的。 - Nate
1
我知道这个功能。我们有数百个目录。与其为每个目录制作一个gitignore文件,忽略我们不想要的文件类型会更快。我真的在寻找一种从.gitignore文件中获取白名单功能的方法。 - Nate
1
我不认为这是一个重复的问题。另一个问题询问如何将某些文件列入白名单,而这个问题询问如何将包括子文件夹在内的某些文件类型列入白名单。实际上,这更像是 https://dev59.com/tmsz5IYBdhLWcg3wQFYq 的重复。 - Big McLargeHuge
@davidkennedy85 我编辑了这个问题以突出差异,并标记为重新开放。 - sashoalm
显示剩余4条评论
4个回答

176
如果您这样尝试,它会失败,因为您最终会把结构中的目录列入黑名单。
解决方法是,要列入黑名单的是不是目录,并且不是您想提交的文件类型之一,同时不列入目录的黑名单。
下面是能够实现此功能的.gitignore文件:
# First, ignore everything
*
# Now, whitelist anything that's a directory
!*/
# And all the file types you're interested in.
!*.one
!*.two
!*.etc

在存在于代码库根目录下的一个 .gitignore 文件中,我使用三级结构的白名单针对后缀为 .txt 的文件进行了测试,此时有 *.one*.two*.three 文件 - 对我而言有效。您不必将 .gitignore 文件添加到您结构中的所有目录中。

我用来找到答案的信息包括来自这里(stackoverflow.com)等等。


22
使用 * 时,您也需要输入 !.gitignore 吗? - sjas
3
请看我在这里的回答:https://dev59.com/rHNA5IYBdhLWcg3wX8rk#29932318 为了更好地使用,使用 /* 可以将顶层文件夹列入黑名单,但不递归所有文件夹。这意味着 .gitignore 不应查看白名单文件夹的子文件夹。 - Ryan Taylor
当我在 .gitignore 文件的第二行使用 * 忽略一切时,然后使用符号 !./directory/!./file 取消对文件和目录的忽略,并尝试将这些文件和目录添加到 git 中时,git status 仅显示文件已被暂存,但没有关于目录的信息。此外,由于某种原因,git branch 命令没有输出任何内容。但是,当我将第一个忽略模式更改为 /* 时,所有操作就如预期一样:git add 命令成功地添加了文件和目录,而 git branch 命令则输出了 master - Teemu Leisti

7
一个更简单的实现方式是:
# Ignore all files...
*.*

# ...except the ones we want
!*.txt

这是因为gitignore会将不以/开头的模式应用到.gitignore文件下的每个级别:

如果模式的开头或中间(或两者都有)有分隔符,则该模式相对于特定的.gitignore文件所在的目录级别。否则,该模式也可以匹配在.gitignore级别以下的任何级别。

如果您想对目录内的文件执行此操作,则会变得更加复杂:
# Ignore all files in all directories inside subdir...
/subdir/**/*.*

# ...except the ones we want
!/subdir/**/*.txt

这个方法有效是因为 gitignore** 有特殊规则:
  • 模式中连续出现的两个星号("**"),可能具有特殊含义:
    • 以斜杠开头,接着是两个星号,然后是一个斜杠,用于匹配零个或多个目录。例如,"a/**/b" 匹配 "a/b", "a/x/b", "a/x/y/b" 等。
关键在于确保不忽略目录,否则该目录中的所有文件都会被忽略,而不考虑其他规则。

1
*.*的注释是错误的。它应该是“忽略所有带有句点的文件/文件夹。”Glob模式不会考虑文件;只有通过在末尾添加斜杠才能使其适用于文件夹。 - MonkeyZeus

2
我搜索了很长时间:
1. 假设我有一个大的文件夹结构,其中包含递归嵌套的约100,000个目录。在这些文件夹中,大约有30,000个类型为.txt的文件(在我的情况下:类型为*.md)。除了这些*.md文件外,还有大约500GB的(一百万+)不想跟踪的文件。
2. 我希望git只跟踪所有文件和子目录中的.txt(或*.md)文件。
正确的答案应该是:Git中不可能实现这一点。 我所做的是:
编辑:也没有成功 - 我尝试创建一个带有符号链接(或硬链接)的文件夹,然后在那里使用git,但git不会跟随符号链接并覆盖硬链接。糟糕!

0
如果您想忽略存储库中除了.txt文件之外的所有内容,那么.gitignore应该如下所示:
# Ignore everything
*
# Whitelist every directories, so we can recurse into them
!*/
# Whitelist .gitignore and .txt
!.gitignore
!*.txt

但是,如果您想要忽略存储库中的一个文件夹并在任何目录或子目录中列出.txt文件:

# Recursively ignore every files in my_folder
/my_folder/**
# Recursively whitelist every directories in my_folder
!/my_folder/**/
# Whitelist .txt
!*.txt


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接