如何在工作树文件上应用Git clean filter?

时间:2017-12-14 10:09:03

标签: git filter

我想让Git在我的工作树文件上运行所有已配置的过滤器并打印结果输出(即将写入索引的相同内容)。有没有Git命令来做到这一点?例如,我正在寻找类似的东西:

$ git the-command-i-am-looking-for < huge-lfs-file
version https://git-lfs.github.com/spec/v1
oid sha256:60ab6bad73e833318d3ad4a186c7ea77e0cf26c1419474dd6786db1c53a366c6
size 1050624

1 个答案:

答案 0 :(得分:2)

没有Git命令可以执行此操作。

要手动执行此操作,您必须确定要将哪个过滤器应用于该文件,然后运行该过滤器。如果过滤器是旧式驱动程序,则运行它非常简单。如果它是一个新的样式驱动程序,运行它会更困难。找到它可能有点棘手,但实际上很容易。

the gitattributes manual page中记录了所有内容。要应用的过滤器是由“最佳匹配”filter=name指定的过滤器。 “最佳匹配”是最后一个,并且按顺序应用匹配,从顶级.gitattributes文件开始,在工作树中向下工作到文件的任何子目录中最近的.gitattributes文件生活在。例如,如果项目本身有:

.gitattributes
dir/.gitattributes
dir/sub/.gitattributes
dir/sub/subsub/.gitattributes

并且文件本身名为dir/sub/name.ext,我们会在.gitattributes中查找与name.ext匹配的任何模式并获取其定义:

$ cat .gitattributes
* driver=d1
*.ext driver=d2
name.* driver=d3

由于name.ext*匹配,因此第一行适用。由于name.ext*.ext匹配,因此第二行也适用。由于name.extname.*匹配,因此第三行也适用,因此到目前为止最佳匹配 d3

然后我们查看dir/.gitattributes

$ cat dir/.gitattributes
*.ext driver=d4
*.dat driver=d5

*.ext也匹配,因此目前为止的最佳匹配是d4

现在我们查看dir/sub/.gitattributes

$ cat dir/sub/.gitattributes
* driver=d6

*匹配,因此目前为止的最佳匹配是d6

有一个dir/sub/subsub/.gitattributes,但我们看不到,因为该文件位于dir/sub,而不是dir/sub/subsub。因此,申请dir/sub/name.ext的驱动程序为d6

现在我们只需找到d6的实际驱动程序,我们通过运行git config --get来执行此操作:

git config --get filter.d6.clean

无论如何,我们应该应用于dir/sub/name.ext的清洁过滤器。 (假设这是run-d6 %frun-d6。)现在,我们必须检查是否存在filter.d6.process设置:

git config --get filter.d6.process

如果有这样的设置(git config通过退出非零状态指示),我们有一个旧样式驱动程序过滤器,它很容易运行:它只是读取它标准输入和写入其标准输出,并可能将文件的路径名作为参数。如果调用行是run-d6 %f,我们只运行:

git clean dir/sub/name.ext < dir/sub/name.ext > /tmp/cleaned
例如

如果 filter.d6.process,那么调用它来清除dir/sub/name.ext会相当棘手。有关详细信息,请参阅文档不幸的是,现代的Git-LFS使用长时间运行的过滤器进程(实际上我认为Git-LFS完全存在原因),但我怀疑有一些向后兼容方法可以在一个文件中调用它因为长时间运行的过滤器过程仍然相对较新。

(请注意,在实践中,人们不会构建复杂的.gitattributes树结构。特别是对于Git-LFS,顶级只有一个.gitattributes运行所有内容通过长期运行的过程。)