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