View source | Discuss this page | Page history | Printable version   
Main Page
Upload file
What links here
Recent changes

PDF Books
Add page
Show collection (0 pages)
Collections help


Mercurial Manual for Openbravo Developers



This manual explains the usage of Mercurial for community developers of Openbravo ERP and Openbravo POS. It details the particular configuration and procedures recommended to work in an Openbravo project.

This is not a complete Mercurial manual. If you are looking for general Mercurial resources, there is excellent documentation:


Introduction to distributed SCMs

Before starting with Mercurial, is a good idea to have a general view of what distributed SCMs are and how they work. First of all, read the Understanding Mercurial and Intro to Distributed Version Control (Illustrated) documents. They illustrate the basic concepts.

In a centralized SCM there is only one central repository. Developers have working copies of this repository, and changes are committed to this central site. It is not possible for developer A to share changes with developer B without passing the changes by the central repository. This problem is solved by the distributed SCMs. Instead of checking out a working copy, you get a full clone copy of the repository.

This means that once you have the repository locally, all the operations are local and therefore very fast. Everyday command like diffs, merges, commits and reverts are all done locally. There's no server to ask for old revisions from a year ago.

Additionally, every cloned repository can be considered as a new branch. Merging is an every day operation in distributed SCMs and it is much faster compared to centralized systems. You merge locally and then optionally push the results to another repository.

Finally, a distributed SCM offers working with different collaboration models, even in a centralized manner.

If you want a quick and nice tutorial, follow the Mercurial Kick Start.


Use Mercurial 1.1 or later. Use the hg version command to check it.


If you are are on testing (squeeze) or unstable (sid):

apt-get install mercurial

The current stable version of Debian (Lenny) includes Mercurial 1.0.1, which is old for Openbravo's requirements. If you are running Lenny thenbuild Mercurial from sources


Install Mercurial from the Mercurial Releases PPA. If you are using Lucid (10.04) or Karmic (9.10):

sudo add-apt-repository ppa:mercurial-ppa/releases
sudo apt-get update
sudo apt-get install mercurial

If you are using Jaunty (9.04) or Hardy (8.04):

sudo sh -c 'echo "deb YOUR_UBUNTU_VERSION_HERE main" >> /etc/apt/sources.list'
sudo sh -c 'echo "deb-src YOUR_UBUNTU_VERSION_HERE main" >> /etc/apt/sources.list'
sudo apt-key adv --keyserver --recv-key 323293EE
sudo apt-get update
sudo apt-get install mercurial


Install the latest Mercurial release:

echo dev-vcs/mercurial >> /etc/portage/package.keywords
emerge -av mercurial


There are 2 options:

  1. Use the command line version and install it using a prepackaged binary installer. This is the easiest method.
  2. Install using MacPorts. This method is a little more involved, because you need to first download and install MacPorts, which involves making sure you have the latest Xcode installed. Once you have MacPorts set up:
sudo port -v install mercurial

Microsoft Windows

There are 2 options:

  1. Use the command line version and install it using a prepackaged binary installer.
  2. TortoiseHg: an all-inclusive Mercurial binary installer package for Windows, which provides a windows explorer extension (shell extension), so that Mercurial commands can be executed from the context menu of the explorer.


You should configure Mercurial just after installing it. On UNIX-like systems, this should be done in your $HOME/.hgrc file. On Windows, these settings can be added to C:\Program Files\Mercurial\Mercurial.ini, or, if you'd like per-user settings, $HOME\.hgrc or $HOME\Mercurial.ini. (if the file does not exist you should create it manually).

Your Mercurial configuration file should have at least the following settings:

username = Your Real Name <>
merge = your-merge-program

git = 1

The username is used to identify the commit author.

It is very important to choose a merge program. There are many popular options to choose from, like Meld, KDiff3 or TortoiseMerge.

The git = 1 diff option specifies to use the extended git format. This allows including file permission changes in the diffs.

You can configure the editor to use for commit messages using the editor option in the [ui] section or by setting the EDITOR environment variable.


