似乎在diff之前应用了clean filter。这是正确的吗?
是的。在某些情况下,它必须是这样的。例如,考虑如果smudge filter由“双倍每个字符”组成,而clean filter由“删除双倍”组成——或者如果smudge filter由“翻译为一些替代字符集”,而clean filter将其翻译回来。
用于比较工作树与实际提交的
git diff
必须在提交内容上运行smudge过滤器或在工作树内容上运行clean过滤器。或者它甚至可以同时运行两个过滤器,并将输出写入临时文件。(我很确定我曾经测试过这个,很久以前,发现Git使用的方法是运行clean filter,而不是smudge filter。但是请参见
Cyker's comment,该评论建议运行两个过滤器,然后对smudged结果进行差异比较。)
这个能否禁用?这是一个好主意吗?
请参见上文,最多你可能有一个“仅运行污点过滤器”的选项(但实际上没有)。
请注意,按照定义,索引中的内容已经是干净的。清理发生在从工作树到索引的转换时;污点发生在从索引到工作树的转换时。
现有提交是严格只读的,从提交中提取到索引不会进行任何更改。因此,虽然索引内容按定义是干净的,但如果干净过滤器本身发生了变化,则它们可能与通过重新运行过滤器获得的内容不匹配。
我想要的解决方案是将自动格式应用于暂存区,即仅对已暂存的块进行操作。清理过滤器是否是适当的解决方案?
这并不像你想象的那样起作用。
运行 git add
不会将差异块应用于索引副本:运行 git add
将整个工作树文件复制到索引中。整个文件都会被清理。
运行git add -p
并不会实际将差异块应用于索引副本,因为它根本无法这样做。相反,git add -p
将索引副本提取到临时文件中,将差异块应用于临时文件,然后将整个带有应用程序块的临时文件复制到索引中,并通过清理过滤器运行该文件。再次进行整个清理 - 只是“整个清理”是通过修补弄脏的索引副本构建的临时文件。
换句话说,每个文件的索引副本都是一个独立的实体,与HEAD
提交副本和工作树副本无关。在git checkout
时,Git仅通过直接将文件的提交副本复制到索引中(无更改,无过滤器)来开始,然后将文件的索引副本复制到工作树中(弄脏过滤器)。在git add
时间,Git在工作树文件上运行清理过滤器(或修补结果),并将其塞入索引。1
1从技术上讲,索引并不持有文件本身,而是它们的内容哈希值。添加文件的过程包括将文件写入存储库!生成的blob对象的哈希ID放入索引中。如果索引是唯一使用该blob的地方(如果该blob与某个已提交的blob匹配,则安全免受Grim Collector的影响),则索引条目会阻止该blob被垃圾回收。
git diff
运行的是clean
而不是smudge
过滤器吗?看起来两个过滤器都在运行,但是差异结果是使用smudge
过滤器生成的。Git 版本为 2.24.1(最新版)。 - Cyker