git如何跟踪在文件之间移动的源代码?

git如何跟踪在文件之间移动的源代码?,git,version-control,dvcs,Git,Version Control,Dvcs,显然,当您将一个函数从一个源代码文件移动到另一个源代码文件时,git修订日志(对于新文件)可以向您显示该代码片段最初来自何处(例如,请参见中的查看历史记录部分) 这是如何工作的?这纯粹是一种启发。它比较文件之间的距离并尝试查找匹配块。但是,只有当代码被复制或移动到一个新文件时(否则,检查每一对文件的成本太高)。它不会跟踪它们。这就是它的美妙之处 Git只记录整个项目树的快照:下面是提交之前所有文件的样子,下面是提交之后的样子。我们是怎么从这里到那里的,吉特不在乎 这允许在提交已经发生之后编写智能

显然,当您将一个函数从一个源代码文件移动到另一个源代码文件时,git修订日志(对于新文件)可以向您显示该代码片段最初来自何处(例如,请参见中的查看历史记录部分)


这是如何工作的?

这纯粹是一种启发。它比较文件之间的距离并尝试查找匹配块。但是,只有当代码被复制或移动到一个新文件时(否则,检查每一对文件的成本太高)。

它不会跟踪它们。这就是它的美妙之处

Git只记录整个项目树的快照:下面是提交之前所有文件的样子,下面是提交之后的样子。我们是怎么从这里到那里的,吉特不在乎

这允许在提交已经发生之后编写智能工具,以从该提交中提取信息。例如,Git中的重命名检测是通过将所有删除的文件与所有新文件进行比较,并比较成对的相似性度量来完成的。如果相似性度量大于
x
,则认为它们已重命名;如果相似性度量介于
y
x
y
)之间,则认为它们是重命名+编辑;如果相似性度量低于
y
,则认为它们是独立的。最酷的是,作为一名“承诺考古学家”,你可以在事后指定
x
y
应该是什么。如果提交只是记录“此文件是该文件的重命名”,则此操作将不起作用

检测移动内容的工作原理是相似的:将每个文件分割成多个片段,计算所有片段之间的相似性度量,然后可以推断在这里删除的片段和在那里添加的非常相似的片段实际上是从这里移动到那里的相同片段

然而,正如tonfa在他的回答中提到的,这是非常昂贵的,所以通常不会这样做。但这是可以做到的,这就是重点


顺便说一句:这与Google Wave、EtherPad、Gobby、SubEthaEdit、ACE和Co.使用的操作转换模型几乎完全相反。

并且只在同一个提交中?是的,它查找具有相同提交的匹配文件。请参阅git diff manpage中的
-M
-C
选项文档。我不太明白“这就是它的美妙之处”。我的意思是,你的解释听起来像是“Git并没有存储文件的实际情况,这样你以后就可以自己猜了!“美在哪里?在我看来,它的美在于认识到跟踪不应该是核心版本控制本身的一部分。“外包”此功能避免了SVN的许多复杂性和缺点。您获得了简单性和灵活性(SVN工具通常仅限于使用最初记录的跟踪信息,即使这可能无法很好地表示代码库的实际情况)。Kos,您以后不必猜测它。Git有启发式方法在重要时(即合并时)检测它。妙处在于git并不认为它当前的启发式是正确的-它只是保存数据,让你以后可以使用任何你想要的启发式来解释数据。这也意味着,如果某些启发式计算非常昂贵,可以在其他地方进行(可能非常忙!)共享回购。@tavnab从那以后,Gmane链接就断了,但是邮件。