Search code examples
mercurialmercurial-hook

Using hooks vs. wrapping commands in mercurial


What are the relative pros and cons for using hooks vs. using an extension that wraps a command for a particular task?

In other words, what are the criteria for deciding whether to use hooks or wrap a command?

Please also list the cases where one approach is the only option. One case I can think of is to add new arguments for existing commands. You could also change/remove arguments, for example I default log to log -g but graphlog aborts in the presence of some "incompatible" arguments (see graphlog.check_unsupported_flags), so I added a log wrapper to remove -g in those cases, because forced abortion is a crime against humanity.

It feels like hooks are more clean-cut. Python hooks run in the hg process so there's no performance issue. And while it's easy to use extensions.wrapcommand to create command wrappers, it's trivial to create/disable hooks, and to adjust the order in which they are applied (they should be self-contained in the first place).

And here's a quote from hgrc doc that recommends standard hooks over pre/post command hooks, but it also applies to hooks over wrapper:

... hooks like "commit" will be called in all contexts that generate a commit (e.g. tag) and not just the commit command.

Also I guess that hooks are not subjected to GPL (or are they?), whereas command wrappers in extensions are.

(I hope a 1.5k+ user can create a mercurialhooks tag. Git fan boys have beaten us with githooks.)


Solution

  • I can't speak to licensing issues, but the biggest difference between a hook and an extension is that a hook can be written in any language whereas extensions are always python.

    If one's writing in python then there's little difference between a hook and an extension:

    • either can delve deeply into mercurial internals
    • both require users modify their .hgrc to enable them
    • both can wrap/intercept commands

    I think your log command argument modification could be done with a pre-log hook in addition to being done as an extension.

    TL;DR: If you're writing in python there's little difference, and if you're not hooks are your only option.