Предотвратить запуск хука mercurial precommit на histedit

Я хотел бы запустить clang-format (на самом деле clang-format-diff.py, чтобы отформатировать только то, что изменилось) для кода, который я фиксирую в Mercurial автоматически. Я знаю, что могу сделать это с помощью хука предварительной фиксации. На самом деле, я делал это в прошлом, но это испортило некоторые исторические данные, поэтому я удалил хук, и теперь сделайте это вручную, запустив команду перед фиксацией.

Очевидно, проблема в том, что я могу и иногда забываю это сделать.

Есть ли способ запустить хук только для «обычных» коммитов, а не для histedit или rebase?


person MikMik    schedule 23.11.2015    source источник


Ответы (2)


Насколько я знаю, прямого пути нет. Но вы можете создать себе псевдоним для использования вместо 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=
person planetmaker    schedule 23.11.2015

Чтобы обернуть одну команду (в вашем случае commit), вы можете использовать либо псевдоним, либо расширение. Подход псевдонимов довольно прост, но имеет некоторые недостатки. Пример псевдонима:

commit = !$HG commit --config alias.commit=commit --config hooks.precommit.clang=/tmp/msg "$@"

Есть несколько тонких моментов, связанных с созданием такого псевдонима: во-первых, обычные псевдонимы не принимают параметр --config (вся конфигурация уже проанализирована в момент раскрытия псевдонима). Поэтому нам нужно использовать псевдоним оболочки (!$HG), чтобы обойти эту проблему; во-вторых, чтобы избежать застревания в рекурсии во время раскрытия псевдонима оболочки (в отличие от обычных псевдонимов, Mercurial не может сделать этого для псевдонимов оболочки), мы должны реализовывать commit самому себе (отсюда часть --config alias.commit=commit).

Этот подход имеет несколько недостатков: во-первых, он удваивает время запуска (поскольку Mercurial вызывается дважды для псевдонима оболочки); хотя это относительно небольшие накладные расходы, этого может быть достаточно, чтобы раздражать пользователя-человека. Во-вторых, плохо взаимодействует со скриптами; сценарии и графические интерфейсы могут либо непреднамеренно использовать псевдоним, когда они не собираются этого делать, либо (что еще хуже) отключать его, тем самым обходя ловушку.

Альтернативой является использование расширения для переноса команды 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)

Инструкции по использованию расширения см. в комментарии к документу.

person Reimer Behrends    schedule 23.11.2015