Extensions allow the creation of new features and using them directly from the main hg command line as if they were built-in commands.

Sample extensions:

To enable an extension, add it to the [extensions] section of your $HOME/.hgrc. For example to enable the color, rebase and transplant extensions:

username = Your Real Name <>
merge = your-merge-program

color =
rebase =
transplant =

Some extensions are shipped along with Mercurial. Others can be added externally. Check the official web page for a list of extensions.

Custom diff program

It is usually be very useful to view a diff using an external program like meld, kdiff3.

Activation of the extension:

extdiff =

Specify the desired program:

cmd.vdiff = meld

Example of use:

hg vdiff

For more information about extdiff check the official guide.


From the book Distributed revision control with Mercurial:

"'s often good practice to keep a 'pristine' copy of a remote repository around, which you can then make temporary clones of to create sandboxes for each task you want to work on. This lets you work on multiple tasks in parallel, each isolated from the others until it's complete and you're ready to integrate it back. Because local clones are so cheap, there's almost no overhead to cloning and destroying repositories whenever you want."

We recommend this process of using cheap local clones. The general process is:

A developer could have several temporary clones of the same repository to isolate different developments. For example, if a developer is fixing two bugs simultaneously but wants the commits and tests to be isolated, he would use two separate clones.

We propose having a topology were $HOME/src contains all the pristine copies of the projects you are working on. And $HOME/workspaces contain the clones of these pristine copies. The repositories from $HOME/src are updated from the central repositories and the ones from $HOME/workspaces are updated from the local $HOME/src repositories.

  |--- openbravo/
        |--- erp
                 |--- main
                 |--- pi
                 |--- project1
                 |--- project2
                 |--- 2.3x
                 |--- 2.40
  |--- openbravo/
        |--- erp
                 |--- main
                 |--- pi
                 |--- project1
                 |--- project2
                 |--- 2.3x
                 |--- 2.40

This document will assume that the pristine copies are stored under $HOME/src and the local clones under $HOME/workspaces. If you choose different locations, take it into account when following the examples.

Creating the local pristine clones

While in Subversion a checkout updates your working copy from a repository, in Mercurial you first update your local repository and then the working copy.

In the Mercurial terminology this is called a clone. A clone is a copy of a repository in a new directory. To do a clone:

mkdir -p $HOME/src/openbravo/erp/devel
cd $HOME/src/openbravo/erp/devel
hg clone

Do as many clones as projects you are going to work on.

Remember that these are pristine clones you will keep unmodified.

Keeping the local pristines clones up to date

Check what you're going to pull:

cd $HOME/src/openbravo/erp/devel/pi
hg incoming

To keep your clone up to date, update the repository with these changes:

hg pull

Then, to update your working copy:

hg update

Note that it is possible to combine these two steps in one:

hg pull -u

Since this clone is a pristine copy of the remote repository you may want to maintain it up to date with a cron job.

Creating local working clones

To start working on a project, you should create a local clone of the pristine clone:

mkdir -p $HOME/workspaces/openbravo/erp/devel
cd $HOME/workspaces/openbravo/erp/devel
hg clone $HOME/src/openbravo/erp/devel/pi

Periodically you will want to update the local clone from the pristine clone:

cd $HOME/workspaces/openbravo/erp/devel/pi
hg incoming
hg pull -u

These are the clones where you develop your code.

Check in to the central repository

Required configuration

Firstly make sure you have configured your $HOME/.hgrc with your username.

Secondly, to push to the Openbravo repositories you need push access (or someone with push access needs to pull from your repository).

Commit locally

To check if you're really committing what you want to commit:

hg status
hg diff

Note that while Subversion applies the command to the specific directory you are in, Mercurial applies it to the entire tree. To see the status or diff of a specific directory specify it as an argument:

hg status web/js
hg diff web/js/message.js

As the next step, commit your changes to your local repository:

hg commit -m "message"

You can make as many atomic commits as you need. This commits won't be seen in other repositories until you push them.

Push to the central repository

To check what you are going to push:

hg outgoing

