I have two branches, default and branch1. By mistake one person in our team merged branch1 with default. The content in branch1 is not yet ready to merge with default (it contains a major rework of the build & deploy environment).
We did an experiment with 'hg backout', backing out the merge (not sure this is the right way to do it). Then the changes from branch1 gets deleted on default, which is fine - but we can not remerge with branch1.
How should we solve this issue?
There are many scenarios here where you might want to do this, I'll make each scenario a headline, so that you can find the scenario that fits your case. Note that I'm still learning Mercurial, and I'd like pointers if something I say is wrong, using the wrong terminology, could be done better, etc.
The programmer has merged, but not done anything else, nor has (s)he shared the changes with anyone, in any way
In this case, simply discard the local clone, and get a fresh clone from a safe repository.
The programmer has merged, and continued working based on that merge. The changesets that followed the merge should be kept, but the merge itself should be removed. The changes (merge + following changesets) have not been shared with anyone
In this case I would do one of four:
To get rid of the merge changeset + all the following changesets, there's a couple of options:
Use the strip command in the MQ extension
hg strip <hash of merge changeset>
Clone and pull, and specify the hash of the changesets leading up to, but not including the merge. In essence, create a new clone by pulling from the damaged clone into a new one, and avoid pulling in the merge you don't want.
hg clone damaged -r <hash of first parent> .
hg pull damaged -r <hash of second parent>
The programmer has pushed to master repository, or to someone else, or someone pulled from the programmers repository. However, you (as in the group of developers) have control over all the repositories, as in, you can contact and talk to everyone before more work is done
In this case, I would see if step 1 or 2 could be done, but it might have to be done in a lot of places, so this might involve a lot of work.
If nobody has done work based on the merge changeset, I would use step 1 or 2 to clean up, then push to the master repository, and ask everyone to get a fresh clone from the master repository.
The programmer pushed the mergeset, and you don't know who will have the merge changeset. In other words, if you succeed in eradicating it from your repositories, a stray push from someone who still has it will bring it back.
Ignore the merge changeset and work in the two branches as though it never happened. This will leave a dangling head. You can then later, when you've merged the two branches, do a null-merge for this head to get rid of it.
M <-- this is the one you want to disregard
/ \
* *
| |
* *
| |
Simply continue working in the two branches:
| |
* *
| M | <-- this is the one you want to disregard
|/ \|
* *
| |
* *
| |
Then later you merge the two, the real merge you want:
m
/ \
* *
| |
* *
| M | <-- this is the one you want to disregard
|/ \|
* *
| |
* *
| |
You can then do a null-merge to get rid of the dangling head. Unfortunately I don't know how to do that except through TortoiseHg. It has a checkbox where I can discard the changes from one of the branches.
With TortoiseHg, I would update to the merge I want to keep (the topmost, lowercase m), then select and right-click on the dangling merge head below, and then check the "Discard all changes from merge target (other) revision":