将单个文件拆分成几个文件后,可以使用git来跟踪作者和文件重命名吗?

时间:2015-03-02 16:28:44

标签: git revision-history

通常情况下,当我git blame $filename时,git会向我显示每行代码的各种信息,例如

^3333b include/Spec1.php (First Last)     function load($id) {
^5555b class/Spec.php    (Some One)           $id = ...
^6666b include/Spec1.php (First Last)         $var = ... 

即,

    提交它的
  • 谁最后更新了这条线,
  • 有时甚至是该行的文件名(简单时) 已经执行了单文件重命名。)

在我的情况下,我似乎打破了这个循环,而git将我的变化记录为我所做的一次全局变更。

即,我有一个名为Spec的大型类,其中包含多个产品系列的代码。我将类中的各种代码重构为几个新类。当我做提交时,git会将这些文件检测为"新文件"。

这意味着我的新文件将以我的名义注册为我创建的所有新文件,并且其中的行是"全新的"。

在本能中,我输了:

  • 每一行的原创作者 - 尽管我只是将一行中的一行移到了另一个文件而不是真正创作它,但git认为它是新行。
  • 用于存放每行代码的旧文件名 - 当我执行git blame时,git现在只将该行视为存储在创建的新文件中。它丢失了之前该行所在的文件名的跟踪。

在执行此复杂提交时,有没有办法不丢失它们?

1 个答案:

答案 0 :(得分:1)

当您选择两个不同的提交进行比较时,Git始终会动态重命名和复制检测。

使用git blame时,您为每个动态比较选择的两个提交来自父/子关系。 git log -pgit show也是如此。当你运行git diff时,你自己决定要比较哪两个提交(而不是让git通过提交父ID来选择它们)。在任何情况下,提交最终都通过git的内部diff引擎运行,用于明确的git diff补丁输出(git log -pgit show)或其更改发现效果({{1只需要查看子提交中的行1234是否与其父提交不同。

可以指定匹配文件重命名的“相似性阈值” - 这通常是使用git blame选项完成的 1 - 以及是否要启用“查找副本”,如果是,是否启用“更难找到副本”:这些通常是使用-M(可能重复)或-C完成的。 (--find-copies-harder似乎没有将lattermost作为标记。此外,git blame中的-M不会查找文件重命名;相反,它会更改“已移动的行”的分配方式。 )

在这种情况下,您可能希望设置一个低(ish)git blame阈值,并且可能至少指定-M两次。 (两个-C选项意味着“查找从当前父/子对中的其他文件复制的代码”,而三个-C表示“查找从任何提交中复制的代码”。)


1 您还可以配置-C以始终启用默认diff.renames = true值;或者,为了打开-M-C。这是常规diff.renames = copies特有的; diff以不同的方式定义其git blame-M标记。