维基百科解释了自动重命名检测:
简而言之,给定版本N中的文件,版本N-1中具有相同名称的文件是其默认祖先。但是,当版本N-1中没有类似文件时,Git会搜索仅存在于版本N-1中且与新文件非常相似的文件。
重命名检测显然可以归结为类似的文件检测。该算法在任何地方都有记录吗?知道自动检测哪些类型的转换将非常高兴。
Answers:
Git跟踪文件内容,而不是文件名。因此,重命名文件而不更改其内容很容易被git检测到。(Git不跟踪,但执行检测;使用git mv或git rm和git add有效地相同。)
将文件添加到存储库后,文件名在树对象中。实际文件内容将作为二进制大对象(blob)添加到存储库中。Git不会为包含相同内容的其他文件添加另一个Blob。实际上,Git不能,因为内容存储在文件系统中,哈希的前两个字符是目录名,其余的是其中的文件名。因此,检测重命名是比较散列的问题。
为了检测对重命名文件的微小更改,Git使用某些算法和阈值限制来查看这是否是重命名。例如,查看的-M标志git diff。还有一些配置值,例如merge.renameLimit(在合并期间执行重命名检测时要考虑的文件数)。
要了解git如何处理相似文件(即,将哪些文件转换视为重命名),请探索可用的配置选项和标志,如上所述。您无需考虑如何。要了解git实际上是如何完成这些任务的,请查看用于查找文本差异的算法,然后阅读git源代码。
算法仅适用于差异,合并和记录目的-它们不影响git存储它们的方式。文件内容的任何细微变化都意味着为其添加了一个新对象。在该级别上没有增量或差异发生。当然,稍后,可以将对象打包在delta存储在packfiles中的地方进行打包,但这与重命名检测无关。