从 gitignore 过滤文件和路径

Nic*_*sen 5 c# git gitignore

我想使用 C#查找所有未被.gitignore(或子目录中的任何嵌套 .gitignore 文件)过滤的文件路径。这类似于此处关于 PHP的问题。我想知道是否有人知道此代码是否已经在网上某处可用(在 C# 中)。

更新:为了回答我想要这个的目的,我可以为某些项目运行我自己的源文件的小定期备份(压缩结果),以增加安心。困难的部分是获得一个强大的 .gitignore 解析器来获取过滤的文件路径(并排除其他路径),如果其他人已经为我完成了该规范,则不想太忙于学习该规范。

Cur*_*son 5

好吧,解析.gitignore文件(以及 Git 使用的其他文件,例如$GIT_DIR/info/exclude)的最佳方法是让 Git 为您完成。:-)(在您的情况下,事实上,大多数情况下,这确实涉及执行 git 子进程。)

git check-ignore

git check-ignore命令可用于检测哪些文件被忽略以及为什么被忽略。该--non-matching选项还可以告诉您未被忽略的文件,但由于它仍然以特殊格式告诉您被忽略的文件,因此您需要做一些进一步的工作来获得一个简单的列表未被忽略的文件。这个 Bourne shell 函数可以解决问题:

find_nonignored() {
    find . -path ./.git -prune -o -print \
        | git check-ignore --verbose --non-matching --stdin \
        | sed -n -e 's,\t./,\t,' -e 's,^::\t*,,p' \
}
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

find命令会查找当前工作目录中和下方的所有文件,该目录应该位于您尝试过滤的树中的某个位置。我们.git从输出中排除顶级子目录及其下的所有内容(如果存在);/.git/不在典型.gitignore文件中,因为 Git 会自动忽略它,因此通常被git check-ignore.

git check-ignore--non-matching仅在--verbose模式下打印文件,因为它仅在该模式下打印出额外信息,告诉您文件是否被忽略。(它总是打印被忽略的文件。)格式中每行出现一个路径

source : linenum : pattern <TAB>路径

以冒号分隔的字段是有关导致忽略路径的原因(例如.gitignore文件中的一行)的信息,如果文件未被忽略,则该字段将为空。

sed然后该命令过滤输出以仅显示被忽略文件的路径。该-n选项告诉它默认不打印输入行。出于纯粹的审美原因,第一个替换模式替换<TAB>./为 just <TAB>,删除前导./。第二个替换完成了真正的工作,删除::<TAB>了开始一行的任何(表示没有“忽略”信息),如果发生了替换,则打印该行的剩余部分,这是一条未被忽略的路径。

您可以进一步过滤以进行额外处理;我为一个脚本构建了这个,该脚本按照这些行进行降价检查:

markdownlint $(find_nonignored | grep '\.md$')
Run Code Online (Sandbox Code Playgroud)

笔记

  1. 此代码在输出中包含未跟踪的文件(即从未添加到 Git 存储库或暂存),这通常是您想要的。(例如,测试系统在新文件git add运行之前仍应检查它们。)请注意,涉及等的其他解决方案git ls-files通常不会这样做。

  2. 上面的代码依赖于使用 GNU sed,它解释\t为一个选项卡。如果您使用 BSD sed(例如在 MacOS 上),您可能需要稍微调整一下。检查评论,看看是否有人对此有提示。

  3. 这里的所有代码都在带有空格或其他“不寻常”字符的路径上中断;它需要在几个地方进行修改(例如使用-print0with find)来解决这个问题。为了保持解释简单,我在此不讨论此类问题。我还为其他人保留了函数的泛化以在任意路径上工作,而不仅仅是当前工作目录。

  • 这与“git ls-files --cached --others --exclude-standard”有何不同?似乎只调用一个 git 命令会更直接、更高效。 (3认同)

Nig*_*888 4

如果不确切知道您想对列表做什么(在构建脚本中使用它,以某种方式处理文件,只需在 UI 上查看它们等),就很难提出建议。

我在 C# 中找不到一个,但是这个 JavaScript gitignore 解析器没有很多要转换的代码,并且它公开了一个accepts和 一个denies方法来获取包含或忽略的文件的列表。它有相当完善的文档,有测试,并且它使用的正则表达式在 C# 中和在 JavaScript 中一样工作。

如果您在运行 C# 代码的计算机上安装了 Git,则此答案适用于 C#。

另请注意, Visual Studio 的Git 源代码控制提供程序插件在 IDE 中提供了列表,以及复选框和一起提交某些文件的功能,以及难以在命令行上执行的许多其他功能。

注意:Git 源代码控制提供程序是开源的(用 C# 编写),您可以在此处查看源代码,但它可能比 JavaScript 项目更涉及逆向工程。