The Stochastic Game
Ramblings of General Geekery

Mercurial’s onsub and mixed sub-repos

If you’re using Mercurial with mixed sub-repositories (i.e. sub-repositories handled by different revision control systems), you may be interested in this: I just got a patch accepted into the onsub extension.

The extension lets you run commands on your sub-repositories. For example, with my own dotfiles repository, running on Windows:

> hg onsub "echo I'm in %HG_SUBPATH%"
I'm in lib\hg\hg-git
I'm in lib\hg\onsub
I'm in vim\bundle\badwolf
I'm in vim/bundle/colorschemes
I'm in vim/bundle/commentary
I'm in vim/bundle/ctrlp
I'm in vim/bundle/easymotion
I'm in vim/bundle/fugitive
I'm in vim\bundle\gundo
I'm in vim/bundle/haml
I'm in vim\bundle\lawrencium
I'm in vim/bundle/markdown
I'm in vim/bundle/nerdtree
I'm in vim\bundle\piecrust
I'm in vim/bundle/powerline
I'm in vim/bundle/ragtag
I'm in vim/bundle/repeat
I'm in vim/bundle/solarized
I'm in vim/bundle/supertab
I'm in vim/bundle/surround
I'm in vim/bundle/syntastic
I'm in vim/bundle/vimroom

As you can see, I’ve got quite a few sub-repos. However, some are Mercurial sub-repos, while others are Git sub-repos (that’s one of the nice features of Mercurial: it has decent interop with other RCSes). Which ones are which, though? That’s easy, there’s a new HG_SUBTYPE environment variable now:

> hg onsub "echo I'm in [%HG_SUBTYPE%]%HG_SUBPATH%"
I'm in [hg]lib\hg\hg-git
I'm in [hg]lib\hg\onsub
I'm in [hg]vim\bundle\badwolf
I'm in [git]vim/bundle/colorschemes
I'm in [git]vim/bundle/commentary
I'm in [git]vim/bundle/ctrlp
I'm in [git]vim/bundle/easymotion
I'm in [git]vim/bundle/fugitive
I'm in [hg]vim\bundle\gundo
I'm in [git]vim/bundle/haml
I'm in [hg]vim\bundle\lawrencium
I'm in [git]vim/bundle/markdown
I'm in [git]vim/bundle/nerdtree
I'm in [hg]vim\bundle\piecrust
I'm in [git]vim/bundle/powerline
I'm in [git]vim/bundle/ragtag
I'm in [git]vim/bundle/repeat
I'm in [git]vim/bundle/solarized
I'm in [git]vim/bundle/supertab
I'm in [git]vim/bundle/surround
I'm in [git]vim/bundle/syntastic
I'm in [git]vim/bundle/vimroom

That makes it possible to do something slightly different depending on the sub-repo type, but it’s still tedious. For example, the most common operation for me is to pull and update all those sub-repos. The commands are different (hg pull -u vs. git pull) and doing an if statement in Bash or Cmd is cumbersome, especially as a one-liner argument.

That’s where the other new feature comes in: there’s a new -t/--type option that filters sub-repos based on their type:

> hg onsub -t hg "echo Mercurial subrepo: %HG_SUBPATH%"
Mercurial subrepo: lib\hg\hg-git
Mercurial subrepo: lib\hg\onsub
Mercurial subrepo: vim\bundle\badwolf
Mercurial subrepo: vim\bundle\gundo
Mercurial subrepo: vim\bundle\lawrencium
Mercurial subrepo: vim\bundle\piecrust

This makes it easy to bring all the sub-repos up to date:

> hg onsub -t hg "hg pull -u"
> hg onsub -t git "git pull"

Hopefully it makes life easier for a few other people out there… it sure does for me!