I had created a head in a Mercurial (Hg) repository, at the time, I thought that was a good idea to keep it around, even there would be no more commits on top of that head. However, it’s not, because it always showed up in hg heads.

1   Solution

I would like to merge but not to keep changes of that head. A solution is to use hg debugsetparents, the basic process is like:

$ hg debugsetparents . <REV-OF-ANOTHER-HEAD>
$ hg commit -m 'Drop <REV-OF-ANOTHER-HEAD>'

The result will look like a merge in hg log --graph, but we do not use merge command but a commit command. For this new commit, it will have two parents, one is the commit of that head, another is working copy’s original parent.

Although I don’t know the scene behind, it should be essentially a merge because of two parents. We set an additional parent and commit like a regular commit.

2   Walkthrough

For an example, consider the following repository:

$ hg log -G
@  changeset:   3:3b1ae782fe5f
|  tag:         tip
|  parent:      1:54b67fbaf3c5
|  user:        Yu-Jie Lin <livibetter@gmail.com>
|  date:        Fri Nov 23 20:14:53 2012 +0800
|  summary:     #3
|
| o  changeset:   2:8f2a69f44b85
| |  parent:      0:a2f66ef0d5cd
| |  user:        Yu-Jie Lin <livibetter@gmail.com>
| |  date:        Fri Nov 23 20:14:08 2012 +0800
| |  summary:     #2
| |
o |  changeset:   1:54b67fbaf3c5
|/   user:        Yu-Jie Lin <livibetter@gmail.com>
|    date:        Fri Nov 23 20:12:35 2012 +0800
|    summary:     #1
|
o  changeset:   0:a2f66ef0d5cd
   user:        Yu-Jie Lin <livibetter@gmail.com>
   date:        Fri Nov 23 20:11:16 2012 +0800
   summary:     init

As you can see, there is two heads, #2 and #3. The contents of example file test in two heads are:

$ hg cat -r 3 test
init
#1
#3

$ hg cat -r 2 test
init
#2

Now, run the command to set #2 as a parent also:

$ hg debugsetparents . 2

At this stage, the current working copy has two parents:

$ hg parents
changeset:   3:3b1ae782fe5f
tag:         tip
parent:      1:54b67fbaf3c5
user:        Yu-Jie Lin <livibetter@gmail.com>
date:        Fri Nov 23 20:14:53 2012 +0800
summary:     #3

changeset:   2:8f2a69f44b85
parent:      0:a2f66ef0d5cd
user:        Yu-Jie Lin <livibetter@gmail.com>
date:        Fri Nov 23 20:14:08 2012 +0800
summary:     #2

Commit the change of parents:

$ hg commit -m 'drop #2 head'

The graph shows a merge-like graph for the new commit:

$ hg log -G
@    changeset:   4:ad4ac7c7b4a7
|\   tag:         tip
| |  parent:      3:3b1ae782fe5f
| |  parent:      2:8f2a69f44b85
| |  user:        Yu-Jie Lin <livibetter@gmail.com>
| |  date:        Fri Nov 23 20:29:01 2012 +0800
| |  summary:     drop #2 head
| |
| o  changeset:   3:3b1ae782fe5f
| |  parent:      1:54b67fbaf3c5
| |  user:        Yu-Jie Lin <livibetter@gmail.com>
| |  date:        Fri Nov 23 20:14:53 2012 +0800
| |  summary:     #3
| |
o |  changeset:   2:8f2a69f44b85
| |  parent:      0:a2f66ef0d5cd
| |  user:        Yu-Jie Lin <livibetter@gmail.com>
| |  date:        Fri Nov 23 20:14:08 2012 +0800
| |  summary:     #2
| |
| o  changeset:   1:54b67fbaf3c5
|/   user:        Yu-Jie Lin <livibetter@gmail.com>
|    date:        Fri Nov 23 20:12:35 2012 +0800
|    summary:     #1
|
o  changeset:   0:a2f66ef0d5cd
   user:        Yu-Jie Lin <livibetter@gmail.com>
   date:        Fri Nov 23 20:11:16 2012 +0800
   summary:     init

You can see two parents of new commit. Check file content, it’s same as #3, of course:

$ hg cat -r 4 test # cat test
init
#1
#3

If you have more than two heads, just repeat the process until all heads are merged.