我一直想知道当你做一个git push
时,图像重写旁边的百分比是什么意思
例:
rewrite assets/img/30_credits.png (70%)
我一直认为它只是显示图像画布被重写了多少,尽管我很想知道。
对不起,愚蠢的问题:) 谢谢!
简短回答:这是 Git 的相似性指数。 有关计算相似性的算法的详细说明,请参阅尝试理解"git diff"和"git mv"重命名检测机制。
更长:这实际上并不git push
;你从git pull
看到了这一点。 但它也不git pull
:它是git pull
运行git merge
产生的输出,实际上是git diff --stat
打印它。1git diff --stat
打印的是:2
verb path(percentage)
其中verb
是rename
、rewrite
或copy
之一,path
是文件路径名或相同或(用于重命名)旧路径名和新路径名的缩写版本,百分比是相似性指数。 Git 使用此相似性索引来确定两个名称不同的文件,或者两个名称相同但内容非常不同的文件,是否实际上是同一个文件,或者毕竟是不同的文件。
也就是说,假设 commitba3c046
包含A1.txt
和A2.txt
文件,而 commit50fcdab
包含A2.txt
和B1.txt
(并且两个提交都没有任何其他文件)。 这两个A2.txt
文件很可能是"同一个"文件,即使内容有所更改。 也许有人签出了提交ba3c046
并修改了文件,然后根据修改后的结果进行了提交50fcdab
。
但是A1.txt
与B1.txt
呢? 也许有人签出了ba3c046
,重命名了文件(无论是否更改它)并提交50fcdab
。 如果他们这样做了,提交50fcdab
的B1.txt
实际上与提交ba3c046
的A1.txt
文件相同。
Git 确定这两个文件是否真的是相同的文件,或者"几乎相同"(重命名并略有更改)文件,方法是比较它们的相似性。 为此,它会计算A1.txt
和B1.txt
之间的相似性指数。
现在假设我们正在比较提交ba3c046
(及其两个文件)和提交0f3ac31
,后者有A2.txt
、B1.txt
和C1.txt
。 每次提交对 Git 来说并不重要;Git 会查看A1.txt
中的内容,并评分它们与0f3ac31
的B1.txt
和0f3ac31
的C1.txt
的相似性。 如果文件足够相似,Git 会匹配它。 Git 会选择与ba3c046
中的A1.txt
最相似的0f3ac31
文件。
这个过程——通过内容匹配的程度来匹配文件——是 Git 确定在git diff
-ed 的两个提交中哪些文件"相同"的方式。 我一直在此过程中使用的术语是识别文件,我不喜欢它,因为我们没有尝试查找100%相同的文件(尽管由于 Git 的内部存储系统,当它们被时有很大帮助)。
默认情况下,如果两个不同提交中的两个文件具有相同的名称,则会自动识别(作为"同一文件"),即使它们的内容差异很大。 也就是说,这两个文件是预先配对的,而不是由于计算的相似性而配对的。 在这种情况下,它们的相似性指数会相对较差,Git 会称之为"重写"。
Git 还有一个相异性索引概念,它只是 100 减去相似性:例如,75% 相似的文件是 25% 的不相似。git diff
的-B
(中断配对)标志可用于打破 Git 默认假设的自动配对,即左侧提交中路径为 P 的文件必须与右侧提交中路径为P的文件相同。 但是,运行git merge
调用git diff
而不设置中断标志。
计算相似性是昂贵的,因此仅针对未配对的文件或在 -B. The unpaired files are those without a partner on the other side initially, or those broken-apart by
-B. If you use the
-Cor
--find-copyor
--find-copyies-harder' 选项下完成,Git 会将一些左侧/源端文件视为可能已复制到某些右侧/目标端文件,因此将源端文件与目标端文件配对不会从"源"池中删除源文件。 对于差异两边包含大量文件的大型存储库,这需要进行大量的相似性计算,并且可能需要大量时间。
1您还可以从git apply
获得相似度指数。 我认为git merge
的 diffstat 输出现在直接内置于git merge
本身中,但对于真正的合并,您可以通过运行git diff --stat <merge>^1 <merge>
来重复它。
对于快进操作(即使git merge
会这样做,也不是真正的合并),您需要指定正确的提交对。 在git pull
之后,这是HEAD@{1}
和HEAD
,所以git diff --stat HEAD@{1} HEAD
会做这个技巧,但由于这些是相对名称,它们将在一段时间后停止工作。 此外,一些shell(例如Windows上的PowerShell,Linux上的tcsh和zsh)使得提供@{1}
后缀变得更加困难,因为他们喜欢将{...}
语法用于自己的目的。
2这有几种格式。 例如,git diff-tree
的输出使用代码字母和百分比,而不是单词。 不过,这些只是说同一件事的不同方式:Git 在左侧和右侧提交中配对了某些文件,也许尽管这些文件的内容发生了一些变化。