git相似度指数如何计算?

Sal*_*Orn 1 git

我是git的新手,有些东西我不清楚。git内部如何知道文件是新文件还是修改后的文件?
由于git不跟踪文件,而是跟踪blob。这与相似性指标有关吗?

我也遇到了问题,当移动文件并对其进行修改时,有时git会将其识别为重命名的文件,有时将其识别为新文件。
对于小文件,它将识别为新文件并删除。

我如何才能“欺骗” git,以将这种情况标记为移动文件,而不是新的和删除的文件(不进行两次不同的提交-一个用于移动,另一个用于更改)?

tor*_*rek 5

有关相似性索引计算的详细讨论,请参见尝试理解`git diff`和`git mv`重命名检测机制。但是,在执行此操作之前,请注意以下几点:

  • 每次提交都是完整的独立快照。快照是包含更多文件和/或更多目录的命名文件和命名目录(或文件夹)的树。1 给定一个提交和一个完整的路径名path/to/file.ext,Git可以提取在该提交中保存命名文件的适当的blob内容(如Git所称),而无需查看任何其他提交。

  • 每当您向Git询问快照以进行比较时,都必须为Git提供两次提交(两次快照)的哈希ID,或名称或解析为哈希ID的其他字符串。实际上,Git一次提取一个快照,然后比较生成的文件树。(某些命令,例如git showgit log -p,通过查看子提交来找出父哈希,然后按该顺序比较父和子。)

因此,Git总是在看两棵树:左侧(a/)的树可能包含a README.txt,右侧()的树b/也包含a README.txt,例如,左侧包含doc.txt,右侧包含有一个doc.txt。左侧提交具有documentation.rst和右侧documentation.rst

此时,Git要做的是匹配文件。路径名完全相同的两个README.txt文件(例如此处的两个文件)必须是“相同”文件,因此Git会查看左侧README.txt的内容和右侧的内容,README.txt以产生两者的差异。用于匹配此类内容的技术术语是确定文件的身份。(这是在哲学方面颇有成就。见Thesus的船舶进行讨论。不同的哲学论点,在计算,我们得到了一个明确而具体的答案。那么,我们这样做,直到我们介绍之类的东西Git的-B断裂git diff,在最小!)

但是,在没有名称可匹配的地方(例如doc.txtvs)documentation.rst,Git会计算每对此类文件之间的相似性索引,比较左侧的文件(此时,到达右侧时似乎已被删除)到右侧的文件(现在似乎是新文件)。好吧,就是说,如果您已启用重命名检测,则Git会计算该索引。在Git 2.9之前的版本中,重命名检测默认情况下处于关闭状态,而在后续版本中,默认情况下处于启用状态。Git在这里进行最佳匹配,然后将文件配对:如果doc.txt与足够相似documentation.rst,那么为什么这些文件也必须是“相同”文件,即使它们具有不同的名称。

在Git甚至不喜欢这种相似性索引技巧之前,它都会进行第一遍查找100%相同的文件。由于Git存储内容的方式,这比计算相似性索引要容易得多。任何这样的精确匹配都会被配对,并从可能配对的文件列表中删除,仅在Git内部称为重命名队列的文件中只剩下完全匹配的文件。因此,仅对名称在重命名队列中的文件执行相似性索引计算。这种计算比较昂贵(文件数为O(n 2)),因此对于fast git showgit log -p,最好先提交重命名,然后再对内容进行任何更改,这是一个好主意。


1这是内部表示–从外部看,您甚至不应该知道或关心Git将每个目录存储为树条目。特别是,Git喜欢声称它只存储文件(不存储目录),并且Git使其很难存储空目录。为此,Git必须有一棵空树 -而且确实如此,但是如果您尝试使用它,则会得到怪异的效果。

  • 我正要召唤你,然后我看到你答应了。“噢,天哪!我召唤你来打击不正确的知识” (2认同)