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?
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.