【问题标题】:How does Git track history during a refactoring?Git 如何在重构期间跟踪历史记录?
【发布时间】:2011-04-01 00:08:45
【问题描述】:

我非常了解 Git 如何支持文件移动:由于它使用文件哈希,“添加”文件很容易被检测为与“删除”文件相同。

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

【问题讨论】:

  • 等一下……我面前的那本“Apache Maven”书有一个作者名字出奇地熟悉……
  • 我知道!我仍然试图忘记“C'est pas sorcier”中一个疯狂的 Fred 在最近的 JUG 上谈论 maven3 迁移的照片……好时光;)欢迎您。

标签: git refactoring hash dvcs


【解决方案1】:

正如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,则它是相似性指数的阈值(即添加/删除的数量与文件的比较大小)。
例如,-M90% 表示如果 90% 以上的文件没有更改,git 应该将删除/添加对视为重命名。


其他参考资料:


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

【讨论】:

  • 好的,但是对于原始情况是否有简单的简单语言答案?如果我通过将 Java 类移动到不同的包目录来重构它,那么在(例如)100 行中,有一行已被修改以指示 Java 包,default 日志和责备是否会识别移动/重命名?我还会在 GitHub/BitBucket 上看到正确的责任吗?换句话说,如果我执行这个(非常、非常、非常)常见的活动,一切是否会“正常工作”?
  • @GarretWilson 是的,它将在本地端(您可以在其中调用git log --follow(如stackoverflow.com/q/2314652/6309)或git blame -C。这不会在Git托管服务器端完成虽然(GitHub:stackoverflow.com/a/5647721/6309)(或 BitBucket:bitbucket.org/site/master/issues/589/…)
  • 感谢您对链接的快速澄清!我将在 Git 上保留我的 cmets,看来我别无选择,只能使用... :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-20
  • 2023-04-06
  • 2011-04-26
  • 1970-01-01
  • 1970-01-01
  • 2020-11-07
  • 2020-11-12
相关资源
最近更新 更多