Abandoning changes without deleting from history

Viewed 55119

There is a commit that just didn't work, so I want to abandon it without deleting it from history.

I have updated from an earlier revision and committed, thus creating a new head.


I don't have branches, I don't want branches, I just want to simply go on with the new head exactly as it is, nothing fancy, no merge, no worries, just go on forgetting the previous one.

I can't seem to find how to do that, and I'm starting to believe it can't be done. All I find is stuff about branches, or stuff about merging.

9 Answers

An alternative to closing or stripping the unwanted branch would be to merge it in a way that totally discards its effects, but leaves it in history. This approach will allow those unwanted changes to propagate in a push - so only use this if that is the intended effect.

Let's say the changeset history looks like this:

1-2-3-4-5-6    
       \    
        7-8-*

and it is 5 and 6 which are no longer wanted.

You can do this:

hg up 8
hg merge -r 6 -t :local
hg commit ...

which will create this:

1-2-3-4-5-6    
       \   \
        7-8-9-*

The update to 8 ensures you are working at the desired head in history, which you want to keep.

The -t :local instructs hg to use the merge "tool" called local which tells it to ignore changes from the other branch, i.e., the one NOT represented by the current working folder state. More info.

Thus the unwanted changes in 5 and 6 are preserved in history but do not affect anything more recent.

This is a use case for the Evolve extension. It's currently not bundled with Mercurial, so it is technically a third party extension. But it's being used quite heavily by a bunch of people, including Mercurial developers, is being very actively developed, and isn't going anywhere.

With the Evolve extension, you simply do

hg prune -r revname

and get on with your life. The cset will still be there, but obsoleted. It won't be visible unless you pass the --hidden option to Mercurial commands, and by default won't be pushed to remote repositories. Though I think you can force it if you really want to.

If the cset you are pruning has ancestors you want to keep, then you'll have to run hg evolve to rebase those changesets. hg evolve will do so automatically. Otherwise, you don't have to do anything.

Related