为了包装单个命令(在您的情况下为commit),您可以使用别名或扩展名。别名方法相当简单,但有一些缺点。别名示例:
commit = !$HG commit --config alias.commit=commit --config hooks.precommit.clang=/tmp/msg "$@"
创建这样的别名涉及一些微妙的问题:首先,普通别名不接受--config 参数(所有配置在别名扩展时都已被解析)。因此,我们需要使用 shell 别名 (!$HG) 来解决这个问题;其次,为了避免在 shell 别名扩展期间陷入递归(与普通别名不同,Mercurial 不能对 shell 别名执行此操作),我们必须将 commit 重新定义为自身(因此 --config alias.commit=commit 部分)。
这种方法有几个缺点:首先,它使启动时间加倍(因为 Mercurial 被调用两次以获得 shell 别名);虽然这相对较少的开销,但对于人类用户来说已经足够烦人了。其次,它与脚本的交互很差;脚本和 GUI 可能会在不打算使用别名时无意使用别名,或者(更糟糕的是)禁用别名,从而绕过钩子。
另一种方法是使用扩展来包装commit 命令。例如:
# Simple extension to provide a hook for manual commits only
"""hook for manual commits
This extension allows the selective definition of a hook for
manual commits only (i.e. outside graft, histedit, rebase, etc.).
In order to use it, add the following lines to your ``.hg/hgrc`` or
``~/.hgrc`` file::
[extensions]
manualcommithook=/path/to/extension
[hooks]
premanualcommit=/path/to/hook
The ``hooks.premanualcommit`` hook will then be (temporarily) installed
under ``hooks.precommit.manual``, but only for manual commits.
"""
from mercurial import commands, extensions
def commit_with_hook(original_cmd, ui, repo, *pats, **opts):
hook = ui.config("hooks", "premanualcommit")
if hook:
if ui.config("hooks", "precommit.manual"):
ui.warn("overriding existing precommit.manual hook\n")
ui.setconfig("hooks", "precommit.manual", hook)
return original_cmd(ui, repo, *pats, **opts)
def uisetup(ui):
extensions.wrapcommand(commands.table, "commit", commit_with_hook)
有关如何使用扩展程序的说明,请参阅文档注释。