简体   繁体   English

hg拷贝有什么作用?

[英]What does hg copy do?

We recently did a hg copy of a directory in our repository. 我们最近在我们的存储库中做了一个目录的hg copy We thought it does something like cp -a and hg add and maybe flag somehow that this file has been copied from another file inside the repo (so hg annotate shows the original committer). 我们认为它做的事情就像cp -ahg add并且可能标记这个文件已经从repo中的另一个文件复制(所以hg annotate显示原始提交者)。 But it now seems that hg copy does more or different stuff than that. 但现在看来, hg copy做的更多或不同。 I couldn't really find much on how exactly copy works. 我真的找不到复制的确切方式。 So: 所以:

  • What exactly does hg copy do and what special treatment does this cause in the future? hg copy究竟做了什么以及这将在未来引起什么特殊处理?
  • If it turns out to do "the wrong thing(tm)" for our case, how do I unflag the file as beeing a copy of another file? 如果事实证明对我们的案例做了“错误的事情(tm)”,我该如何取消文件作为另一个文件的副本?

(This question was asked on the Mercurial mailinglist, you may want to follow the original thread too.) (这个问题是在Mercurial邮件列表中提出的,您可能也想跟随原始帖子 。)

  • What exactly does hg copy do and what special treatment does this cause in the future? hg拷贝究竟做了什么以及这将在未来引起什么特殊处理?

It adds new files and marks them as copies of the old files. 它添加新文件并将其标记为旧文件的副本。 Because they are copies, a change made in the original file will be merged into copy. 因为它们是副本,所以原始文件中的更改将合并到副本中。 Time flows from left to right: 时间从左到右流动:

(init) --- (edit a.txt) ---- (a.txt edit is copied to b.txt)
      \                     /
       (hg copy a.txt b.txt)
  • If it turns out to do 'the wrong thing(tm)' for our case, how do I unflag the file as beeing a copy of another file? 如果事实证明对我们的案例做了“错误的事情(tm)”,我如何取消文件作为另一个文件的副本?

This mechanism only kicks in when you merge. 合并时,此机制才会启动。 If b.txt is not present in the common ancestor revision (init in the above graph), then Mercurial will do a search backwards to see if b.txt is copied from somewhere else. 如果共同的祖先修订版中没有b.txt (上图中的init),那么Mercurial将向后搜索以查看是否从其他地方复制了b.txt

Let us continue the above graph in abbreviated form: 让我们以缩写形式继续上面的图表:

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

The question is how the final merge is done. 问题是最终合并是如何完成的。 The common ancestor point is now the copy ab node and here both a and b are present. 共同的祖先点现在是copy ab节点,这里存在ab两者。 This means that there wont be any search for copies! 这意味着不会有任何副本搜索! So the second edit to a wont be merged into b . 所以,第二个编辑到a不会被合并到b

To double-check, I tried it out: 为了仔细检查,我试了一下:

$ hg init
$ echo a > a
$ hg add a
$ hg commit -m init
$ hg copy a b
$ hg commit -m "copy a b"

This was the copy, b now contains a only. 这是副本, 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"

This was the first merge and the edit to a has been copied into b : 这是第一次合并,对a的编辑已复制到b

$ cat b
a
aa

We now make changes in parallel: 我们现在并行进行更改:

$ 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)

There are no further copying done: 没有进一步复制:

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

As for disabling this... you can't really explicitly disable the copy detection. 至于禁用此功能......您无法真正明确禁用复制检测。 But as I hope to have illustrated above, it wont "bother" you again after the first merge. 但正如我希望上面说明的那样,它在第一次合并后不会再“打扰”你了。

If the first merge is a problem, then you can use hg resolve --tool internal:local to reset the files back to their state before you started the merge. 如果第一次合并是一个问题,那么您可以使用hg resolve --tool internal:local将文件重置回其开始合并之前的状态。 So with 所以

$ hg resolve --tool internal:local b

we could have brought b back to just containing one line with a . 我们可以带来b回到刚才含有一条线a

How do I unflag the file as being a copy of another file? 如何将文件作为另一个文件的副本取消标记?

If you revert a hg copy, the copied-to file remains in your working directory afterwards, untracked. 如果您还原hg副本,则复制到的文件将保留在您的工作目录中,未跟踪。 You just have to add it normally. 你只需要正常添加它。 The copied-from file isn't affected at all. 复制的文件根本不受影响。

% 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

Reference: Mercurial: The definitive guide 参考: Mercurial权威指南

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM