Edgewall Software

Version 72 (modified by Boris Kocherov <bkocherov@…>, 14 years ago) ( diff )

mercurial: change milestone in Ticked Query

Mercurial Plugin for Trac (#1847)

This a plugin for Trac which enables Mercurial to be used instead of Subversion as the VersioningSystemBackend for Trac.

The plugin has been marked as experimental for a while, but even if there are still some rough edges here and there, it's gotten quite usable.

Please take care to use a recent version of the plugin before reporting issues. See the version table below.

Detailed Change Logs:

Download and Installation

Trac

Trac 0.10

The plugin plugins/0.10/mercurial-plugin works fine with Trac 0.10.3, though it will lack the "quickjump" to a branch or tag feature (this was implemented in source:sandbox/vc-refactoring, but is only available in the mainline for 0.11).

See TracDownload and install Trac the usual way (see TracInstall)

The plugin itself is available from source:plugins/0.10/mercurial-plugin

Check it out:

svn co http://svn.edgewall.com/repos/trac/plugins/0.10/mercurial-plugin 

and create an "egg" from there

$ cd mercurial-plugin
$ python setup.py bdist_egg

Note that this version of the plugin is not actively maintained anymore, but as the same can be said for Trac 0.10.x itself, better upgrade anyway.

Trac 0.11

That version of the Mercurial plugin also supports of the new features added in 0.11 to the TracBrowser:

Installation of the plugin:

svn co http://svn.edgewall.org/repos/trac/plugins/0.11/mercurial-plugin

create an "egg" from there:

$ cd mercurial-plugin
$ python setup.py bdist_egg

$ easy_install dist/TracMercurial-0.11.0.[x]-py2.[x].egg

Note that you'll need setuptools ≥ 0.6 for that (I used setuptools-0.6a9).

Trac 0.12

The latest version of the plugin is at plugins/0.12/mercurial-plugin.

This was merged from plugins/multirepos/mercurial-plugin as part of the MultipleRepositorySupport branch.

Installation of the plugin:

svn co http://svn.edgewall.com/repos/trac/plugins/0.12/mercurial-plugin

create an "egg" from there:

$ cd mercurial-plugin
$ python setup.py bdist_egg

Releases and compatibility matrix

Version mercurial-plugin Trac Compatible with hg
0.12.0.21 plugins/0.12/mercurial-plugin@9133 trunk@9125 and up 1.1.x, 1.2.x, 1.3.x, 1.4, 1.5
0.12.0.9 plugins/multirepos/mercurial-plugin@8692 sandbox/multirepos@8677 and up 1.1.x, 1.2.x, 1.3.x, 1.4, tip?
0.12.0.8 plugins/multirepos/mercurial-plugin@8659 sandbox/multirepos@8652-8676 1.1.x, 1.2.x, 1.3.x
0.11.0.8 plugins/0.11/mercurial-plugin@8646 0.11 or branches/0.11-stable 1.0.x, 1.1.x, 1.2.x, 1.3.x, 1.4, tip
0.12.0.5 plugins/0.12/mercurial-plugin@7443 sandbox/multirepos (possibly trunk as well) 1.0.x, 1.1.x
0.11.0.6 plugins/0.11/mercurial-plugin@7442 0.11 or branches/0.11-stable 0.9.x (?), 1.0.x, 1.1.x
0.11.0.4 plugins/0.11/mercurial-plugin@7243 0.11 or branches/0.11-stable 0.9.x, 1.0.x
0.10.0.3 plugins/0.10/mercurial-plugin@7951 (0.10) 0.10 0.7, 0.8, 0.9, 1.0.x, 1.1.x, 1.2
0.10.0.2 plugins/0.10/mercurial-plugin@4467 (0.10) 0.10 0.7, 0.8, 0.9
0.2 r3014 trunk@2900 0.7, 0.8
0.2 r2905 r2905 0.7, 0.8
r2620 r2620 0.7 with 1d7d0c07
0.1 r2514 r2511 0.7 without 1d7d0c07

General Notes:

  • It is quite likely that some 0.9.x versions (maybe even 0.9.5) won't work anymore with the 0.11 and 0.12 versions of the plugin (i.e. those are the versions actively maintained). Most notably, since r7742 the filectx API is used, which means that versions anterior to hg:482c524dd9ab can't possibly work. Anyway, at this time you should not be using a pre-1.0 version of Mercurial anymore.
  • the 0.12 version works as well as the 0.11 one, but requires the source:sandbox/multirepos (i.e. doesn't work with source:trunk)
  • the original branch (plugins/0.10/mercurial-plugin) which is only for Trac 0.10 is not actively maintained anymore (patches still accepted if you happen to fix a bug, of course)
  • 0.9.1 was reported not to work with the 0.11 version of the plugin
  • 0.9.4 (and probably quite a few intermediate changesets between 0.9.3 and 0.9.4) interferes badly with the TH:AccountManager plugin when using Python 2.3.5.

It's not unlikely that other setups can be affected by the problem, as basically any code that relies on trapping the ImportError, after the mercurial.demandimport mechanism has been activated, will fail.

If you happen to have this problem (TypeError: 'unloaded module' object is not callable}, you need at least r5766/r5767. See also issue605.

Mercurial

The plugin has been tested with recent development versions of Mercurial (upto Changeset 3324:34f08b8883cf from http://selenic.com/hg) and also with Mercurial 0.7 and 0.8. It won't work with earlier versions, in particular not with 0.6x.

The plugin for 0.11 takes benefit of some new features introduced after the 0.8.2 release of Mercurial, and therefore needs at least a 0.9 version of Mercurial.

Note: as mentioned here http://groups.google.com/group/trac-users/browse_thread/thread/9b1cd95621c19921/9f829e8acd958a8e It *does* require mercurial-0.9.5. Mercurial 0.9.3 is confirmed to not work with plugin 0.11.

You can download Mercurial itself from Hg:Download.

On Windows, it looks like it's possible to re-use the Mercurial library coming from the installer, see this mail (though to my knowledge, it is not possible to achieve this using PYTHONPATH and PATH: it fails with ImportError: No module named handlers due to library.zip coming in the sys.path before the standard library).

Note! Mercurial's library.zip contains pyd-files, which normal python import can't use (py2exe uses a special importer that allows that), but if you unzip library.zip somewhere and add that directory, it will work on Windows (tested with tracd).

Alternatively you can install the pre-built Mercurial Python modules from http://bitbucket.org/tortoisehg/thg-winbuild/downloads/

Configuration

The configuration has to be done on the Trac side, there's nothing to do on the Mercurial repository side, except for the fact that the repository should be made accessible as a local repository. Thanks to the distributed nature of Mercurial, that's always possible (if the repository is not already local, simply hg clone it).

Setting up the mercurial plugin

The TracMercurial plugin egg should be added to the plugins folder of the environment, or it can be globally installed (python setup.py install or a python setup.py develop).

For general instructions about plugins, see also TracPlugins.

If you installed the egg globally and you're modifying an existing Trac environment to use the Mercurial backend, then you have to explicitly enable the plugin in TracIni.

For the 0.10 plugin, this is done like that:

[components]
tracvc.hg.* = enabled

Since the 0.11 of the plugin, the package has been renamed to tracext:

[components]
tracext.hg.* = enabled

Setting up a Trac environment

You can either reuse an existing Trac environment, or create a brand new one.

For general instructions, see TracInstall.

Since 0.10, the TracAdmin initenv command has now a repository type argument besides repository directory.

For the repository type, specify hg instead of the default svn. For the repository directory, specify the location of the Mercurial repository (without the ending .hg).

Your <trac_environment>/conf/trac.ini configuration file should have a [trac] section similar to the following:

[trac]
repository_type = hg
repository_dir = /path/to/my/hg/repository

There's also a few Mercurial specific settings in TracIni:

[hg]
# -- Show revision number in addition to the changeset hash
show_rev = yes

# -- Changeset hash format
node_format = short
# hex:   Show the full SHA1 hash 
# short: Show a shortened hash for the changesets 

Features

The Mercurial support is pretty basic, but works well. I've tested that on the Mercurial repository itself and the performance is acceptable, even if there's currently no caching in the database (this is what I'm going to work on next). Don't even think about using the plugin on a Linux-kernel-sized Mercurial repository, you'll probably burn your disk and/or CPUs ;)

For those used to Subversion in general and Subversion repository browsing in Trac in particular, there are a few differences worth noting.

Mercurial Changesets

Changeset Navigation

In Mercurial, the Previous Changeset/Next Changeset navigation is not purely sequential, as it is in Subversion. Instead of a flat history of successive changesets, we actually navigate a DAG of changesets. This means a changeset can have multiple parents (0, 1 or 2) and multiple children as well (0 to n).

Therefore, Previous Changeset is a link to the first parent, and Next Changeset is a link to the first child. In case there are additional parents or children, these are shown as additional changeset properties (Parents or Children), placed below the Author property and above the Message property.

Changeset view, showing multiple parents. Note that the diffs are providing against each parent.

Another additional changeset property is the list of Tags that might be associated with a changeset.

Wiki syntax

The Wiki syntax has been extended a bit, to cope with the hexadecimal notation of hg changesets. E.g [8ef2] would link to the changeset 8ef2ba892518c115170398ec754bd1c27cab271f … Plain changeset numbers are also recognized, provided they are long enough (12 to 40). Also, it is possible to refer to changesets using the changeset: prefix (or cset: or chgset:, for hgweb compatibility). The tag: prefix can be used to refer to symbolic tags, although this is not a requirement (using. e.g. cset:tip would work too). Finally, the branch: prefix has a special meaning, as this will not select the specified revision, but the head which is reachable from that revision.

TracBrowser changes in 0.11

The TracBrowser View revision form has been extended with pulldown menus for jumping to a given tag or branch (in Mercurial, a branch within a repository corresponds to a head, i.e. a changeset without children):


Browser view, showing the pulldown menu of tags


There's also support for visual blame annotations:


Screen shot of the annotate / blame feature of Trac 0.11, on the .hgtags file of the Mercurial repository

Mercurial Queue

Since r6443, the MQ extension is supported. If you happen to have applied mq patches in your repository, Trac will show the corresponding patch names as Tags: in the changeset view.

Also, with the 0.12 branch of the plugin (and the MultipleRepositorySupport branch of Trac), you can browse jointly the main repository and the repository for the associated Mercurial queue, if any (i.e. if you versioned your patch queue using hg qinit -c and hg qcommit). Furthermore, if you declare such a mercurial repository to be a MQ repository, then all the patches will be correctly rendered as patches, regardless of the patch name (see r6462 for details).

Bugs and Limitations

There are still a lot of things that can be improved.

Features that Trac+svn has but not currently implemented for Trac+hg

  • History doesn't follow copy/move operations implemented in r8445
    Works for files only, which is OK I think, as Mercurial has no notion of directories and detecting copy/move of directories would be pretty hard to implement
  • No path history mode (i.e. show all create/delete operations that affected a given path)
  • Revision log ranges [xxx:yyy]
  • View arbitrary diffs implemented in r6053

Multi-repository support

First and foremost, even if Mercurial allows intra-repository branching, it strongly supports the use of branching by cloning the full repository. Therefore, it is common to have a lot of hg repositories around, each devoted to the implementation of some particular feature.

Trac should support this by the way of multiple repository support within a single environment (see #2086).

New: This is now implemented. Use the 0.12 version of the plugin and the MultipleRepositorySupport.

To cache or not to cache?

Recent versions of the plugin (r7744 for 0.11 or r7757 for 0.12) have a greatly improved browsing speed. It's now possible to navigate on repositories of the size of the Linux kernel repo.

However, producing diffs or even gathering the timeline events for repositories of such size is still too slow. For the diffs, we could reduce the amount diffs generated (see #2591, #7975). For the timeline, we should really have a cache, not only for the performance issue but also because the current heuristic for retrieving the changesets in a given period of time doesn't always work (see r5365).

Cool Features

Wild ideas section…

Visualize branches and merges

There should be a way to show graphically the branch and merge points within the revision log view. Not something as fancy as hgk, but nonetheless something that will make the changeset relationships immediately obvious.

There's an existing web implementation by Alexander Schremmer:

http://moin.pocoo.org:8080/ (select a repo and then 'branchview' button on the top to see it in action)

Also, there is RevtreePlugin.

Search over the source

A search provider could do the equivalent of an hg grep.

Highlight Conflict Resolution

While visualizing changeset diffs for merge changesets, we already show the changes relative to both parents, which helps to understand how conflicts (if any) were solved. But this can be improved by specifically highlighting lines that differs from both parents.

Repository Management

Trac should allow for creating new repositories or clones of existing repositories. Maybe repository deletion and renaming should be supported, too.

HG Forest Support

Support for the Forest extension for Mercurial. Forest extension allows operations on trees with nested Mercurial repositories, called forests. Those to some degree correspond to multi-project CVS/Svn/… repositories.

Already got most of it working, expect that it's pretty much hacked in the Trac 0.10.3 version of the mercurial plugin. Since it needs a bit more flexibile templating (in regards with the lookup/url's) this is hacked around node.path at the moment. Some (small/large?) issues remain but most of it is working.

Note that with the MultipleRepositorySupport branch of Trac, it should be possible to implement an IRepositoryProvider component knowing about the forest extension and adding besides the repository for the forest itself, the managed repositories as well.

Add your cool feature here…

Troubleshooting

"unsupported version control system hg"

If you get this message try the following two basic checks first:

  • From a Python console session try to import the Mercurial module, if all goes well it should not complain:
    $ python
    >>> import mercurial
    >>>
    
  • Log in as an user with TRAC_ADMIN permission, and look in the Admin pages, General / Plugins. Do you see the entry for the TracMercurial plugin there? If yes, is the MercurialConnector component enabled?

Known Issues

#8068
Mercurial bundle attachments should be viewable in readable representation.
#8417
CachedRepository support in TracMercurial
#9704
Support for subrepositories mercurial extension
#9852
Mercurial plugin support for pulling repository description from hgrc
#10411
Enhancing TracMercurial plugin to use new server-command protocol
#10719
Abort: cannot follow file not in parent revision: "tracext/hg/backend.py"
#10950
[hg] encoding setting is not used for files in hg
#11044
Include Mercurial support in Trac distribution
#13050
Quickjump dropdown overflows due to Mercurial tags
#13092
Unified diff of changeset sometimes include wrong changes?
#13318
Changeset with new file links to a different revision

Implementation Notes

I'm interested in feedback concerning the code, in particular concerning Mercurial. I'm pretty sure I did things in a sub-optimal way, as I was discovering the guts of hg while writing the plugin. Therefore, I'll be pleased to get tips for improvements.

ChristianBoos

Attachments (4)

Download all attachments as: .zip

Note: See TracWiki for help on using the wiki.