To actually send the commits to the central repository:

hg push

If you receive the message "abort: push creates new remote heads", do not do what the message suggests (hg push -f). What this message means is that some changes have been done to the central repository since the last time you updated your local repository. If you do it the server will reject it anyway. We recommend following one of these two approaches:

In case of doubt use the first approach: rebase


Check that the rebase extension is enabled in your .hgrc file:

rebase =

Now, type:

hg pull --rebase

This will pull and rebase your local changesets at the same time. More details and options can be found at the Mercurial wiki.

So now you are ready to push your commits:

hg push

In the process of the rebase, it may discover conflicts. In that case it will stop and allow you to fix the conflicts. After fixing the conflicts, use hg resolve to mark the files as resolved, and then, instead of running hg commit just run hg rebase --continue. Example:

$ hg pull --rebase
pulling from /home/johndoe/src/openbravo/erp/devel/pi
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)
merging src/build.xml
warning: conflicts during merge.
merging srv/build.xml failed!
abort: fix unresolved conflicts with hg resolve then run hg rebase --continue

Now we edit src/build.xml and fix the conflicts. Then, we mark the files as resolved:

$ hg resolve -l
U src/build.xml
hg resolve -m src/build.xml
hg resolve -l
R src/build.xml

And we continue the rebase process:

$ hg rebase --continue
saving bundle to /home/johndoe/src/openbravo/erp/devel/pi/.hg/strip-backup/05a5fc850b1f-temp
adding branch
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files
rebase completed


Pull the latest changes from the repository:

hg pull

This will create an extra head locally. Merge the two heads:

hg merge

Commit the result:

hg commit -m "Merge heads A and B"

Push to the central repository:

hg push

Fixing a bug

Example: the developer has to fix issue 6265 in main.

The developer starts going to the local work clone of the main repository. Then the developer can start fixing and testing the issue in that clone, doing as many commits as needed. Each commit should be an atomic piece.

cd $HOME/workspaces/openbravo/erp/devel/pi
hg ci -m "Fixes issue 6265."

When the developer is happy with the fix, the changesets can be pushed to Openbravo repository.

hg push

Before pushing it is a good idea to see what's going to be pushed with hg outgoing

Backporting a bug fix

Example: the developer has to backport the fix of issue 6265 from devel/pi to stable/2.40.

The developer has already fixed the bug in one branch and wants to repeat the fix in another branch. Then he can use transplant to apply the same fix in this branch (4544 is the revision of the commit done to fix this bug in main):

cd $HOME/workspaces/erp/stable/2.40
hg transplant -s $HOME/workspaces/erp/devel/pi 4544

After testing the fix, he can push the update to Openbravo repository and delete the temporary clone:

hg outgoing
hg push

The transplant extension is distributed along with Mercurial. Another possibility to backport changes is to use hg export and hg import.

Developing a new feature

New features can be developed in local repositories. But if other core developers or community members are also contributing to this feature, you want a public repository to share your developments.

Example: the developer wants to start a community project to develop a new feature based on main.

hg clone $HOME/src/openbravo/erp/devel/modularity
hg clone $HOME/src/openbravo/erp/devel/modularity $HOME/workspaces/openbravo/erp/devel/modularity
hg clone $HOME/src/erp/devel/pi $HOME/src/erp/devel/merge_modularity
cd $HOME/src/erp/devel/merge_modularity
hg pull $HOME/src/erp/devel/modularity
hg merge
(conflict resolution)
hg ci -m "Merged modularity."

Instead of pull+merge+commit, the fetch extension could be used.

Once the merge is done, the changesets can be pushed into the centralized main repository and the merge repository can be deleted:

cd $HOME/src/erp/devel/merge_modularity
hg outgoing
hg push
rm -rf $HOME/src/erp/devel/merge_modularity

Finally, the modularity repository can be deleted.

Backing out changes

Generally if you make a mistake and want to fix it, you should just edit sources to fix it and commit a new revision. This preserves history of the mistake and its correction and is suitable for routine programming errors.

I've committed one changeset locally, it's not pushed

