hg copy是什么意思?

16
最近我们在代码库中对一个目录进行了hg copy操作。我们认为这个命令类似于执行cp -ahg add,并在文件中添加标记以表明该文件是从代码库中的另一个文件复制而来(以便hg annotate能够显示原始提交者)。但现在看来,hg copy执行的操作比这要多或不同。我找不到太多关于它的工作原理的资料。因此,我的问题如下:
  • hg copy具体执行了哪些操作?这会引起以后的特殊处理吗?
  • 如果发现它对我们的情况做出了错误的操作,我该如何取消文件的复制标记?
(本问题来源于Mercurial邮件列表,您可能也想查看原始帖子。)

您还可以在《Mercurial:权威指南》一书中阅读有关复制文件的内容。 - Matus
2个回答

17
  • hg copy具体是做什么的,这会对未来造成什么特殊影响?

它添加新文件并将其标记为旧文件的副本。因为它们是副本,所以在原文件中进行的更改将合并到副本中。时间从左到右流动:

(init) --- (edit a.txt) ---- (a.txt edit is copied to b.txt)
      \                     /
       (hg copy a.txt b.txt)
  • 如果发现对我们的情况做了“错误的事情”,我该如何将文件标记为不是另一个文件的副本?

此机制仅在合并时启动。如果在共同祖先版本(上述图表中的init)中不存在b.txt,则Mercurial将向后搜索以查看b.txt是否从其他地方复制而来。

让我们继续上面的图表:

(i) -- (edit a) -- (a edit copied to b) -- (edit a) -- (merge)
   \              /                                   /
    (copy a b) --/------- (edit b) ------------------/

问题在于最终合并是如何完成的。共同祖先点现在是copy a b节点,在这里同时存在ab。这意味着不会搜索任何副本! 因此,对a的第二次编辑将不会合并到b中。
为了双重检查,我试了一下:
$ hg init
$ echo a > a
$ hg add a
$ hg commit -m init
$ hg copy a b
$ hg commit -m "copy a b"

这是复制品,b现在只包含a
$ hg update 0
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ echo aa >> a
$ hg commit -m "edit a"
created a new head
$ hg merge
merging a and b to b
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg commit -m "a edit copied to b"

这是第一次合并,对 a 的编辑已被复制到 b 中:

$ cat b
a
aa

我们现在同时进行变更:

$ echo aaa >> a
$ hg commit -m "edit a again"
$ hg update 3
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ echo bbb >> b
$ hg commit -m "edit b"
created new head
$ hg merge
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)

没有进行进一步的复制:

$ cat a
a
aa
aaa
$ cat b
a
aa
bbb

关于禁用复制检测,实际上你并不能明确地禁用它。但是如我在上面所示,第一次合并后它就不会再“打扰”你了。

如果第一次合并是个问题,那么你可以使用hg resolve --tool internal:local将文件重置回合并之前的状态。因此:

$ hg resolve --tool internal:local b

我们可以通过将b还原为包含一个行的状态来实现。

抱歉,无法确认在我的测试中合并头部的复制更改。>hg version Mercurial Distributed SCM(版本2.0.1) - Lazy Badger
如果在第一次合并中没有解决?请发送电子邮件至mercurial@selenic.com,这样我们可以在那里进行全面讨论,比在这些小评论框中更好 :) - Martin Geisler
“也不在第一次合并中?” - 是的。已记录电子邮件,将发送消息(附带日志)。 - Lazy Badger
如果你无法按照我的步骤重现它,那就很奇怪了……感谢您将日志发送到列表中,这将使讨论更容易。 - Martin Geisler
你解决问题了吗?我在邮件列表中没有看到任何日志。 - Martin Geisler
我想指出的是:第一次合并的效果不是通过保持ab“同步”来实现的。在第一次合并中,只有b会成为任何在没有b分支上对a进行更改的合并结果,以及在具有b副本的分支上对b进行更改的结果。(从上面的答案中读取时对我来说不太清楚hg是否也会将更改合并回a,因为在第一次合并之前示例没有修改b。经过快速测试,我相信它不会这样做。) - Joshua Goldberg

1
如果您要取消文件的副本标记,该怎么办? 如果您还原了一个hg复制,那么复制到的文件将保留在您的工作目录中,未被跟踪。 您只需要按照正常流程添加它即可。 复制的文件不会受到任何影响。
% hg copy file new-file
% hg status -C
A new-file
__file
% hg revert new-file
% hg add new-file
% hg status -C
A new-file

参考资料:Mercurial:权威指南

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