c# - 从 gitignore 过滤文件和路径

标签 c# git gitignore

我想使用 C# 查找所有由 .gitignore(或子目录中任何嵌套的 .gitignore 文件)过滤的文件路径。这类似于 question here关于PHP。我想知道是否有人知道这段代码是否已经在网上某个地方可用(在 C# 中)。

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

最佳答案

嗯,解析.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将打印出 --non-matching文件仅在 --verbose模式,因为它仅在该模式下打印出额外信息,告诉您文件是否被忽略。 (它总是打印被忽略的文件。)路径以格式每行出现一个

source:linenum:pattern<TAB>path

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

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

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

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

注意事项

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

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

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

关于c# - 从 gitignore 过滤文件和路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32506510/

相关文章:

ruby - 如何使用 Ruby 解析特定文件的 git diff?

c# - 绑定(bind)到类成员

git - IntelliJ git checkin 将文件模式设置为 +X

php - 我如何告诉 Composer 对给定的 Composer 存储库使用哪个 key ?

git - 如何阻止 Git 中某些特定类型的文件提交?

github - 为什么将 Jekyll 站点的 _site-directory 放在 .gitignore 中?

git ignore vs. exclude vs. assume-unchanged

c# - 使用前端 Controller 和 IIS 提供静态文件的方法?

c# - 为什么使用 Google Cloud Firestore 1.0.0-beta05 C# SetAsync 时会出现 Grpc.Core.RpcException StatusCode=Unavailable, Detail ="Connect Failed"?

c# - 调用线程无法访问此对象,因为另一个线程拥有它。即使在使用调度程序之后