Git如何在重构期间跟踪历史记录?

时间:2010-08-19 08:38:03

标签: git refactoring hash dvcs

我很清楚Git如何支持文件移动:因为它使用文件哈希,“添加”文件很容易被检测为与“删除”文件相同。

我的问题是关于重构:考虑到Java,包声明会发生变化,因此文件内容将不相同。在这种情况下,Git如何确定“添加”文件与“已删除”文件共享历史记录?它是否检查“最相似的内容”,假设我只做了一些小改动或类似的非确定性解决方案?

1 个答案:

答案 0 :(得分:20)

Git FAQ中所述,它会根据启发式检测类似的内容。

  

Git必须与许多不同的工作流互操作,例如某些更改可能来自补丁,其中重命名信息可能不可用。依赖于显式重命名跟踪使得无法合并两个完全相同的树,除了一个做了补丁(创建/删除),一个用其他启发式做了。

     

在第二个注释中,跟踪重命名实际上只是跟踪内容在树中移动的特殊情况。在某些情况下,您可能会对添加函数或将其移动到其他文件时的查询感兴趣。只需依靠在需要时重新创建此信息的能力,Git旨在提供一种更灵活的方式来跟踪树的变化情况。

     

但是,这并不意味着Git不支持重命名   Git中的diff机制支持自动检测重命名,“-M”切换到git-diff-*命令系列。   重命名检测机制由git-log(1)和git-whatchanged(1)使用,例如,'git log -M'将为重定名信息提供提交历史记录。 />   Git还支持有限形式的重命名合并   分配责备的两个工具git-blame(1)git-annotate(1)都使用自动重命名检测代码来跟踪重命名。


git log为您提供有关该启发式的一些详细信息:

-B[<n>][/<m>]
  

将完全重写更改分为删除和创建对。这有两个目的:

     
      
  • 它影响了一个更改的方式,该更改相当于一个文件的完全重写,而不是一系列删除和插入混合在一起,只有很少的行恰好与文本作为上下文匹配,而是作为一个删除所有旧的,然后单个插入所有新的,并且数字m控制-B选项的这一方面(默认为60%)。
       -B / 70%指定不到30%的原始内容应保留在结果中,以便git将其视为完全重写(即,否则生成的补丁将是一系列删除和插入混合在一起与上下文行)。

  •   
  • 与-M一起使用时,完全重写的文件也被视为重命名源(通常-M只考虑作为重命名源消失的文件),并且数字n控制此 -B选项的方面(默认为50%)   -B20%指定添加和删除的更改与文件大小的20%或更多相比有资格被选为可能的重命名源到另一个文件。

  •   
-M[<n>]
  

如果生成差异,请检测并报告每次提交的重命名。对于在遍历历史记录时重命名后续文件,请参阅--follow   如果指定了n,则a是相似性指数的阈值(即与文件大小相比的添加/删除量)。
  例如, -M90%表示如果文件的90%以上未更改,git应将删除/添加对视为重命名


其他参考资料:


注意:使用Git 2.18(2018年第二季度),git status现在应该在移动/重命名文件时显示重命名(而不是删除/添加文件)。
请参阅“How to tell Git that it's the same directory, just a different name”。