Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Mercurial only have one level of rollback?

I understand the restrictions of rollback and the care required in its use, but I just wondered why there is only one level of rollback.

My guess it's a design decision and that the hassle of storing multiple previous transactional states to handle multiple levels of rollback is more trouble than its worth.

like image 536
Nick Pierpoint Avatar asked Jun 18 '10 11:06

Nick Pierpoint


People also ask

How do I rollback a commit in Mercurial?

If you want to revert just the latest commit use: hg strip --keep -r . Using strip will revert the state of your files to the specified commit but you will have them as pending changes, so you can apply them together with your file to a new commit.

What is backout in mercurial?

Backout works by applying a changeset that's the opposite of the changeset to be backed out. That new changeset is committed to the repository, and eventually merged.

How do you undo the last commit in Heartgold?

You can manually trigger a rollback with 'hg rollback'. This will undo the last transactional command. If a pull command brought 10 new changesets into the repository on different branches, then ' hg rollback ' will remove them all. Please note: there is no backup when you rollback a transaction!

How do I revert a commit in TortoiseHg?

In the TortoiseHg client's Commit dialog, right-click the needed file and then click Revert.


2 Answers

There's only one level of rollback because rollback was never really intended as a feature. Rollback exists, and has it's odd name, because it grew out of mercurial's commit/push/pull transaction system.

If a network push is coming in and it gets 99% done and then the connection is lost the repository shouldn't be left in an inconsistent state. To make sure that an incomplete change can be discarded a "before anything happened" pointer is created before any writes are done and if the change is aborted everything is reset to that state -- rolled back.

The rollback command is really just "failing" the previous operation after it had successfully completed. It's just something that "came free" after necessary transactional security was designed in.

When using something like a controlling hook one can define checks/tests that must be passed in order for a push or commit to complete successfully. In order to not-complete successfully it must be possible to undo that in progress commit, but that doesn't require multiple levels either.

As VonC correctly notes rollback can be pretty dangerous. Many a person rollsback changes they've already pushed and then gets very confused when other those changes come back on subsequent pulls. The hg backout command is almost always a better idea.

Note also that you can simulate a rollback to any point in time easily by doing this:

hg clone -r last_revision_I_want repo_with_things_I_do_not_want new_repo_with_only_good_stuff
like image 100
Ry4an Brase Avatar answered Oct 25 '22 00:10

Ry4an Brase


The trick is: hg rollback is not just about resetting some commits, it reset every data and meta-data associated with the repository.
It actually has no equivalent in Git, and is quite a dangerous mechanism.
It can be mis-used as a way to rewrite the history by resetting it, and that can "reset" more than you wanted.
To allow this on more than one level back would be too dangerous.

When it comes only to resetting/rewriting changeset (which are, by design, immutable), extensions like MQ are better suited.

like image 29
VonC Avatar answered Oct 25 '22 01:10

VonC