在Mercurial中,当彼得“hg克隆”我,并且我承诺并且他拉动并更新时,他得到我的版本,但不是在我回滚时?

时间:2010-06-14 03:07:31

标签: git mercurial dvcs

也就是说,在Mercurial中,如果Peter通过

克隆了我
hg clone c:\mycode e:\code

进入他的e:\ code

假设有一个文件code.txt,它包含文字the code is 7

现在,当我将其更改为the code is 11和hg commit时,他可以使用hg pull和hg update来获取我的代码。现在他的版本说the code is 11

但如果我认为更改错误并且hg回滚,那么我的存储库应该具有7版本,而工作目录应该具有11版本。

所以,当Peter做一个hg pull和hg更新时,他应该同步到我当前的存储库,即7,但我发现事实并非如此 - 他仍然得到了11版本。这是为什么?他能获得回滚代码(7)吗? Git的行为也一样吗?

更新:我认为commit影响存储库的方式与rollback影响存储库的方式相同 - 提交和回滚都是数据库事务字...现在我们是说commit影响了存储库,但rollback没有?这里的规则是什么?

更新2:此时,如果Mary执行了

hg clone c:\mycode e:\marycode

此时,她实际上获得了7版本。所以,玛丽获得7。彼得得到11。它们都是“最新的”?这是什么?

4 个答案:

答案 0 :(得分:3)

hg pull从远程存储库中下载变更集 - 但它不会删除远程存在的变更集。否则,执行拉动将删除任何尚未推送到遥控器的工作。因此,pull并没有摆脱被拉出的变更集,然后远程回滚,因为没有新的变更集可以抓住。

如果你创建一个具有回滚状态的新提交,那么该提交将被拉下来,彼得将会看到它。

换句话说,您需要做的是首先使用hg revert -r <previous-rev>检出要更改回的早期版本,然后使用hg commit根据旧版本创建新提交修改,然后让人们拉动该提交。

答案 1 :(得分:1)

我不使用Mercurial,但是因为你问过Git在这方面的行为......

在Git中,有两种撤消方式:revertreset

revert命令修补现有代码,使其类似于先前的状态:历史记录将记录从原始“代码为7”到“代码为11”的更改,然后将修补程序记录为“代码是7“。

另一方面,reset是历史的实际“倒带”。如果使用此命令,则从历史记录树中删除对“代码为11”的更改,并且存储库的状态就像从未发生过更改一样。

因此,虽然revertreset可能导致您的存储库显然已恢复到更改为“代码为11”之前存在的相同状态,但它们在概念上是非常不同的操作。 revert实际创建新历史记录,而reset删除现有历史记录。

实际上,如果在存储库上执行revert操作,并且Peter从中获取操作,那么,实际上,他的存储库也会将更改记录回“代码为7”。 另一方面,如果在存储库上执行reset操作,那么,从Peter的repo POV中,他所从的存储库实际上处于比他更老的状态,并且什么都不会发生。 这就是为什么使用Git,如果没有人撤消你的更改(或者你没有推到遥控器),你应该只使用reset。在所有其他情况下,您应该使用revert

答案 2 :(得分:1)

hg pull不是完全同步。所有hg pull remote都会将remote中不在本地存储库中的每个变更集复制到本地存储库。所有rollback都会删除最近的提交(或更一般地说,DB操作,但这几乎总是提交) - 它不会记录任何类型的“提交已被删除”消息。除非有另一个拥有它的存储库,否则提交将永远消失。要记录它的反转,所以其他存储库得到反转,你需要一个反转提交(这可以通过hg backout创建)。然后你还有另一个提交,它反转了前一个提交的效果。

所以,当你做回滚并且彼得再次拉动时,你没有任何新的变更集供彼得拉。事实上,你比彼得少了一个变革集。所以,如果Peter推给你,你会再次获得11修订版。

在克隆方案中,它们都是最新的(因为它们都包含7修订版),但Peter有一个额外的变更集。这就好像彼得自己创建了11更改并为其签名。

rollback无法在跨存储库通信中安全或有意义地使用。为此,您需要backout。出于这个原因,我总是倾向于推送到已发布的位置并让人们从那里拉出而不是让他们直接从我的工作存储库中提取,以便我知道rollback何时是安全的以及何时不安全(对于我需要的时候很少次。)

答案 3 :(得分:-1)

彼得不会看到任何未提交的更改。您的回滚仅影响您的工作目录。做一个提交然后peter可以拉/更新以查看你的回滚。