HowTo use HG (Mercurial) from the point of view of a developer who is used to cvs
- 1 Preface
- 2 What else needs to be done before we can transition to hg?
- 3 Setup
- 4 Checkout / Cloning
- 5 Updating / Pulling everything
- 6 Update individual files to a newer or older revision
- 7 trunk vs stable
- 8 Creating a branch
- 9 Create a named tag for your local, commited snapshot
- 10 Revert a file to its original state
- 11 Check which filenames have been changed
- 12 Create a release tar ball based on a named tag
- 13 Commit / push
- 14 Looking at the list of changes to a file
- 15 Line-by-line blame
- 16 Querying the list of changes inside a directory and in a date range and get a nice web page with results
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.
- NSPR at https://hg.mozilla.org/projects/nspr/ which contains mozilla/nsprpub
- NSS at https://hg.mozilla.org/projects/nss/ which contains:
- we should probably copy over the following, too:
- 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
- no longer needed (because part of Mozilla core, not NSS:
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
[ui] merge = kdiff3 username = Kai Engert <firstname.lastname@example.org> [defaults] diff=-U 8 -p qdiff=-U 8 [diff] git = 1 nodates = 1 showfunc=true [merge-tools] kdiff3.args = $base $local $other -o $output [extensions] 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
|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
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
[paths] default = https://hg.mozilla.org/mozilla-central/
You must add another line like
default-push = ssh://email@example.com@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
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.