不忽略特定深度嵌套文件集的更简单方法

Easier way to not-ignore a specific deeply nested set of files

我有很深的嵌套文件,我想将其包含在源代码管理中并让 git 跟踪它们。

例子是:

Projects/
    .git/
    StrategicProject/
        SpecificProject1/
            Method1/
                doc/
                   *.tex
    .gitignore

在每个不同的文件夹中还有其他 files/folders 我不想跟踪。我只想跟踪 Projects/StrategicProject/SpecificProject1/Method1/doc/

中的所有 .tex 文件

截至目前,要完成此操作,我的 .gitignore 文件中有:

StrategicProject/* # ignore everything under this, exceptions below
!StrategicProject/SpecificProject1/ # don't ignore this
StrategicProject/SpecificProject1/* # ignore everything under this, exceptions below
!StrategicProject/SpecificProject1/Method1/ # don't ignore this
StrategicProject/SpecificProject1/Method1/* # ignore everything under this, exceptions below
!StrategicProject/SpecificProject1/Method1/doc/ # don't ignore this
StrategicProject/SpecificProject1/Method1/doc/* # ignore everything under this, exceptions below
!StrategicProject/SpecificProject1/Method1/doc/*.tex # don't ignore this

上面的方法有效,但是当我在我的工作目录中创建一个新的文件夹结构时容易出错。这也很麻烦。要跟踪嵌套文件夹中的一组 .tex 文件,需要在 .gitignore 文件中创建 8 行。一位 SO 用户创建了一个网络应用程序来缓解这个特定的困难 activity。参见 here

虽然该应用目前运行良好,但它只能在网络上运行。更一般地说,是否有一个 gui 应用程序,可以离线工作(无需使用互联网),可以查看我的文件夹结构并允许我 check/uncheck 框(作为其用户界面的一部分)对应于files/folders 并基于此自动生成适当的 .gitignore 文件?


预计到达时间:

我使用 VSCode 的默认 Git 界面。虽然这确实提供了右键单击文件并将其添加到 .gitignore 的选项,但这不是我想要的。我想 而不是 忽略一组特定的深度嵌套文件。我愿意尝试使用其他编辑器来完成这项任务。

仅包括深度嵌套的文件集:

通过 .gitinclude

生成规则(离线)

因为这个问题,我打开了一个 GitHub 存储库来尝试拥有一个 .gitinclude 文件的想法,并让命令行应用程序在 .gitignore 中生成一个部分文件:https://github.com/gitinclude/gitinclude.NET

可通过存储库自述文件中的链接下载 windows、linux 和 osx 的可执行文件。

或者:在deep子目录下再添加一个.gitignore文件

请注意,如果您发现拥有多个 .gitignore 文件没问题,您可以忽略一个 .gitignore 文件中的文件夹,然后 not-ignore 通过 [=13] 几个文件=] 文件放在这些文件所在的深层子文件夹中。那只需要 2 个规则而不是 8 个。

或者:按照 torek

的建议使用 !*/
StrategicProject/*
!StrategicProject/SpecificProject1/Method1/doc/*.tex

!*/ # tell git to look in all folders, even ignored ones, on the last line of your .gitignore file

您可以使用一种有用但计算量大的技巧。如您所见,如果您忽略一个目录,Git 永远不会查看 目录内部 ,从而无法 un-ignore 嵌套在该目录下更深的文件。这通常可以节省 Git 很多时间:git status 必须递归地查看工作树中的所有内容, 除了 每次它遇到一个被忽略的目录时,它不必看那里的 任何东西。由于在工作树的递归旅行中 lstat-ing 每个目录中的每个实体通常是 最慢的 部分 Git working-tree 操作,绕过其中一些调用会有很大帮助。

不过,您可以通过简单地确保 !*/ 是每个 [=16= 中的 last 条目来完全防止 Git 绕过目录] 文件。无论 Git 在其遍历的哪个位置,最后一个条目都会说 如果您遇到一个目录,请查看其中 。现在你不再需要小心和明确的东西,比如:

StrategicProject/*
!StrategicProject/SpecificProject1/
StrategicProject/SpecificProject1/*
!StrategicProject/SpecificProject1/Method1/
StrategicProject/SpecificProject1/Method1/*
!StrategicProject/SpecificProject1/Method1/doc/
StrategicProject/SpecificProject1/Method1/doc/*
!StrategicProject/SpecificProject1/Method1/doc/*.tex

因为您可以简单地列出应该忽略的文件; Git 将永远到处寻找。

提议的未来增强(未实施)

我认为 Git 应该 根据需要自动插入 异常。也就是说,我们应该可以这样写:

*.o
generated-docs
!generated-docs/*.in

和Git应该弄清楚这个“意思”,例如:

generated-docs/*
!generated-docs/*.in

也就是说,我们在generated-docs中排除了某些东西这一事实意味着Git应该看里面 generated-docs,尽管 默认值 是跳过可能在那里找到的文件。

至于创建和维护 .gitignore,您可能会查看适用于您的 IDE 的插件。

例如,对于 IntelliJ/PyCharm,这可能是 GUI 就足以满足您要执行的操作: https://plugins.jetbrains.com/plugin/7495--ignore

到目前为止,对于您的示例,最简单的是

StrategicProject/**
!StrategicProject/**/
!StrategicProject/SpecificProject1/Method1/doc/*.tex

我的发音是“递归地排除 StrategicProject 中的所有内容,但仍然扫描所有目录以查找更多异常,例如这些 tex 文件”。


除非或直到你有一个非常大和复杂的源代码树,否则放置类似

的东西通常更紧凑
!*/
build/

在你的 .gitignore 的末尾简单地关闭所有目​​录排除,除了这里的任何 build 目录,我会称之为惯用的,一些人之前已经看过它明白了。