是否可以"滥用"Mercurial的重命名功能来跟踪代码块的移动?

Chr*_*ips 13 version-control merge mercurial rename

有时候我发现我的文件随着时间的推移而变得越来越多,包含了比我喜欢的更多的类/函数/ whatevers.现在是重构的时候了!在这种情况下,我通常会发现我的一个文件变成了几个:本身加上其他几个文件,每个文件都包含文件的不同部分.

不幸的是,只是创建这些新文件会"破坏"历史记录 - 很难说这些函数最初来自另一个文件.如果在重构期间对代码进行任何其他更改,情况会更糟.

我的一位同事发现他可以通过这样的方式"滥用"重命名功能:

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
Run Code Online (Sandbox Code Playgroud)

结果是每个新文件看起来像一个重命名,文件的其余部分被删除,原始文件看起来像丢失了删除的块.到目前为止,这似乎是理想的.但是,我担心这些多次重命名会导致一些混乱的合并.

这种"多重命名"方法有什么问题吗?

Mar*_*ler 10

在这样做之前,你应该确定你知道hg copy真正意味着什么.

简而言之,复制文件original_filenew_file_1添加Mercurial将来在合并中使用的链接,当且仅当new_file_1在共同的祖先中找不到时.这通常只是在您复制后的第一次合并中的情况.

图表可能会更好地说明这一点:

old --- edit old --- edit in old copied to new --- edit old --- merge
   \                /                             /
    copy old new --/------- edit new ------------/
Run Code Online (Sandbox Code Playgroud)

我们从您拥有该文件的变更集开始old.然后old,您在一个分支上编辑并复制oldnew另一个分支.在第一次合并中,编辑将old被复制到new.在第二次合并中,没有特殊的处理,new因为new在共同的祖先(copy old new变更集)中找到了.

对于你的情况来说,这意味着未来的合并会有很大的不同,这取决于人们何时看到copy old new.如果你能让每个人都使用

old --- copy old new
Run Code Online (Sandbox Code Playgroud)

作为他们的出发点,事情就好了.但是如果有人从old变更old集中分支并实际在该分支中进行了编辑,那么当他们尝试与copy old new变更集合并时,他们会遇到合并冲突.

更确切地说,如果他们编辑了old未复制到new文件中的文件的任何部分,则会出现合并冲突.合并冲突会提醒您old需要复制的更改new.但是,当你真的这么做的时候

hg copy old new1
hg copy old new2
hg copy old new3
Run Code Online (Sandbox Code Playgroud)

那么你将在三个新文件中的两个中获得无关的合并冲突.

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

remove changed old which local deleted
use (c)hanged version or leave (d)eleted?
Run Code Online (Sandbox Code Playgroud)

您是否希望看到该提示或看到合并工具启动取决于您 - 但现在您知道hg copy(或者hg rename --after,它实际上是相同的)后果.


Ry4*_*ase 9

更容易使用hg copy:

hg copy original_file new_file_1
hg copy original_file new_file_2
hg copy original_file new_file_3
Run Code Online (Sandbox Code Playgroud)

现在所有3个都有原始历史.但是,是的,无论哪种方式,这都是完全可以的并且通常都可以.