Skip to main content

Mercurial Path Pattern Extension

Project description

Don’t repeat yourself defining [paths] over many repositories, specify the general rule once in ~/.hgrc.

Path Pattern is a Mercurial extension used to define default remote path aliases. You may find it helpful if you maintain consistently layed out repository trees on a few machines.

It also provides shortcut hg cloneto «path-alias» (clone to remote address specified by short name).

Using path patterns

Install the extension as described below.

Write in your ~/.hgrc:

mercurial_path_pattern =

lagrange.local = ~/devel/{repo}
lagrange.remote =  ssh://{repo}
bbssh.local = ~/devel/public/{below}
bbssh.remote = ssh://{below:/=-}

Imagine ~/devel/personal/blog/drafts and ~/devel/public/pymods/acme are both some mercurial repositories. Then:

cd ~/devel/personal/blog/drafts
hg push lagrange
# Works, pushes to ssh://

cd ~/devel/public/pymods/acme
hg pull lagrange
# Works, pulls from ssh://
hg pull bbssh
# Works too, pulls from ssh://

This works in spite of the fact, that those repos lack .hg/hgrc.

For two repositories that’s not very useful, but once you have hundred of them, managing individual .hg/hgrc becomes a hassle (imagine changing to everywhere, or maybe adding second remote alias for the new development machine).

By default path patterns have lower priority than per-repository paths, so in case you define lagrange path on repository level, it won’t be overwritten by pattern. You can augment it by adding .enforce:

lagrange.local = ~/devel/{repo}
lagrange.remote =  ssh://{repo}
lagrange.enforce = true

With such config pattern wins against any path from .hg/hgrc (usually it is not recommended but can be handy if you have some broken paths scattered around repositories).

To (re)use the same alias in a few different locations, use .alias:

production.local = ~/devel/{repo}
production.remote = ssh://{repo}
experiment.local = ~/experiments/{repo}
experiment.remote = ssh://{repo}
experiment.alias = production

Definitions above let you hg push production not only in ~/devel/website/blog but also in ~/experiments/website/qagame. Whether this is a good idea, is up to you.

You can define default via path pattern if you wish:

default_hobby.local = ~/hobby/{repo}
default_hobby.remote =  ssh://{below:/=-}
default_hobby.alias = default
default_wrk.local = ~/work/{what}
default_wrk.remote =  https://tim@devel-department.local/{what}
default_wrk.alias = default

(here in ~/hobby I push to bitbucket by default, but in ~/work to department server).

Path Pattern mostly works behind the courtains, making standard commands like hg pull, hg push, and hg incoming aware of extra paths. Still, it implements some commands described below.

Using cloneto

The cloneto command makes it easier to clone repository to remote url:

hg cloneto lagrange
# Equivalent to
#   hg clone . ssh://
# but noticeably shorter

which works both for normal paths and paths derived from patterns, but is especially handy with patterns. In particular, it makes it possible to push newly created repository, for example:

cd ~/devel/libs
hg init xyz
cd xyz
hg cloneto lagrange
# Works, creates soures/libs/xyz on

Instead of clonefrom

There is no clonefrom command (at least for now), but it is not really needed. The following works (imagine libs/zzz exists on, but is not yet cloned here):

cd ~/devel/libs
hg init zzz
cd zzz
hg pull lagrange

Testing pattern configuration

The standard:

hg paths

command lists paths defined for current repository, after pattern expansion. Use it (in a few different repositories) to verify whether your patterns generate proper paths.


hg list_path_patterns

command prints all patterns found in configuration. Use it to detect typos causing some patterns to be ignored and to check the final result of configuration processing.

Pattern syntax

Patterns are defined in [path_pattern] section of mercurial configuration file (typically they are kept in ~/.hgrc, but feel free to define them system-wide).

You may have as many patterns as you like. Example:

lagrange.local = ~/devel/{repo}
lagrange.remote =  ssh://{repo}
euler.local = ~/devel/{repo}
euler.remote =  ssh://{repo:/=.}/hg
wrk.local = ~/work/{what}
wrk.remote =  https://tim@devel-department.local/{what:/=__:\=__}
ugly.local = ~/(topic)/sources/{subpath}/repo
ugly.remote = ssh://hg{topic}@devel.local/{topic}/{subpath}
cfg.local = ~/.config/upstart
cfg.remote = ssh://
cfg2.local = ~/.local/share/applications
cfg2.remote = ssh://
cfg2.alias = cfg

