git clean filter显示git diff结果的差异

时间:2018-03-19 10:33:50

标签: git git-filter

我设置了一个干净的过滤器来应用autrusormat与uncrustify。相应的涂抹过滤器不执行任何操作,只需调用cat

[filter "autoformat"]
        clean = uncrustify -c ~/tmp/autoformat/uncrustify.cfg --replace
        smudge = cat

我的问题是,当我结帐时,例如master,git说我的工作树与提交不同,显示的差异是干净的过滤器所做的。

似乎在diff之前应用了清洁过滤器。那是对的吗?是否可以禁用此功能?这会是一个好主意吗?

我想要一个解决方案,其中autoformat应用于临时区域,这只是分阶段的帅哥。不清洁过滤适当的解决方案吗?

如果我的uncrustify配置中的主提交不符合我的编码标准,则checkout -f HEAD^后跟checkout master -f会显示差异。这既困惑又麻烦(git拒绝检查其他内容,以防止丢失更改)。

1 个答案:

答案 0 :(得分:2)

  

似乎在diff之前应用了清洁过滤器。这是对的吗?

是。 必须。例如,考虑一下,如果涂抹过滤器包含,例如,"每个字符加倍,会发生什么?清洁过滤器由"删除加倍" - 或者,如果这看起来太奇特了,如果涂抹过滤器包含"翻译成一些替代字符集"干净的过滤器会翻译回来。

将工作树与实际提交进行比较的git diff 必须在提交内容上运行 smudge 过滤器,或运行工作树内容上的 clean 过滤器。 Git使用的方法是运行清洁过滤器,而不是涂抹过滤器。

  

是否可以禁用此功能?这会是一个好主意吗?

见上文 - 充其量你可能会使用"运行涂抹过滤器"选项(但没有)。

请注意,根据定义,索引中的内容已经是干净的。从工作树到索引的转换发生清理;在从索引到工作树的过渡中发生污迹。

现有提交严格是只读的,并且将提交提取到索引中不会发生任何更改。因此,虽然索引内容根据定义是干净的,但如果清理过滤器本身已更改,则它们可能与重新运行过滤器所获得的不匹配。

  

我想要一个解决方案,其中autoformat应用于临时区域,这只是分阶段的帅哥。不清洁过滤适当的解决方案吗?

这不符合您的想法。

运行git add不会对目标副本应用差异:运行git add会将整个工作树文件复制到索引中。整件事情得到了清理。

运行git add -p实际上也不会将差异应用于索引副本,因为它实际上不可能。相反,git add -p将索引副本提取到临时文件,将diff hunk应用于临时文件,然后将整个临时文件(带有应用的hunk)复制到索引中,运行该文件通过清洁过滤器。整个事情再一次得到清理 - 它只是"整个事情"是通过修补污迹索引副本而构建的临时文件。

换句话说,每个文件的索引副本本身就是一个实体,独立于HEAD提交副本和工作树副本。 Git从{{{ 1}}时间,只需将文件的提交副本直接复制到索引中(无更改,无过滤器),然后将文件的索引副本复制到工作树(涂抹过滤器)。在git checkout时间,Git在工作树文件(或修补结果)上运行清理过滤器并将其填充到索引中。 1

1 从技术上讲,索引不包含文件本身,而是包含内容哈希。添加文件包括将文件写入存储库!生成的 blob 对象的哈希ID将进入索引。如果索引是blob使用的唯一位置(如果blob匹配某个已提交的blob,则它可以安全地从Grim Collector中获取),索引条目可以防止blob被垃圾收集。