HgTrainingMaterials

NetBeans + Mercurial Training


Contents



What is Mercurial?

  • One of three popular distributed version control systems (DVCS)
  • Git and Bzr are the other widely used choices
  • Also known as Hg (hydrargyrum or mercury)
  • Hosted on selenic.com/mercurial
  • Initially written by Matt Mackall at Selenic Consulting
  • Vigorous open-source community (under GPL)
  • Several patches per day posted, reviewed, sometimes accepted

What does it do?

  • Manages changes to a file tree called a repository
  • Allows you to record and examine changes to files
  • Manages interaction with other developers when you are ready
  • Superficial feel similar to CVS
  • Underlying model closer to TeamWare

Basic UI

  • Basic command structure similar to CVS; one executable: hg
  • a few global options, lots of options on subcommands, abbreviations
  • hg -R nb_all loc -f \*.java
  • hg --repository=nb_all locate --fullpath \*.java
  • Command defaults and lots of other options can be configured
  • Interactive help: hg help, hg help locate

Distributed development

  • Each repository is self-contained: history in .hg subdir
  • fully offline operation possible
  • You can clone a remote repository to work on it locally
  • or clone a local repository to make a temporary work area
  • You can pull changes from a source you trust
  • You can push changes to a destination that trusts you
  • Changes made in parallel can be merged and thus resolved
  • Branches can be isolated physically
  • each repository is effectively a branch in Hg!

Terminology (1 / 2)

  • Working directory (or checkout) has your editable files
  • a repository may also have no checkout, just .hg
  • Revision is a snapshot of the source tree
  • no special labels for revisions of individual files
  • SHA-1 hashes identify revisions uniquely and globally
  • 40 hex digits, but usually abbreviated to 12
  • Sequence numbers can be used as shortcuts inside a single clone only
  • a tag is just a label for a revision

Terminology (2 / 2)

  • Changeset is the difference from a parent revision to a child
  • a patch or diff could be applied to many similar parents
  • a head is a revision with no children
  • tip is the changeset last saved in local history (always a head)
  • a merge revision has two parents (more later...)
  • its merge ancestor is the closest common ancestor of both parents

Typical history with merges (hg glog excerpt)

o    changeset:   63829:97db7e2e1dc8
|\   parent:      63827:5df9cf7e1ae8
| |  parent:      63828:9def4e8126ee
| |  user:        Jesse Glick <jglick@netbeans.org>
| |  date:        Tue Jan 15 14:47:33 2008 -0500
| |  summary:     Automated merge with http://hg.netbeans.org/main/
| |
| o  changeset:   63828:9def4e8126ee
| |  parent:      63826:67b7cf411f30
| |  user:        Michal Zlamal <mzlamal@netbeans.org>
| |  date:        Tue Jan 15 18:27:34 2008 +0100
| |  summary:     Production build changes
| |
o |  changeset:   63827:5df9cf7e1ae8
|/   user:        Jesse Glick <jglick@netbeans.org>
|    date:        Tue Jan 15 10:19:41 2008 -0500
|    summary:     Top-level build.xml for convenience.
|
o  changeset:   63826:67b7cf411f30
[Etc...]

Architecture and extensions

  • Hg is almost all Python
  • a little C for bottlenecks and OS services
  • Core is small, many features added in extensions
  • extensions usually add commands but can do other things too
  • registered in some hgrc
  • several useful extensions bundled with Hg
  • Custom hooks can be run before or after commands
  • can be external scripts, or in-process Python for more power
  • example: check that your code compiles before commit

Why is NB using Hg?

  • CVS is awful
  • making a branch of NB sources can take all day
  • Subversion is better, but
  • rather bloated and complex
  • still lacks merge tracking, a basic VCS function
  • OpenJDK, OpenSolaris, soon Glassfish will all use Hg
  • we can share expertise, maybe infrastructure

Key Hg advantages

  • small: 37 kLOC (incl. web view!) plus docs and tests
  • extensible (and extensions are very easy to write)
  • fast: disk access carefully optimized, cheap local clones
  • decentralized: offline operations, simplified permissions
  • straightforward UI, clear documentation
  • actively maintained and developed, portable

Current Hg limitations

  • Young system (Apr 2005)
  • future relative to Git and Bzr still uncertain
  • Cannot clone just a subdirectory of a repo
  • Cannot clone just the last year of a repo's history
  • Some annoyances on Windows (long paths, case sensitivity)
  • Massive renames will make the repo larger


Getting your feet wet

Everyday tasks you will perform with Mercurial.

