At 11:33 PM

Mercurial branches - ‘named branches’ way - prefered way to do it?

Mercurial provides many ways to do branch based development. I was searchingfor the best in-repo branch solution. I chose named branches …

Branching in mercurial

Mercurial provides following solutions to branch based development:

  • hg tag + hg clone + push/pull :

    • dvcs - isolation done with distinct repositories
    • in the book it looks like this is most common way to do branch development
  • hg branch , a.k.a. named branches :

    • standard builtin command(s)
    • enable in-repo branches
    • can be transfered accross the wire
    • the subject of this article
    • reference here
  • bookmarks extensions

    • hg bookmarks - standard mercurial extension
    • needs to be enabled
    • transfered if both sides enable extension
    • IMHO very similar to named branches but not so elegant
    • reference here
  • anonymous branch

    • hg up -C + hg ci -m”commit on old revision”
    • system similar to named branches, but with no names ;)
    • reference here
  • mq extension

    • extension for management of mutable changesets, that can be used for branch development too, but haven’t yet figured how ;)
    • seems a bit complicated for my needs
    • reference here

Between all these options I chose named branches as the best way to do in-repo branches (simple, native, handy, works accross the wire, just works). The basic workflow is explained in next sections.


I won’t explain much, I’ll just list operations used in standard workflow of branch development.

Create new named branch

The command will create new branch named for instance, after feature nr. 91 (such branch should not previously exist). After command finishes, it will switch working copy to newly created branch:

<default> hg branch feat91

List all created branches

<> hg branches

On which branch am I?

<feat91> hg branch

Switch working copy to branch

The command will switch working copy (with local changes) to branch feat91:

<default> hg update feat91

(some documentation suggests using -C option but it works without -C).

First push of newly created branch to other repo

First push of newly created branch to other repo needs extra option —new-branch:

<> hg push --new-branch

Next pushes goes normal (hg push).

See incomming changes from feat91 to current

How to see incomming changes from feat91 to current - default branch (preview merge):

<default> hg merge -P feat91

Merge changes from branch feat91 to default

<default> hg merge feat91

check changes and commit:

<default> hg commit -m"merged feat91 -> default"

Merge changes from default branch to feat91

<feat91> hg merge default

check changes and commit:

<feat91> hg commit -m"merged default -> feat91"

Close a branch

There are many ways to do it, but this one I found as the most regular one. Workflow:

list branches

<feat91> hg branches

close a branch:

<feat91> hg commit --close-branch -m "close feat91"

The command will just chang status of branch to “closed”, the branch won’t be stripped, and you can come back to it anytime, and if you like you can reactivate it and continue development on it.

After closing it is advised to switch to an active branch:

<feat91> hg up default

Default listing of branches won’t show closed:
<default>hg branches

But if you like you can list closed too:

<default> hg branches -c
feat91 (closed)

Like noted before, after closing you can switch to closed branch:
<default> hg up feat91

You can make changes and commit - what will automatically put branch to “reopened” state:
<feat91> hg ci -m"commit in feat91 after close"
reopening closed branch head 11

List branches after reopening: <> hg branches -c default feat91 (inactive)

and you can close it again:

<feat91> hg ci --close-branch -m"closing feat91 again"

View branches log graphically

hg serve won’t show this graphically, but there is extension graphlog which can show this in console. Enable it in .hg\hgrc

hgext.graphlog =

and try:
<default> hg glog

| o  changeset:   8:4b4d4b76110b
| |  branch:      feat91
| |  user:        trebor74hr
| |  date:        Sat Sep 03 18:47:43 2011 +0200
| |  summary:     new feature in feat91
| |
| o  changeset:   7:8d78dd2d7334
|/|  branch:      feat91
| |  parent:      4:0d29e1ecb689
| |  parent:      6:04ec650ace3c
| |  user:        trebor74hr
| |  date:        Sat Sep 03 18:45:04 2011 +0200
| |  summary:     merged default -> feat91
| |
o |  changeset:   6:04ec650ace3c
|\|  parent:      5:3c4a79f2ac3b
| |  parent:      4:0d29e1ecb689
| |  user:
| |  date:        Sat Sep 03 18:39:28 2011 +0200
| |  summary:     merged feat91 -> default
| |
o |  changeset:   5:3c4a79f2ac3b
| |  parent:      2:fbc6ab30159e
| |  user:
| |  date:        Sat Sep 03 18:34:06 2011 +0200
| |  summary:     ovaj ci u default branch-u zelim u feat91 branch prebaciti
| |
| o  changeset:   4:0d29e1ecb689
| |  branch:      feat91
| |  user:        trebor74hr
| |  date:        Sat Sep 03 18:33:54 2011 +0200
| |  summary:     ovo je f1 commit u feat91
| |
| o  changeset:   3:308b5d06a330
|/   branch:      feat91
|    user:        trebor74hr
|    date:        Sat Sep 03 18:29:52 2011 +0200
|    summary:     branch feat91 commit
o  changeset:   2:fbc6ab30159e
|  user:
|  date:        Sat Sep 03 18:28:07 2011 +0200
|  summary:     noc

Other references
blog comments powered by Disqus


  1. trebor74hr posted this