Mercurial tips

This is a collection of various tips and tricks for improving your Mercurial experience.

Configuration

These settings normally go into ~/.config/hg/hgrc or ~/.hgrc.

This command opens your config file in an editor:

hg config --edit

User interface

Mercurial ships with very conservative defaults. The ui.tweakdefaults option, as the name implies, tweaks the defaults for various other settings.

This results in a much more modern experience, but things may change behaviour between versions.

[ui]
tweakdefaults = True

See hg help ui.config and search for tweakdefaults for more information.

Colors

Phase colors

The “phases” concept in Mercurial is a great way to keep track of works-in-progress contra published changes, but the default colors don’t show the phase.

[color]
changeset.public = green
changeset.secret = red

Warnings

ui.warning = yellow

Appropriate warning color. Errors are already red by default.

Annotate

[annotate]
ignorews = True

Ignore white space in hg annotate.

Update

[commands]
update.check = noconflict

This makes hg update abort if there is potential for a merge conflict. This way you can mentally prepare for dealing with it instead of suddenly dropping unprepared into vimdiff.

Note: This is currently enabled by ui.tweakdefaults.

Includes

The configuration format supports includes, so snippets can be split into multiple files if you prefer organizing like that.

%include ~/.config/hg/hgrc.d/*.rc

Misc

Non-publishing

[phases]
publish = False

Setting this in your local hgrc prevents marking changes as published when pushed between local repositories.

Path sub-options

[paths]
default = https://hg.example.org/project/
default:pushurl = ssh://hg@hg.example.org/project/
default:pushrev = .

A ssh :pushurl is useful when the repo is read-only via https, or is otherwise different.

Setting :pushrev is equivalent to hg push -r REV, with . being the currently checked out revision.

Automatic commit message prefix

This inserts the common directory path as prefix when starting a commit editor:

[committemplate]
changeset = {ifeq(desc, "", "{commondir(files)}: ", "{desc}")}\n\n\n{changeset_trailer}\n{diff()}

Extensions

Viewing changes in alternate ways

The extdiff extension is handy for showing changes in various alternate ways.

[alias]
meld = extdiff -p meld
vimdiff = extdiff -p vimdiff

[extensions]
extdiff =

This allows e.g. hg meld -c . to show the currently checked out changeset.

Code formatting

The fix extension provides a handy command for applying filters to code, such as code formatters or simply trimming trailing whitespace. It can operate on both uncommitted changes and draft commits, amending them in place.

[fix]
# Trim trailing whitespace (only) on changed lines
trailing-whitespace:command = sed
trailing-whitespace:linerange = -e '{first},{last}s/\s\+$//'
trailing-whitespace:pattern = set:not binary()

# Normalize XML
xmllint:command = xmllint --nsclean --encode UTF-8 --format -
xmllint:pattern = set:**.xml + **.svg

[extensions]
fix =

Then you can run it like hg fix -w thisfile.ext to apply the filters in the working directory, or hg fix -r REV to rewrite commits with filters applied.

Daily use

Revsets are awesome

Revsets is a powerful query language for revisions that Mercurial uses.

Finding tags

Sometimes you find the fix for some bug in revision rev and wonder which release, if any, it was included in.

hg log -r 'first(rev:: and tag())'

What this does is:

  1. rev is the revision we’re interested in.
  2. rev:: is that and every descendant of it.
  3. rev:: and tag() are all tags that descends from rev.
  4. first(rev:: and tag()) is the first tag.

hgweb