Every pattern is defined by the pair of keys - «alias».local and «alias».remote - or, less frequently, by set of three keys «prefix».local, «prefix».remote, and «prefix».alias (where «prefix» is anything unique).

While processing patterns, the extension matches current repository root path against local pattern, and if it matches, extracts parts marked with markers and fills remote part with them to calculate proper path to use.

The .local part should specify absolute repository path (~ and ~user are allowed). Some part(s) of the path may be replaced with {brace} or (paren) markers:

  • {brace} matches everything aggressively (to the very end, unless some fixed text follows it),

  • (paren) is limited to single path item and does not cross / or \\ characters).

Those parts will be extracted from local repository path and available for use in remote path being defined.

Markers are optional, if no marker is used (see cfg above), rule applies to exactly one repository. This may make sense (over defining path in given repo .hg/hgrc) if you prefer to centralize your paths.

The .remote part defines appropriate remote address. This is typical Mercurial remote path, but {marker}’s can be used to refer to values extracted from local path: {sth} is replaced with whatever matched {sth} or (sth) present in local path.

Simple modifications are supported – {sth:x=y} means take whatever was extracted as sth and replace any x with y. This is mostly used to replace / with some other character (in particular {below:/=-} handles BitBucket convention, replacing slashes with minuses).

Replacements can be chained if necessary – {sth:x=y,v=z} means take whatever was extracted as sth, replace any x with y, then replace any v with z, then use the final result.

For example, with definitions above, if you happen to work in repository ~/devel/python/libs/webby, the extension will:

  1. Find that lagrange.local matches and that {repo} is python/libs/webby. Filling lagrange.remote with that value generates ssh://, so finally it will create path alias lagrange=ssh://

  2. Discover that euler.local also matches, and {repo} is again python/libs/webby. After replacing /-s with .-s, that brings alias euler=ssh://

  3. Ignore remaining patterns as they do not match.

If .alias is defined, value of this item serves as path alias. Otherwise pattern prefix is used as alias. So, with definitions above:

  1. You may issue hg pull lagrange or hg push euler in ~/devel/snippets/js.

  2. You may issue hg push cfg in both ~/.config/upstart and ~/.local/share/applications (in the latter thanks to .alias).


Linux/Unix (from PyPI)

If you have working pip or easy_install:

pip install --user mercurial_path_pattern

or maybe:

sudo pip install mercurial_path_pattern

(or use easy_install instead of pip). Then activate by:

mercurial_path_pattern =

To upgrade, repeat the same command with --upgrade option, for example:

pip install --user --upgrade mercurial_path_pattern

Linux/Unix (from source)

If you don’t have pip, or wish to follow development more closely:

  • clone both this repository and mercurial_extension_utils and put them in the same directory, for example:

    cd ~/sources
    hg clone
    hg clone
  • update to newest tags,

  • activate by:

    mercurial_path_pattern = ~/sources/mercurial-path_pattern/

To upgrade, pull and update.

Note that directory names matter. See mercurial_extension_utils for longer description of this kind of installation.


If you have any Python installed, you may install with pip:

pip install mercurial_path_pattern

Still, as Mercurial (whether taken from TortoiseHg, or own package) uses it’s own bundled Python, you must activate by specifying the path:

mercurial_path_pattern = C:/Python27/Lib/site-packages/
;; Or wherever pip installed it

To upgrade to new version:

pip --upgrade mercurial_path_pattern

If you don’t have any Python, clone repositories:

cd c:\hgplugins
hg clone
hg clone

update to tagged versions and activate by path:

mercurial_path_pattern = C:/hgplugins/mercurial-path_pattern/
;; Or wherever you cloned

See mercurial_extension_utils documentation for more details on Windows installation.



Development, bug reports, enhancement suggestions

Development is tracked on BitBucket, see

Use BitBucket issue tracker for bug reports and enhancement suggestions.

Additional notes

Information about this extension is also available on Mercurial Wiki:

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mercurial_path_pattern-1.0.0.tar.gz (11.6 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page