【问题标题】:How does git track source code moved between files?git如何跟踪文件之间移动的源代码?
【发布时间】:2009-11-13 12:26:50
【问题描述】:

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

这是如何工作的?

【问题讨论】:

    标签: git version-control dvcs


    【解决方案1】:

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

    Git 只记录整个项目树的快照:这是提交前的所有文件的样子,以及提交后的样子。 如何我们从这里到那里,Git 不在乎。

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

    检测移动的内容的工作方式类似:您将每个文件切成小块,计算所有切片之间的相似度指标,然后可以推断出在此处删除的切片和在此处添加的非常相似的切片实际上是相同的切片从这里搬到那里。

    但是,正如 tonfa 在他的回答中提到的那样,这是非常昂贵的,因此通常不会这样做。但它可以完成,这就是重点。

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

    【讨论】:

    • 我不太明白“这就是它的美妙之处”。我的意思是,您的解释听起来像 “Git 不存储文件实际发生的情况,以便您以后自己猜测!” 美在哪里?
    • 在我看来,它的美妙之处在于认识到跟踪不应该成为核心版本控制本身的一部分。 “外包”此功能避免了许多复杂性和缺点,例如SVN。您获得了简单性和灵活性(SVN 工具通常仅限于使用最初记录的跟踪信息,即使这可能不能很好地表示代码库实际发生的情况)。
    • 科斯,你以后不用猜了。 Git 具有启发式方法,可以在重要时(即合并时)检测它。
    • 美妙之处在于 git 并不假定其当前的启发式方法是正确的 - 它只是保存数据并让您稍后使用任何您想要的启发式方法来解释该数据。这也意味着,如果某些启发式算法的计算成本确实很高,则可以在共享存储库(可能非常繁忙!)以外的其他地方进行。
    • @tavnab 此后 Gmane 链接已关闭,但邮件 is still available through the Web Archive.
    【解决方案2】:

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

    【讨论】:

    • 并且只在同一个提交中?
    • 是的,它会寻找具有相同提交的匹配文件。
    • 请参阅 git diff 手册页中有关 -M-C 选项的文档。
    猜你喜欢
    • 2016-02-14
    • 1970-01-01
    • 1970-01-01
    • 2016-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-07
    • 1970-01-01
    相关资源
    最近更新 更多