Is there any interest in a patchset for mr to manage which repos are being handled?

Adam Spiers vcs-home at
Mon Dec 12 11:28:52 CET 2011

Hi Richard,

On Mon, Dec 12, 2011 at 12:28 AM, Richard Hartmann
<richih.mailinglist at> wrote:
> Hi all,
> the subject line may be a bit convoluted, but it's just what I meant.
> To make a short story somewhat longer, my setup looks like this:
> % cat .mrconfig
> git_gc = git gc "$@"
> jobs = 5
> include = cat /usr/share/mr/vcsh
> include = cat ~/.config/mr/config.d/*
> % ls .config/mr/available.d
> foo bar baz
> % ls -l .config/mr/config.d
> foo -> ../available.d/foo
> bar -> ../available.d/bar
> %
> So I only have foo & bar activated on this machine, baz is not checked
> out. I may not want to have your ssh config on a semi-trusted machine,
> my mplayer config on a server, etc.
> I would like to handle the local repo set via mr and not by manually
> using ln & rm. Thus, I would like to patch mr to do this, but only if
> there is any interest and if Joey is OK with actually merging them.
> As I know several other people are using my directory layout, I
> suspect there is some interest, but it's always good to get direct
> feedback.

I've already solved this, but in a different way to what you are
proposing.  I'm using a layout which is superficially similar to
yours; effectively:

    include = cat ~/.config/mr/groups.d/*

(I got the idea to use ~/.config/mr from you.)  However, the
similarity ends there - each included file contains a group of related
repositories, and I'm not using active->available symlinks to activate
them.  I did consider using this approach, but I use mr on about 6
machines, and with ~70 repositories I really didn't like the idea of
having to manually make ~420 decisions about which repositories to
enable on which machines.  So I decided I wanted to automate these
decisions wherever possible by putting as much intelligence as
possible in my mr config.

The solution I came up with was a combination of the following
elements ...

Firstly, I built a library of skip functions:

which lets me write things like:

    skip = default_skipper || missing_exe gpg

The '.sec' suffix indicates that this repository contains
security-sensitive data (my GPG private key).  The default_skipper
notices this, and only allows checkout on machines I consider secure
(i.e. with a known hostname, behind a NAT firewall, and only
physically accessible by me).  The repository is also skipped unless
gpg is installed.

When I don't know in advance whether I'll need a repo on a particular
machine, I use the 'lazy' skipper:

    skip = default_skipper || lazy

However, in the upstream mr, this is not fully implemented yet because
it does not prevent checkouts of lazy repositories:

To solve this, I knew mr would need a mechanism for referring to a
single repository, which in turn would require a new namespace for
repositories.  Your 'available.d' directory effectively provides this
namespace, but at the cost of being forced to split all repository
definitions into separate files *and* keep all those definitions in a
single directory (which by necessity would exclude the repository
containing those definitions).  So I decided on a different approach:

I added support for naming repositories via a special 'name' config
parameter and referring to them via a new --repos option:

and coincidentally I sent a pull request for this yesterday:

Then I patched lazy() so that checkouts only happen when --repos is used:

(No pull request for this yet, because it depends on the first patch.)

The end result is that lazy repositories will always get skipped
unless I specifically ask mr to check them out, e.g.

    mr -r foo checkout

This is effectively equivalent to your proposal:

    mr enable foo

except that it's more direct, since if you enable 'foo', surely you
would checkout 'foo' immediately after.  Then the only missing piece
is 'disable'.  Personally I don't need this (yet, at least).  But if
you really needed it, the lazy() skipper could easily be extended (or
a new skipper written) to perform an extra check:

    test -d .mrdisabled

and then the disable action could be implemented via:

    enable  = rm .mrdisabled
    disable = touch .mrdisabled

Would love to hear your thoughts on all this!

More information about the vcs-home mailing list