Joymaker
Joymaker

Reputation: 1418

Mercurial, simplifying a multi-headed monster

I share an online Mercurial repository with one colleague. Came to a complicated situation:

On station A, made a mess and had to back up a few revisions. Created a clone, added new code there, and manually merged changes INTO that clone.

  1. Can't push, I now have multiple heads. Giving one of these a name as a named branch fixes nothing, to my dismay. After some study, I responded by closing all but the head I really wanted. Good idea? Bad idea?

  2. Push will create a new remote head. Having spent more than enough time on this, I went for push -f. It worked. But I really would rather have CONVINCED it that this is the true and rightful continuation of the head that was already there. But NOT a real merge, a full replacement with my new set of code files. How?

  3. Going to Station B and doing a pull, I don't get my newest, wanted head, I get the original head which I had closed, at its last real version. I'm looking around for how to tell the "pull" command to get the other head. How do I do that? How do I query the server as to what heads or branches it contains, so that I can intelligently pick one?

More information:

Station A view: Station A view Station B view after pull: enter image description here

Upvotes: 0

Views: 77

Answers (1)

Craig
Craig

Reputation: 776

There are a number of issues I see:

1) you attempted to use clone to git rid of the issue. Once you get familiar with Mercurial, you will find that there are better ways to fix the type of issues you describe.

Your description is unclear what steps you took with the clone. For example, did you clone from the master remote repo or from your local repo with the bad code.

2) When you tried to push, it stopped you with the warning about creating multiple heads on the remote repo. By using the -f option to hg push, your problem escalated. You ended up with two heads in your remote repository. Be careful with push -f. It overrides Mercurials attempt at preventing you from creating a problem. There may be good reasons for creating multiple heads on a remote repository, but it is best be be very clear that that is exactly what you want to do.

For the follow, I will assume that you pushed multiple heads to your remote repo.

At this point, the best solution would be to merge the two heads into one.

From you description, it sounds line you have something similar to this:

hg log -G

@  changeset:   4:fa78b78c5094
|  tag:         tip
|  user:        Craig
|  date:        Sun Oct 21 10:38:15 2018 -0600
|  summary:     Good commit 2
|
o  changeset:   3:af5cfaf651ff
|  parent:      0:f46808ac779b
|  user:        Craig
|  date:        Sun Oct 21 10:38:02 2018 -0600
|  summary:     Good commit 1
|
| o  changeset:   2:aabb053f11a9
| |  user:        Craig
| |  date:        Sun Oct 21 10:37:44 2018 -0600
| |  summary:     Bad commit 2
| |
| o  changeset:   1:9168cd930d40
|/   user:        Craig
|    date:        Sun Oct 21 10:37:32 2018 -0600
|    summary:     Bad commit 1
|
o  changeset:   0:f46808ac779b
   user:        Craig
   date:        Sun Oct 21 10:18:32 2018 -0600
   summary:     Commit some work

In my test repo, I would do the following to merge the heads together:

hg update 4

hg merge 2

Note: hg merge without the number will work if there are only two heads.

You will likely need to resolve merge conflicts.

Once the merge is complete, it will leave your repository with modified files (the merge results). Make sure that these modifications contain the changes you want only.

once you are completely sure that the changes (as a result of the merge) are what you want, you can commit the merge:

hg merge -m "Merge heads"

At this point you should now have just one heads that looks like the following:

@    changeset:   5:8f9e6a947b3a
|\   tag:         tip
| |  parent:      4:fa78b78c5094
| |  parent:      2:aabb053f11a9
| |  user:        Craig
| |  date:        Sun Oct 21 11:14:43 2018 -0600
| |  summary:     Merge heads
| |
| o  changeset:   4:fa78b78c5094
| |  user:        Craig
| |  date:        Sun Oct 21 10:38:15 2018 -0600
| |  summary:     Good commit 2
| |
| o  changeset:   3:af5cfaf651ff
| |  parent:      0:f46808ac779b
| |  user:        Craig
| |  date:        Sun Oct 21 10:38:02 2018 -0600
| |  summary:     Good commit 1
| |
o |  changeset:   2:aabb053f11a9
| |  user:        Craig
| |  date:        Sun Oct 21 10:37:44 2018 -0600
| |  summary:     Bad commit 2
| |
o |  changeset:   1:9168cd930d40
|/   user:        Craig
|    date:        Sun Oct 21 10:37:32 2018 -0600
|    summary:     Bad commit 1
|
o  changeset:   0:f46808ac779b
   user:        Craig
   date:        Sun Oct 21 10:18:32 2018 -0600
   summary:     Commit some work

Before pushing the merged code to the remote repository, it is very important that you verify that the changes are correct and tested. pushing a bad merge just compounds the problem.

My best advice is to take you time with this and verify each step does what you expect and want.

Upvotes: 2

Related Questions