From MozillaWiki
Jump to: navigation, search

HowTo use HG (Mercurial) from the point of view of a developer who is used to cvs


At the time of writing these instructions are hypothetical, because there isn't a hg repository for NSS yet. The intention is to document how to use NSS, if a decision were made to switch the master copy of NSS to a hg repository.

This document also assumes that a new master of NSS in hg would receive the full history of changes that were made in cvs.

We should have two separate repositories, one for NSPR, another one for NSS.

  • NSS at https://hg.mozilla.org/projects/nss/ which contains:
    • mozilla/dbm
    • mozilla/security/dbm
    • mozilla/security/coreconf
  • we should probably copy over the following, too:
    • mozilla/security/tinderbox
    • mozilla/security/tinderlight
    • mozilla/security/svrcore
  • we also need a place for the following directories - a decision must be made whether it shall be part of NSS, or whether they get their own repositories
    • mozilla/security/jss
    • mozilla/security/python
  • no longer needed (because part of Mozilla core, not NSS:
    • mozilla/security/manager

For the following I'll use the NSS respository as an example.

What else needs to be done before we can transition to hg?

  • accept that the "guilty" column of tinderbox.mozilla.org will be empty until someone gives us a tinderbox replacement that pulls from hg (Will the new "tinderboxpushlog" accept our old tinderbox emails, or will it require that we use new tools to submit our results, which would require additional work?).
  • change the tinderbox scripts to pull from hg instead from cvs, reconfigure all existing build/test slaves
  • accept that we can no longer use bonsai, but must use the HG webtools


use commands to login, saved in $HOME/.cvspass

Edit file $HOME/.hgrc with your preferences and enabled extensions (hg plugins), for example mine is

 merge = kdiff3
 username = Kai Engert <kaie@kuix.de>
 diff=-U 8 -p
 qdiff=-U 8
 git = 1
 nodates = 1
 kdiff3.args = $base $local $other -o $output
 hgext.mq =
 rebase = 

Checkout / Cloning

cvs checkout NSS HG: hg clone https://hg.mozilla.org/projects/nss/ name-for-directory-that-contains-your-local-tree

Updating / Pulling everything

cvs update hg pull -u

Update individual files to a newer or older revision


cvs update -r otherrevision path/file

hg revert -r <otherrevision> path/file

If the old file was in a different directory (prior to a directory reorganization), then it must be done in two steps:

hg revert -r <otherrevision> old/path/file

cp old/path/file new/path/file

trunk vs stable

cvs checkout -r NAME_OF_BRANCH NSS

I think we would distinguish between lightweight branches for minor releases, and release repositories for each new major version. This would allow the NSS team to avoid dealing with the term branch most of the time. In other words, NSS trunk development would happen on https://hg.mozilla.org/projects/nss/ We would request a release repository (work done by Mozilla rel-eng?) each time we start a new major version, e.g.:

For each of the above https:// URLs you can use its own separate local directory, and you usually don't need to worry about branches.

If necessary, we can create named branches inside a respository, but most of the time it won't be necessary. We can simply create a minor release tag inside a repository and continue work on the main branch. The main branch inside a repository is named "default".

Creating a branch

I don't think it's necessary, if interested read "hg help branch".

Create a named tag for your local, commited snapshot

cvs tag NAME_OF_TAG list-of-files... hg tag NAME_OF_TAG

Revert a file to its original state

If you want to throw away your local changes in a file, delete it, then use "cvs update", and you'll get the most version of the file from cvs (which might be a newer version than what you had earlier) use "hg revert filename", and you'll receive the original base file contents, from the base revision you are currently working with. (You might have to remove a backup copy with an .orig extension afterwards.)

Check which filenames have been changed

You probably must run a full diff "mozcvs -q diff" "hg status" produces a simple list of all filenames you have touched (or are unknown to hg)

Create a release tar ball based on a named tag

For example, we have tag RELEASE_123, and we want all files to be inside a directory named release-123, and create a tar.gz archive

Must be done manually by a series of commands like "mkdir release-123", "cd release-123", "cvs export NSS", "cd ..", "tar -czf release-123.tar.gz" hg archive -t tgz -p release-123 -r RELEASE_123 ../release-123.tar.gz

Commit / push

cvs commit

Each locally cloned tree must be prepared once before you can commit, by editing the file .hg/hgrc inside that directory. The file will already contain

default = https://hg.mozilla.org/mozilla-central/

You must add another line like

default-push = ssh://kaie@kuix.de@hg.mozilla.org/mozilla-central/

Each time you commit, you must remember to do both commit and push, because HG allows you to commit many changes locally, and only push them afterwards.

If other people have commited and pushed since you updated your tree, you'll have to clean that up. There are easy instructions how to do that on Mozilla's Mercurial FAQ page. But using the following instructions for commit, it's unlikely to run into this scenario, given only few developers commit to NSS.

My suggestion is, never use "hg commit" directly, but instead run the combination of the following two commands:

 hg incoming || hg commit

This effectively means, "check whether anyone else has done changes in the meantime, if yes, then don't commit, if no, then go ahead and commit." If that aborted, simply update your local tree (hg pull -u), and hg will automatically merge in the remote updates, and then repeat your "incoming/commit", and you'll succeed.

I use a script named hgcommit.sh with the following contents:

 hg incoming || hg commit "$@"

Once that succeeds, immediately run "hg push", in order to minimize the risk of collisions.

(If you really ever run into a collision with NSPR/NSS, then follow the steps explained in the FAQ. Either a "merge commit" (which will create a noise entry in the changelog so many prefer to avoid it) or using the rebase extension or using a series of steps using the patch-queue extension (cannot remember, must follow the steps from wiki page).

Looking at the list of changes to a file

Either "hg log file | less" or e.g. https://hg.mozilla.org/mozilla-central/filelog/default/security/manager/ssl/src/nsKeygenHandler.h

Line-by-line blame

Either "hg annotate file | less" or e.g. https://hg.mozilla.org/mozilla-central/annotate/default/security/manager/ssl/src/nsKeygenHandler.h

Querying the list of changes inside a directory and in a date range and get a nice web page with results

use Bonsai and enter the directory and date range I only know of "hg log directory", which also takes a date parameter (does it accept a range?), but I don't know of a web tool. Edit: http://hg.mozilla.org/mozilla-central/pushloghtml?startdate=2012-04-21&enddate=2012-04-24 is an example of hgweb showing a date range in mozilla-central.