The use of local branches

From OTBWiki
Jump to: navigation, search


Introduction

Heavy new stuff may take quite a long time to be stable and mature enough to be shared even with other developpers. Mercurial, as a distributed SCM, allows to keep a fine-grain history through local commits without letting the genie out of the bottle. It is only through merging and pushing the new changesets to some common repository that new things gets available to others. Yet it is quite frequent that one would like to work on heavy stuff while maintaining the ability to perform fixes and smaller task on the trunk, without releasing into the open experimental and unfinished changesets. With mercurial, there are two natural answers to this problem : cloning and branching.

Making a new clone and working the heavy stuff in it is probably the simplest way: things get naturally separated since they happen in distinct folders. However, maintaining and building multiple clones may prove to be quite demanding, in terms of physical spaces and working folder organization. In this short article, we will investigate the other option: branching. We will demonstrate how to :

  • Start a new local branch,
  • Work in it,
  • Switch to the trunk and back,
  • Close the branch if it appears to be a dead-end,
  • Merge the branch with the trunk when it is ready.

Creating a new branch and working in it

The first step toward local branching is to create a new branch, which can be done by using:

hg branch new_heavy_feature

This creates a new branch called new_heavy_feature and switch to it.

To check on which branch the repository currently is, simply run:

$ hg branch
new_heavy_feature

We can now start working and make commits, as usual:

$ hg commit -m "ENH: my new changeset"


To see all available branches, you may run:

$ hg branches
new_heavy_feature          16326:d499e4b4fd6c
default                    16325:e1932b72ca58 (inactive)

Note that the default branch is the trunk (and currently marked inactive). Also note that a branch with no changesets in it will not appear here.

Switching to trunk and back

To switch back to the trunk, simply run:

$ hg update default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

You are now working on the trunk version shared with everybody. You can commit, pull --rebase and push without sharing the changesets you made in your new_heavy_feature branch.

Careful: if you simply run

$ hg push

You will get the following error:

searching for changes
abandon : push creates new remote branches: new_heavy_feature!
(use 'hg push --new-branch' to create new remote branches)

Do not try to force pushing (using the -f option or --new-branch)! In OTB it is forbidden to push new remote branches (actually this may even be forbidden on the server side). To push your changesets made to the trunk, you need to specify the head you want to push. The topmost head of the trunk is the one with no branch properties:

$ hg heads
changeset:   16326:d499e4b4fd6c
branch:      new_heavy_feature
tag:         tip
user:        <>
date:        Thu Oct 31 14:35:06 2013 +0100
summary:     ENH: New commit in new_heavy_feature branch

changeset:   16325:e1932b72ca58
user:        <>
date:        Thu Oct 10 17:01:28 2013 +0200
summary:     ENH: Some trunk commit

You therefore need to specify the correct changeset short (or long) id to push:

$ hg push -r 16325

Last, you can switch back to your local branch running:

$ hg update new_heavy_feature

Work done: merging with trunk

Once the work on the local branch is completed and you want to share it with others, you can rebase your branched changesets on trunk. If you need to, you ensure you are on the trunk and rebase incoming changeset:

$ hg update default
$ hg pull --rebase

Now, track the head of the local branch you want to rebase :

$ hg heads
changeset:   16326:d499e4b4fd6c
branch:      new_heavy_feature
user:        <>
date:        Thu Oct 31 14:35:06 2013 +0100
summary:     ENH: New commit in new_heavy_feature branch

changeset:   16325:e1932b72ca58
tag:         tip
user:        <>
date:        Thu Oct 10 17:01:28 2013 +0200
summary:     ENH: Some trunk commit

And rebase the commits of your local branch onto trunk using the -b option and the id of the head of you local branch:

$ hg rebase -b 16326

Now, the local branch you created is no longer visible:

$ hg branches
default                    16442:518c25a95e45

And you can safely push to trunk.

Dead-end: closing branch

If your work reaches a dead-end, you can get rid of the local branch you created by closing it:

$ hg update new_heavy_feature
$ hg commit --close-branch -m "Closing dead-end"
$ hg update default

The branch will no longer appear in hg branches. However, it is still there, and you can still swith to it using hg update.