If you commit something that you really cannot tolerate being in history (e.g. legally forbidden files, passwords) it is possible to discard the commit only if you have not yet pushed it (Once it is on the server, it is permanent). If you have just committed the change and nothing else, just run hg rollback. Your working copy will still be modified; you can hg revert if you need to.

Alternatively you can also make a version of the repository that does not include the latest changes. Use hg clone -r and pass in the "last known good" changeset ID.

I've committed one changeset locally, it's pushed

Just back it out and push it:

hg backout -r REV
hg push

I've committed more than one changeset locally, it's not pushed

If you commit several changesets locally but you haven't pushed them, it is possible to backout the changes in 2 different ways:

mq =

If you strip out a changeset from your local repository, it will be removed along with all descendant changesets. Be careful. (Do backups)

Alternatively you can also make a version of the repository that does not include the latest changes. Use hg clone -r and pass in the "last known good" changeset ID.

I've committed more than one changeset locally and it's pushed

The easiest way is to revert your local working directory to the REV you want to revert to and then commit the changes:

hg revert -a -r REV
hg commit -m "Back our changesets A, B and C"

Triggering actions in the issue tracker

As a general rule your commit must be related to an issue reported in Mantis. You can benefit from the integration between Mercurial and Mantis. Depending on the comment you write for the commit, a note can be automatically added to the issue. Moreover, the status of the issue can be automatically set to resolved.

Take into account that writing issue A and issue B in the same commit message will add comments to both issues. So, for example, solve issue 321, related to issue 223 would add a comment to issues 321 and 223 and solve issue 321. If you want to reference another issue in the same comment, use issue #B instead. In our example: solve issue 321, related to issue #223.

New repository for new feature

Bulbgraph.png   This feature is not implemented yet in

Sharing changes with other developers is an easy task with SSH or using the built-in web server. However, there are situations where developers want to share the work with other developers or with the community in a centralized manner.

There is no built-in support in Mercurial for server-side copy of a branch (i.e. remote to remote cloning). However, an interactive script could be added to the server to provide this feature. An example session could look like this:

$ ssh $ 'create erp feature-1'
Clone another ERP branch? Answering no will create an empty repository [Y/N]: Y
Name of the branch to clone: erp/devel/pi
Your new branch is at

Core developers are allowed to create remote clones of the main repository.

An alternative to SSH is to create your own web interface to manage these requests.

New developer & access controls

Bulbgraph.png   This feature is not implemented yet in

Every repository will have one or more developers in charge of them (manager). The Project Managers decide who can pull/push and who cannot.

To add a new developer, an interactive script could be added to the server to provide this feature. An example session could look like this:

$ ssh $ 'addhguser'
Create a new account? [Y/N]: Y
Developer user name: johndoe
Developer e-mail:
New user created. An e-mail has been sent to with the developer credentials.

Equally, to delete a developer account:

$ ssh $ 'delhguser'
Delete an existing account? [Y/N]: Y
Developer user name: johndoe
This is permanent. Are you absolutely sure? [Y/N]: Y
User johndoe deleted.

Finally, the developer in charge of a repository is capable of managing the access controls. An example session could look like this:

$ ssh $ 'hgacl'
Manage access controls? [Y/N]: Y
You are the manager of the following repositories:
  * erp/devel/pi
  * erp/devel/localization
  * erp/devel/my-feature-1
Select a repository: erp/devel/my-feature-1
Developer user name (use 'all' for anonymous): johndoe
Current permissions of johndoe in erp/devel/my-feature-1:
Select action: +pull
Permissions modified for user johndoe in erp/devel/my-feature-1:

Sharing repositories with local developers

The easiest way to share a repository with a developer in the same LAN is to use hg serve, it includes a mini-web server:

~/workspaces/openbravo/erp/devel/pi $ hg serve -v
listening at (bound to *:8000)

Alternatively you can clone/push/pull directly using SSH:

hg clone ssh://john@

In this case the repo would be located in /home/john/workspaces/erp/devel/pi. To specify absolute paths use double slashes (//):

hg clone ssh://john@

Write meaningful commit messages

Both the hg log command and the hgweb web interface print only the first line of a commit message by default. So it's best to write a commit message whose first line stands alone. Our recommendation is to write short but informative messages that tells us something we can't quickly figure out from the diff.

Template for good commit messages

Short (72 chars or less) summary of changes.

More detailed explanatory text, if necessary.  Wrap it to about 72
characters or so. Leave a blank line between the summary and the
detailed explanation.

If needed, further paragraphs can come after:

  - Bullet points are fine.
  - Second bullet point.

Example of a good commit message

Fixed issue 27183: make postcreate and postupdate stop on build errors

This ensures that importing masterdata and sampledata will not
fail because of this past error.

Example of a bad commit message

Fix issue 27183: make the postcreate and postupdate ant tasks stop the build process when errors are found. This is useful to ensure that importing masterdata and sampledata will not fail later on in the process. So changed the "onerror" paramater accordingly. Now that I'm writing, I'd also like to say hello to my friend John Doe.

Changing push password

To change your password to push to, use the hgpasswd utility.

Mercurial for Subversion refugees

Subversion Mercurial
svn co URL hg clone URL

hg update

svn diff hg diff
svn status hg status
svn add file1 file2 hg add file1 file2
svn del file1 file2 hg del file1 file2
svn commit -m "message" hg commit -m "message"

hg push

svn update hg pull -u / hg pull --rebase
svn log hg log
svn log --limit 5 hg log --limit 5
svn diff -c 6445 hg log -r 6455 -p
svn info hg identify

hg paths

svn revert file1 file2 hg revert file1 file2
svn revert -R . hg revert -a

Mailing list

There is mailing list called openbravo-commits. For every push to the Openbravo ERP repository an e-mail is generated and sent to the list showing all the changesets of that push, their authors, dates and diffs.


There is one read only mirror in SourceForge:


How can I store my push/pull login and password?

This information is saved per repository. So edit <hg-clone>/.hg/hgrc of the repository and edit the URL:

If you're using Mercurial 1.3 or later, you can specify the credentials globally in your main hgrc file. As an example, edit $HOME/.hgrc ($HOME\mercurial.ini in Windows) and add the following section:

ob.prefix =
ob.username = myusername
ob.password = mypassword

For more information about this check the hgrc(5) man page.

I'm running hg push -f and it fails! What do I do?

Running this command is forbidden. In fact it intentionally fails with an error similar to:

transaction abort!
rollback completed
abort: pretxncchangegroup.forbid_2heads hook exited with status 1

To fix this situation follow these steps.

How do I add a file to the ignore list, to prevent it from being committed?

If its of general interest edit the <hg-clone>/.hgignore file and add your list of files there. Take into account this file is version controlled as a common file and that it has to be committed. For example to ignore config/

echo config/ >> .hgignore
hg ci -m "Ignore config/"
hg push

This is the equivalent to the svn:ignore property in Subversion.

How do ignore files *only* in my local repository?

You may want do ignore files locally, without having to modify the general .hgignore file. To achieve this, edit <hg-clone>/.hg/hgrc and add:

ignore = /absolute/path/to/repo/.hg/hgignore

And use /absolute/path/to/repo/.hg/hgignore as the local ignore file.

How do I go to revision XY in my working directory?

Use hg update to achieve this. For example to go to revision 2345

hg up -C 2345

How do I create a new repository for testing?

mkdir my-new-repo
cd my-new-repo
hg init
(add some files)
hg addremove
hg commit -m 'Initial commit'

Can I edit the last commit message?

Yes you can, as long as it's not pushed. First, enable the mq extension in your $HOME/.hgrc file. Then:

hg qimport -r tip
hg qrefresh -m "Enter here the new message"
hg qfinish -a


For more information about Mercurial:

Retrieved from ""

This page has been accessed 124,982 times. This page was last modified on 8 June 2012, at 07:48. Content is available under Creative Commons Attribution-ShareAlike 2.5 Spain License.