Installing Hg

  • See selenic.com/mercurial for downloads
  • Windows users: use all-in-one installer
  • you probably want to configure CRLF newline translation
  • Mac users: use an installer (for 10.4 or 10.5)
  • Linux users: Ubuntu package, Fedora package, ...
  • inotify extension speeds up many operations, but still buggy
  • Building from sources
  • generally easy, just need Python and a C compiler
  • Configure your username!

Typical per-user configuration

Basic configuration (~/.hgrc):

[Ui]
username = John Q. Hacker <jhacker@netbeans.org>
[Extensions]
fetch =

Extra Windows configuration (...\Mercurial.ini):

[Extensions]
win32text =
[Encode]
{}** = cleverencode:
[Decode]
{}** = cleverdecode:

Typical repository configuration

..../main/.hg/hgrc:

[Paths]
default = http://hg.netbeans.org/main/
default-push = https://jhacker:secretpass@hg.netbeans.org/main/
golden = http://hg.netbeans.org/main-golden/
[Defaults]
log = --no-merges
  • default is the default pull location (can also be dir path)
  • default-push is default push location (if different)
  • golden is just a convenient alias for another location
  • hg log run here will implicitly use --no-merges (-M)

NB IDE Integration

  • Now in NB development builds
  • or available from Tools > Plugin Manager for 6.0 release
  • No configuration needed, will autodetect files under Hg repo
  • Diff, commit, push, annotate, etc. from inside IDE
  • Report bugs: use mercurial component in Issuezilla

Cloning main

  • All sources needed for regular NB build are in one repo
  • hg clone http://hg.netbeans.org/main
  • Easy to create a mirror for a local team and clone that
  • Update mirror when you like, or just pull remainder from main
  • Clone also checks out tip unless you use -U

Doing a build

  • Type: ant
  • We can have top-level build.xml, unlike with CVS
  • Should be able to open modules as NB projects as before

Updating sources

  • Update your repository whenever you like
  • hg pull -u
  • (this may say you need to merge... more later)
  • Or look at what would be pulled in
  • hg incoming for summary or hg in -p to see diffs
  • Can use the Fetch extension to make this easier (more later)

Committing some changes

  • See what you have to commit
  • hg stat for a summary
  • hg di for the patch
  • Record the commit
  • hg ci (may specify files, else commits everything)
  • uses your default $EDITOR for the log message
  • first line of a log message should be self-contained summary
  • Push one or more commits when you are ready
  • wise to do a build first; no "rush to commit" like with CVS
  • hg push will stop if you need to pull and merge first

Collaboration: merging

  • If you and someone else have both made changes, you need to merge
  • even if you were not working on the same file(s)
  • hg merge does a 3-way merge (two heads + common ancestor)
  • If there are file-level conflicts, a merge tool will be launched
  • or conflict markers will be left to be resolved in a text editor
  • Commit the result of a merge when you are satisfied with it
  • For safety, Hg records every merge explicitly
  • CVS/SVN do an implicit merge after updating a modified tree
  • If fetch extension enabled, hg fetch does pull, merge, commit
  • do not use with inotify, do not put auth info in push path

Adds, renames, deletes

  • Add a file or whole dir with hg add
  • Delete a file or whole dir with hg rem
  • if all files in a dir are gone, so is the dir
  • Add & delete new/missing files: hg addremove, or hg ci -A
  • one top-level .hgignore replaces per-dir .cvsignore
  • Rename a file or dir: hg ren
  • preserves history, not like CVS! (use --follow later)
  • and renames merge sensibly with modifications
  • Adds/renames/deletes get committed alongside other changes

Browsing history

  • hg log to browse history (of specified files, or all)
  • -v for full log message, -p for patches
  • -l 10 for last ten
  • hg glog (graphlog extension) visualizes branches & merges
  • hg tip shows tip revision, hg heads shows all heads
  • hg di -r start:end to see a patch
  • hg ann file shows which changesets created which lines

Fixing mistakes

  • Normal programming errors ("hey, this is wrong")
  • hg backout reverts last change (tip) as new rev
  • with -m, reverts some earlier change (requires merge)
  • or, just fix somehow and commit
  • Catastrophic mistakes ("did I just commit my ATM PIN?!")
  • hg rollback undoes last operation, such as commit
  • hg strip (mq extension) destroys rev and descendants
  • hg clone -r makes copy without last few changesets
  • none of these will save you if you have already pushed

