Mercurial的重命名功能是否可以被“滥用”来追踪代码块的移动?

14
有时候我会发现一个文件随着时间增长包含了太多的类、函数或其他东西,我不太喜欢这种情况。这时就需要进行重构!通常情况下,我会把一个文件拆成几个文件,每个文件都包含文件的不同部分。
不幸的是,仅仅是创建这些新文件会“破坏”原来的历史记录——很难看出那些函数最初来自另一个文件。如果在重构期间对代码进行了其他更改,情况会变得更糟。
我的一位同事发现他可以通过这样做来“滥用”重命名功能:
hg rename --after original_file new_file_1
hg rename --after original_file new_file_2
hg rename --after original_file new_file_3
hg add original_file

结果是每个新文件看起来都像重命名,其余部分被删除了,而原始文件似乎失去了被删除的块。到目前为止,这似乎是理想的。然而,我担心这些多个重命名会在以后引起一些混淆的合并。

采用这种“多次重命名”方法有什么问题吗?

2个回答

11

在执行这个操作之前,您应该确保了解hg copy的真正含义

简而言之,在将文件从original_file复制到new_file_1时,会添加一个链接,Mercurial将在未来的合并中使用此链接仅当它无法在共同祖先中找到new_file_1。这通常只会在您进行复制后的第一次合并中出现。

下面的图形可能更好地说明这一点:

old --- edit old --- edit in old copied to new --- edit old --- merge
   \                /                             /
    copy old new --/------- edit new ------------/
我们从一个变更集开始,其中您拥有文件old。然后您在一个分支上编辑old并将old复制到另一个分支的new中。在第一次合并中,对old的编辑被复制到了new中。在第二次合并中,由于new在共同祖先(copy old new变更集)中找到,因此没有特殊处理new
对于您的情况,这意味着未来合并取决于人们何时看到copy old new,存在很大的差异。如果您可以让每个人都使用
old --- copy old new
如果某人以 old 变更集为起点开始修改代码,那么一切都很好。但是如果有人从 old 变更集中分支出去并在该分支中实际编辑了 old,那么当他们尝试与 copy old new 变更集合并时,就会遇到合并冲突。
更准确地说,如果他们编辑了没有复制到 new 文件中的 old 文件的任何部分,则会出现合并冲突。合并冲突会提示您存在需要将 old 中的更改复制到 new 中的事实。
hg copy old new1
hg copy old new2
hg copy old new3

如果你只是删除了old文件并添加了三个新文件,那么你在这里仍然会遇到合并冲突:你将被询问

然后你将在这三个新文件中的两个文件中得到不相关的合并冲突。

remove changed old which local deleted
use (c)hanged version or leave (d)eleted?

你可以选择看到提示或看到合并工具启动,这取决于你——不过现在你知道了使用 hg copy(或者 hg rename --after,其实是一样的)的后果。


9
更简单的方法是使用hg copy来实现:
hg copy original_file new_file_1
hg copy original_file new_file_2
hg copy original_file new_file_3

现在所有三个都有原始历史记录。但是,无论哪种方式都是完全可以的并且很常见。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接