What's the best way to close a Mercurial branch?

Lieven Cardoen picture Lieven Cardoen · Jun 18, 2013 · Viewed 15.6k times · Source

Is it better to first close a branch and then merge it with the default branch(for instance) or first merge it and then close it?

In TortoiseHg for instance, in the first case, you'll see a line from a close node to the default branch. In the second case you'll see a line from the last commit to the default branch and an extra line from the last commit to a close node.

I hope I'm clear. Maybe it's a matter of taste...

Answer

Ilia Barahovski picture Ilia Barahovski · Oct 28, 2014

This isn't a matter of taste and there's a difference. In short, close the branch, then merge.

The thing is for Mercurial branch names is a mere "metadata" for each changeset. It does affect results of certain commands like hg branches omits closed ones, or hg push disallow addition of new head per branch by default. But again - it's filtering.

Internally, Mercurial sees repository as a graph of changesets, DAG to be specific. And topological heads of that graph are used for logic implementation, for example while comparing local and remote repositories during hg pull. Larger number of topological heads can (slightly, but still) affect performance - How do closed branches affect Mercurial performance?. As well certain number of them can cause 400 Bad Request from Mercurial running in IIS server - https://bitbucket.org/site/master/issue/8263/http-400-bad-request-error-when-pulling.

When one first merge and then close, the branch is close - all right, and human doesn't see that branch by default. But mercurial gets another topological head. Look below for visual explanation. Hence close first.

close then merge                merge then close
----------------                ----------------

@    default, head              @    default, head
|                               |
o    merge              <-->    | x  close branch, head
|\                              | |
| x  close branch       <-->    o |  merge
| |                             |\|
o |  dev on default             o |  dev on default
| |                             | |
| o  dev on branch              | o  dev on branch
| |                             | |
| o  open branch                | o  open branch
|/                              |/
o    default                    o    default

You may look here for details on how we came to this conclusion.