5

I need simple hook for mercurial that checks commit comment using pattern. Here is my hook:

#!/usr/bin/env python
#
# save as .hg/check_whitespace.py and make executable

import re

def check_comment(comment):
    #
    print 'Checking comment...'
    pattern = '^((Issue \d+:)|(No Issue:)).+'
    if re.match(pattern, comment, flags=re.IGNORECASE):
        return 1
    else:
        print >> sys.stderr, 'Comment does not match pattern. You must start it with "Issue 12323:" or "No Issue:"'
        return 0

if __name__ == '__main__':
    import os, sys
    comment=os.popen('hg tip --template "{desc}"').read()
    if not check_comment(comment):
        sys.exit(1)
sys.exit(0)

It works. It even shows error message 'Comment does not match pattern. You must start it with "Issue 12323:" or "No Issue:"' when I commit from console. But when I trying to commit from Tortoise Hg Workbench, only system message is shown: abort: pretxncommit.check_comment hook exited with status 1.

I need to inform user what is wrong. Is there any way to force Tortoise Hg to show output from hook?

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
Victor Haydin
  • 3,518
  • 2
  • 26
  • 41

2 Answers2

5

I got it to work by making it an in-process hook rather than an external hook. In-process hooks are defined quite differently, however.

First, the python file needs only a single function that will be called by the name in the hook definition. The hook function is passed ui, repo, and hooktype objects. It is also passed additional objects based on the type of hook. For pretrxncommit, it is passed node, parent1, and parent2, but you're only interested in node, so the rest are gathered in kwargs. The ui object is used to give the status and error messages.

Contents of check_comment.py:

#!/usr/bin/env python

import re

def check_comment(ui, repo, hooktype, node=None, **kwargs):
    ui.status('Checking comment...\n')
    comment = repo[node].description()
    pattern = '^((Issue \d+:)|(No Issue:)).+'
    if not re.match(pattern, comment, flags=re.IGNORECASE):
        ui.warn('Comment does not match pattern. You must start it with "Issue 12323:" or "No Issue:"\n')
        return True

In the hgrc, the hook would be defined with python:/path/to/file.py:function_name, like this:

[hooks]
pretxncommit.check_comment = python:/path/to/check_comment.py:check_comment

The .suffix_name on pretxncommit is to avoid overriding any globally defined hook, especially if this is defined in the repository's hgrc rather than the global one. Suffixes are how one allows multiple responses to the same hook.

Joel B Fant
  • 24,406
  • 4
  • 66
  • 67
0

In case the hook runs on a repository that is served via e.g. hgserve:
I use this small Python function in a pretxnchangegroup script to show the same output

  • in the server log
  • in the TortoiseHg workbench Log pan or the cmd line

:

def log(ui, string):
    print(string) # will show up as "remote:" on the client
    ui.status("{0}\n".format(string)) # will show up in the same hg process: hgserve ; append newline
    return 
jan
  • 1,581
  • 2
  • 19
  • 34