如何将我的代码重构为新文件并保留git历史记录?

时间:2016-11-07 13:18:42

标签: git refactoring

所以我想将一个大文件的一部分提取到一个新文件并保留git历史记录,这样我就可以运行git blame并在重构之前看到更改。

1 个答案:

答案 0 :(得分:2)

在Git中,历史提交。没有文件历史记录。这与大多数其他版本控制系统不同:执行跟踪“文件标识”的其他VCS需要您通知他们新文件path/to/new.ext派生自path/to/existing.ext,以便他们可以将新文件的历史记录与旧文件的历史记录相关联。同样,他们需要您告知他们文件重命名 - 尽管有些像ClearCase一样,只需充当工作树的文件系统就可以自动检测重命名。 Git不需要这些,因为它不会那样工作。 1

相反,在Git中,当你比较一个提交 - 调用它a - 到另一个(b)时,Git会尝试发现(动态地,在比较时) )某个文件a/path/to/name是否与另一个文件b/some/other/path/to/anothername“相同”。比较程度和决定这些相同文件或不同文件的算法取决于Git命令。 git diff命令首先查看实际路径名称:如果它们相同,则文件相同, 2 否则它们可能不同。 “可能”部分是重命名检测的来源,如果您已启用它。常规git diff也有-C--find-copies-harder以启用“文件复制 - 来自”检测。使用-C两次(或--find-copies-harder)进行设置以查找从a提交中的任何文件中复制的新文件(这被认为太昂贵了自动执行;通常,只有被视为“已修改”的文件才会被视为副本候选者。

git blame命令有些不同(ab提交只是每次提交的父子进程,但它仍然有{{1} } 选项。它的-C的工作方式略有不同:一个-C查找从提交-Ca之间修改的文件中复制的。使用b两次查找从提交-C中的任何文件复制的这些行,并使用三个a标记,它将“更难找到副本”:它将查看每个提交中的每个文件以查找复制的代码。

因此,对于大多数用途,您只需在-C上使用一个-C。如果复制的代码来自未修改的文件,则应使用git blame。如果您认为某些代码在很多年前被删除,然后复活,并且您想要找到原始来源,请使用三个-C -C s。请注意,-C的{​​{1}}选项会启用git blame的{​​{1}}选项,该选项会检测已移动的代码(因此与{}完全不同{1}} -C选项文件重命名检测,la git blame 3 始终处于启用状态。

1 对于Git而言,这是其他VCS的一个很好的优势,因为Git可以检测人类忘记的案例,并且还可以在比较“相距甚远”的修订时检测重命名。这对Git来说是一个可怕的劣势,因为它必须检测案例,即使人类不会忘记,因此也会错过重命名。这对Git来说是一个很大的优势,因为未来更智能的算法会以更好的方式使用现有数据。简而言之,有理由说明为什么它更好以及为什么它更糟,但最终它只是不同

2 对于-M,您可以使用其git diff选项有条件地拆分这些自动配对的“相同名称意味着相同文件”配对。对于-M来说,这是不可能的,但是没有必要进行这种配对。

3 git log --follow git diff启用的代码是一个可怕的黑客攻击,基本上只适用于-B所需的一个案例。请勿尝试将git blame与反向订单--follow一起使用。