Working with branches

  • A "branch" is just a repo clone you treat specially
  • hg tag sometag marks a revision with a symbolic name
  • hg clone -r sometag original branch clones up to that point
  • you can pull from or push to any repo whenever you like
  • paths section in .hg/hgrc can define aliases
  • default & default-push used unless you specify location
  • hg transplant -s main rev copies a change from another repo
  • you might need to resolve merge conflicts
  • Hg also has named branches but better not use them for now


hg.netbeans.org

  • Hg bundles the equivalent of ViewCVS / FishEye
  • If you can commit to CVS, you should have a login here too
  • for administrative reasons you may need a new password
  • Until "flag day", these repositories are for testing only
  • all changes will be discarded
  • temporary password for testing: hguser
  • commit notifications still sent to cvs@module.netbeans.org

What are the different repositories?

  • main: modules in standard distro, infra, Stable AU
  • main/contrib: alpha AU modules
  • main/misc: other as-yet-uncategorized content
  • can be moved to main or main/contrib later
  • main-golden: mirror of main that always compiles
  • should always be safe to pull from
  • core-main etc.: team integration areas
  • release61: fake demo of release branch

New file layout

  • Modules were rearranged as part of Hg import
  • currently impractical to do this as Hg changeset
  • Every module now named according to code name base
  • thus at top level, with contrib/* at second level
  • abbreviations: org.netbeans.modules.xml.core -> xml.core
  • Some sources (tests, j2se projects) moved inside modules
  • nbbuild, installer, etc. unchanged
  • complete mapping recorded in nbbuild/translations

Cloning the forest

  • Install Forest extension (see Hg wiki for details)
  • Register extension: forest=..../forest.py
  • hg fclone http://hg.netbeans.org/main this no longer works
  • contrib and misc get cloned as subdirectories
  • e.g. ant init all-contrib/docbook builds DocBook module
  • hg fpull, etc. work on all three repos at once

Things you cannot push

To fix: save patches, strip bad revs, recommit patches, retry push

  • Text files with CRLF newlines
  • please set up CRLF conversion on commit
  • or you can configure local repo to reject CRLF on commit
  • Changesets using a non-@netbeans.org author
  • Merge changesets created by hg fetch with passwords
  • New unmerged heads (just need to merge & retry)
  • Paths too long for Windows to deal with

External binaries

  • To reduce repo size, we may store libraries externally
  • Applies to: */external/*.zip,jar,gz,bz2,gem,dll
  • Custom extension hooks into working copy storage
  • registered in .hg/hgrc by bootstrap Ant target
  • mostly automated already, may be some rough spots still
  • Upon checkout, "decode" hook downloads binary from server
  • Upon add & commit, "encode" hook uploads binary to server
  • Local cache prevents same binary from being downloaded 2x
  • Mostly transparent: operate on binaries using normal Hg commands


Cool Stuff

Hg has some unique capabilities you can explore.

Using a team repository

  • Should be familiar to old TeamWare hands!
  • Set up a clone of main, make sure it is OK
  • Team members clone team repo, pull from it, push to it
  • If the team repo is broken, you know who to blame!
  • When things are stable (clean build & tests), push to main
  • Pull from main-golden whenever you feel comfortable

Working with changesets

  • hg bundle will save 1+ changesets as a compressed binary
  • with --base null, create archive of whole repo
  • hg unbundle to apply to "related" clone
  • hg incoming --bundle to preview contents
  • hg export saves standard patch
  • use --git to track renames, binaries, execute bit
  • hg import loads patch as commit
  • hg transplant applies a changeset to another repo
  • hg mail sends changesets by mail, e.g. for review

Investigating bugs

  • hg grep says when in history some text was added to any file
  • hg bisect lets you narrow down a regression
  • set up a reliable unit test
  • identify a "last known good" revision
  • start it running and go to lunch!

Advanced repository browsing

  • Commands like log take templates
  • can include various fields, e.g. full SHA-1 hash
  • powerful formatting options (fill para, ...)
  • save valuable templates as styles
  • hg locate enumerates files by pattern (quickly!)
  • to do more: hg locate -0 ... | xargs -0 ...
  • hg log -k to look for author or log message keyword
  • hg log -k GPL --template '{rev}\t{desc|fill68|tabindent}\n'

Using MQ

  • Mercurial Queues extension: manage and develop patches
  • useful if you are not ready to commit a variety of changes
  • or for non-committers who can only submit patches in IZ
  • qnew to begin work on a new patch, added to a stack
  • qpush / qpop to select "active" patch in stack
  • qdiff to review or save the current patch
  • qrefresh to update current patch with working changes
  • hg mail qtip to send a proposed patch to someone
  • Not trivial to use, but very powerful!


Resources

Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo