在 Mercurial 中,当 Peter “hg 克隆”我,我提交,他拉取并更新,他得到我的版本,但当我回滚时却没有?
也就是说,在 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 获取我的代码。现在他的版本说代码是11
但是如果我认为更改是错误的并且hg回滚,那么我的存储库应该有7
版本,而工作目录应该有11
版本。
因此,当 Peter 执行 hg pull 和 hg update 时,他应该同步到我当前的存储库,即 7
,但我发现情况并非如此 - 他仍然得到11
版本。这是为什么?他能得到回滚的代码(7
)吗? Git 也有同样的行为吗?
更新:我认为commit
影响存储库的方式与rollback
影响存储库的方式相同——提交和回滚都是数据库事务词......现在我们说 commit
会影响存储库,但 rollback
不会?这里有什么规则?
更新 2: 此时,如果 Mary
hg clone c:\mycode e:\marycode
此时执行操作,她实际上会获得 7
版本。因此,玛丽得到7
。彼得得到11
。它们都是“最新的”吗?这是什么?
That is, in Mercurial, if Peter cloned from me by
hg clone c:\mycode e:\code
into his e:\code
let's say there is a file code.txt
and it contains the text the code is 7
Now, when I change it to the code is 11
and hg commit, then he can get my code using hg pull and hg update. Now his version says the code is 11
But if I decide the change was wrong and hg rollback, then my repository should have the 7
version, while the working directory should have the 11
version.
So when Peter does an hg pull and hg update, he should be sync'ed up to my current repository, which is the 7
, but I found that it is not the case -- he still gets the 11
version. Why is that? Can he get the rolled back code (the 7
)? Does Git behave the same way too?
Update: I thought commit
affects the repository the same way that rollback
affects the repository -- commit and rollback are both DB transaction words... and now we are saying commit
affects the repository but rollback
doesn't? What's the rule here?
Update 2: At this point, if Mary does an
hg clone c:\mycode e:\marycode
at this point, she actually gets the 7
version. So, Mary gets 7
. Peter gets 11
. And they are both "up to date"? What is this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
hg pull
从远程存储库中拉取新变更集 - 但它不会删除远程不存在的变更集。否则,执行拉操作会删除您自己尚未推送到远程的任何工作。因此,拉取不会删除已拉取的变更集,然后遥控器将其回滚,因为没有新的变更集可供获取。如果您进行了具有回滚状态的新提交,那么该提交将被拉下来,Peter 会看到它。
换句话说,您需要做的是首先使用
hg revert -r
查看您想要改回的早期版本,然后使用hg commit
基于旧版本创建新提交,然后让人们拉取该提交。hg pull
pulls down new changesets from a remote repository - but it doesn't delete ones that don't exist remotely. Otherwise, doing a pull would erase any of your own work that hadn't already be pushed to the remote. Thus, pull doesn't get rid of a changeset that was pulled, and then the remote rolled it back, because there's no new changeset to grab.If you make a new commit which has the rolled-back state, then that commit will get pulled down and Peter will see it.
In other words, what you need to do is first use
hg revert -r <previous-rev>
to check out an earlier version that you want to change back to, then usehg commit
to create a new commit based on the older revision, and then have people pull that commit.我不使用 Mercurial,但既然你问了 Git 在这方面的行为如何......
在 Git 中,有两种撤消方法:
revert
和reset
。revert
命令对现有代码进行修补,使其类似于之前的状态:历史记录将记录从原始“代码是 7”到“代码是 11”的更改,然后修补到“代码是 7"。另一方面,
重置
是历史记录的实际“倒带”。如果使用此命令,则对“代码为 11”的更改将从历史树中删除,并且存储库的状态就好像更改从未发生过一样。因此,虽然
revert
和reset
都可能导致您的存储库明显恢复到更改为“代码为 11”之前存在的相同状态,但它们是非常不同的概念上的操作。恢复
实际上创建新的历史记录,而重置
则删除现有历史记录。实际上,如果在存储库上执行
revert
操作,并且 Peter 从该存储库中提取数据,那么他的存储库实际上也会将更改记录回“代码为 7”。另一方面,如果对存储库执行重置操作,那么从 Peter 的存储库 POV 来看,他从中提取的存储库实际上处于比他的状态更旧的状态,并且不会发生任何情况。
这就是为什么使用 Git,只有在没有人拉取您的更改(或者您还没有推送到远程)时才应该使用重置。在所有其他情况下,您应该使用
revert
。I do not use Mercurial, but since you asked how Git behaves in this regard ...
In Git, there are two ways to undo:
revert
andreset
.The
revert
command patches the existing code so that it resembles a previous state: the history will record the change from the original "the code is 7" to "the code is 11" and then the patch to "the code is 7".On the other hand, a
reset
is an actual "rewinding" of the history. If this command is used, the change to "the code is 11" is removed from the history tree, and the state of the repository is as if the change never happened.Thus, while
revert
andreset
might both result in your repository being apparently restored to the same state that existed before the change to "the code is 11", they are very different operations conceptually.A
revert
actually creates new history, while areset
removes existing history.In practical terms, if a
revert
operation is carried out on a repository, and Peter pulls from it, then, indeed, his repository, too, will record the change back to "the code is 7".On the other hand, if a
reset
operation is carried out on a repository, then, from Peter's repo POV, the repository that he is pulling from is actually in an older state than his, and nothing will happen.Which is why with Git, you should only use
reset
if nobody has pulled your changes (or you have not pushed to a remote). In all other circumstances, you should userevert
.hg pull
不是完全同步。hg pull remote
所做的就是将remote
中不在本地存储库中的每个变更集复制到本地存储库。回滚所做的只是删除最近的提交(或者更一般地说,数据库操作,但这几乎总是提交) - 它不记录任何类型的“提交已被删除”消息。提交将永远消失,除非有另一个存储库拥有它。要记录其反转,以便其他存储库获得反转,您需要反转提交(这可以通过hg backout
创建)。然后你又进行了一次提交,它逆转了前一次的效果。因此,当您进行回滚并且 Peter 再次拉取时,您没有任何新的变更集可供 Peter 拉取。事实上,您的变更集比 Peter 少一个。因此,如果 Peter 向您推送,您将再次获得
11
修订版。在克隆场景中,它们都是最新的(因为它们都包含
7
修订版),但 Peter 有一个额外的变更集。这就好像 Peter 自己创建了11
变更,并在上面签上了您的名字。rollback
无法在跨存储库通信中安全或有意义地使用。为此,您需要backout
。出于这个原因,我总是更喜欢推送到已发布的位置并让人们从那里拉取,而不是让他们直接从我的工作存储库中拉取,以便我知道何时回滚是安全的,何时不安全(当我需要的时候)。hg pull
is not a full sync. Allhg pull remote
does is copy every changeset inremote
that is not in the local repository to the local repository. Allrollback
does is delete the most recent commit (or more generally, DB operation, but that's almost always a commit) - it does not record any kind of "commit has been deleted" message. The commit is gone, forever, unless there's another repository that has it. To record its reversal, so other repositories get the reversal, you need a reversing commit (this can be created viahg backout
). Then you have yet another commit which reverses the effect of the previous one.So, when you do the rollback and Peter pulls again, you don't have any new changesets for Peter to pull. In fact, you have one less changeset than Peter. So, if Peter pushed to you, you would get the
11
revision again.In the clone scenario, they are both up to date (as they both contain the
7
revision), but Peter has an additional changeset. It's as if Peter created the11
change on his own and signed your name to it.rollback
cannot be used safely or meaningfully across cross-repository communication. For that you needbackout
. For this reason, I always prefer to push to a published location and have people pull from there rather than have them pull directly from my working repository so that I know whenrollback
is safe and when it isn't (for the few times when I need it).Peter 不会看到任何未提交的更改。您的回滚仅影响您的工作目录。进行提交,然后彼得可以拉取/更新以查看您的回滚。
Peter won't see any uncommitted changes. Your rollback only affected your working directory. Do a commit and then peter can pull/update to see your rollback.