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.
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.
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.
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!
In the TortoiseHg client's Commit dialog, right-click the needed file and then click Revert.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With