【问题标题】:Prevent mercurial precommit hook from running on histedit防止 mercurial precommit hook 在 histedit 上运行
【发布时间】:2015-11-23 10:19:34
【问题描述】:

我想对我在 Mercurial 中自动提交的代码运行 clang-format(实际上是 clang-format-diff.py,仅格式化更改的内容)。我知道我可以使用预提交钩子来做到这一点。事实上,我过去做过,但是it messed up some histedits,所以我去掉了钩子,现在手动做,在提交之前运行命令。

很明显,问题是我可以而且确实有时会忘记这样做。

有没有办法只在“正常”提交上运行挂钩,而不是在 histedit 或 rebase 上运行?

【问题讨论】:

    标签: mercurial mercurial-hook


    【解决方案1】:

    据我所知,没有直接的方法。但是您可以为自己创建一个别名来代替 rebase 和 histedit,让我们称它们为 hrebase 和 hhistedit,它们会禁用钩子以供其使用。

    为了在命令行上禁用单次运行的钩子,您可以使用--config hook.HOOKNAME=,例如:

    hg --config hook.HOOKNAME= rebase -d2 -b5
    

    然后你定义你的别名:

    [alias]
    hrebase = rebase --config hook.HOOKNAME=
    hhistedit = histedit --config hook.HOOKNAME=
    

    【讨论】:

      【解决方案2】:

      为了包装单个命令(在您的情况下为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)
      

      有关如何使用扩展程序的说明,请参阅文档注释。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-11-09
        • 1970-01-01
        • 2018-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-07
        相关资源
        最近更新 更多