2015-11-23 7 views
1

Je voudrais exécuter clang-format (en fait clang-format-diff.py, pour formater uniquement ce qui a changé) sur le code que je commets dans Mercurial automatiquement. Je sais que je peux le faire avec un crochet précommit. En fait, je l'ai fait dans le passé, mais it messed up some histedits, donc j'ai retiré le crochet, et maintenant le faire manuellement, en exécutant la commande avant de valider.Empêcher mercurial precommit de s'exécuter sur histedit

De toute évidence, le problème est que je peux, et j'oublie de le faire parfois.

Existe-t-il un moyen d'exécuter le hook uniquement sur les validations "normales", pas celles sur histedit ou rebase?

Répondre

2

Il n'y a pas de chemin direct autant que je sache. Mais vous pouvez créer vous-même un alias à utiliser à la place de rebase et histedit, appelons-les hrebase et hhistedit qui désactivent le hook pour leur utilisation.

Pour désactiver un crochet pour une seule course sur la ligne de commande, vous pouvez utiliser --config hook.HOOKNAME=, ainsi, par exemple:

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

et vous définissez ainsi votre alias:

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

Pour pour envelopper une seule commande (dans votre cas, commit) vous pouvez utiliser un alias ou une extension. L'approche alias est assez simple, mais présente quelques inconvénients. Exemple pour un alias:

commit = !$HG commit --config alias.commit=commit --config hooks.precommit.clang=/tmp/msg "[email protected]" 

Il y a quelques problèmes subtils impliqués dans la création d'un tel alias: d'abord, alias normaux n'acceptent pas --config paramater (toute la configuration a déjà été analysé au point d'expansion alias). Par conséquent, nous devons utiliser un alias shell (!$HG) afin de contourner ce problème; deuxièmement, afin d'éviter de rester bloqué dans une récursion lors de l'expansion de l'alias shell (contrairement aux alias normaux, Mercurial ne peut pas le faire pour les alias shell), nous devons lui faire des realias (d'où la partie --config alias.commit=commit).

Cette approche a quelques inconvénients: d'abord, elle double le temps de démarrage (parce que Mercurial est invoqué deux fois pour un alias shell); Bien que ce soit relativement peu de frais généraux, il peut être suffisant d'être ennuyeux pour un utilisateur humain. Deuxièmement, il interagit mal avec les scripts; Les scripts et les interfaces graphiques peuvent involontairement utiliser l'alias quand ils ne le souhaitent pas ou (pire) le désactiver, contournant ainsi le hook.

Une alternative consiste à utiliser une extension pour enrouler la commande commit. Par exemple:

# 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) 

Consultez le commentaire doc pour savoir comment utiliser l'extension.