从gitignore过滤文件和路径

我想找到所有使用C#在.gitignore(或子目录中的任何嵌套.gitignore文件)中过滤的文件路径。 这类似于PHP中的问题 。 我想知道是否有人知道这个代码是否已经在线提供(在C#中)。

更新:为了回答我想要的内容,我可以为某些项目运行我自己的源文件的定期备份(压缩结果),让您更加放心。 困难的部分是获得一个强大的.gitignore解析器来获取过滤后的文件路径(并排除其他路径),而不想在学习该规范时过于卷入其他人已经为我做过的事情。

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

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

如果您在运行C#代码的计算机上安装了Git,那么这个答案将适用于C#。

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

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

hWell,解析.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' \ } 

这个怎么运作

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

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

来源linenumpattern 路径

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

然后, sed命令过滤输出以仅显示被忽略文件的路径。 -n选项告诉它默认不打印输入行。 第一个替换模式仅用替换./ ,删除前导./ ,纯粹出于美学原因。 第二个替换执行实际工作,删除任何开始一行的:: (表示没有“忽略”信息),如果发生替换,则打印该行的左边是非忽略路径。

您可以进一步过滤以进行其他处理; 我为一个脚本构建了这个脚本,它按照这些行进行markdown检查:

 markdownlint $(find_nonignored | grep '\.md$') 

笔记

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

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

  3. 这里的所有代码都在带有空格或其他“exception”字符的路径上中断; 它需要在几个地方修改(例如使用-print0 with find )来解决这个问题。 我不解决这里的问题,以便简化解释。 我也留给其他人一般化的函数来处理任意路径,而不仅仅是当前的工作目录。