问题
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?
回答1:
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 use hg commit to create a new commit based on the older revision, and then have people pull that commit.
回答2:
I do not use Mercurial, but since you asked how Git behaves in this regard ...
In Git, there are two ways to undo: revert and reset.
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 and reset 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 a reset 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 use revert.
回答3:
hg pull is not a full sync. All hg pull remote does is copy every changeset in remote that is not in the local repository to the local repository. All rollback 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 via hg 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 the 11 change on his own and signed your name to it.
rollback cannot be used safely or meaningfully across cross-repository communication. For that you need backout. 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 when rollback is safe and when it isn't (for the few times when I need it).
回答4:
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.
来源:https://stackoverflow.com/questions/3034793/in-mercurial-when-peter-hg-clone-me-and-i-commit-and-he-pull-and-update-he