[PATCH] New hook for checking commit messages over multiple repositories

Matt Doar matt at xensource.com
Tue Sep 12 21:33:14 UTC 2006


This hook makes it easier to check that commit messages contain a 
particular pattern for multiple repositories. Configuration uses a 
central repo like the notify hook.

Feedback welcome.

~Matt

# HG changeset patch
# User Matt Doar <matt at xensource.com>
# Date 1158096441 25200
# Node ID 6185b946fec6479d3a93608cc98731bef11d557b
# Parent  e86c654ba432422731cb5200cae5d26256bc2d5d
New hook for checking commit messages over multiple repositories

diff -r e86c654ba432 -r 6185b946fec6 hgext/message.py
--- /dev/null    Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext/message.py    Tue Sep 12 14:27:21 2006 -0700
@@ -0,0 +1,89 @@
+# message.py - check mercurial commit messages against a pattern
+#
+# Copyright (c) 2006 XenSource
+# Author: Matthew Doar
+#
+# This software may be used and distributed according to the terms
+# of the GNU General Public License, incorporated herein by reference.
+#
+# Hook extension to require a particular commit message format
+#
+# To use, configure message extension and enable in hgrc like this:
+#
+#   [extensions]
+#   hgext.message =
+#
+#   [hooks]
+#   pretxncommit.needs_bug_identifier = python:hgext.message.hook
+
+#   [message]
+#   config = /path/to/file # file containing repositories to check
+#
+#   # OPTIONAL: the format can be specified outside the config file
+#   # but the config file takes priority
+#   format = [A-Z]+-[\d]+
+#
+# The message config file has same format as regular hgrc and can be
+# combined with a notify config file.
+#
+#   [message]
+#   # regex is a Python regex that the commit message must contain to
+#   # be accepted as a valid commit message
+#   format = [A-Z]+-[\d]+
+#
+# If you like, you can put notify/message config file in repo that 
users can
+# push changes to, they can manage their own subscriptions.
+
+from mercurial.demandload import *
+from mercurial.i18n import gettext as _
+from mercurial.node import *
+demandload(globals(), 'getpass mercurial:util')
+import re
+
+class checker(object):
+    '''Commit message checking class.'''
+
+    def __init__(self, ui, repo):
+        self.ui = ui
+        self.repo = repo
+        ui.debug(_('message: repo: %s\n') % str(repo.root))
+        self.checking = True
+        self.cfg = self.ui.config('message', 'config')
+        if self.cfg:
+            ui.debug(_('message: reading config from: ' + self.cfg + '\n'))
+            self.ui.readconfig(self.cfg)
+            self.pat = self.ui.config('message', 'format')
+            if self.pat:
+                ui.debug(_('message: format from config file: %s\n') % 
self.pat)
+            else:
+                ui.debug(_('message: no format specified, so accepting 
all commit messages\n'))
+                self.checking = False
+        else:
+            # See if there is a local format defined
+            self.pat = self.ui.config('message', 'format')
+            if self.pat:
+                ui.debug(_('message: format from hgrc: %s\n') % self.pat)
+                self.cfg = str(self.repo.root) + '/.hg/hgrc'
+            else:
+                ui.debug(_('message: no config or format specified, so 
accepting all commit messages\n'))
+                self.checking = False
+
+    def check(self, node):
+        '''Return if message format is allowed, raise an exception if 
not.'''
+        text = self.repo.changelog.read(bin(node))[4]
+        self.ui.debug(_('message: text: %s\n') % text)
+        if not self.checking:
+            return
+        p = re.compile(self.pat)
+        if p.search(text):
+            return
+        else:
+            raise util.Abort(_('message: Commit message\n"%s"\ndoes not 
contain the required pattern: %s\nTo change this, edit %s') % (text, 
self.pat, self.cfg))
+
+def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
+    '''check commit message format.'''
+    if hooktype != 'pretxncommit':
+        raise util.Abort(_('config error - hook type "%s" cannot check '
+                           'incoming commit messages') % hooktype)
+    c = checker(ui, repo)
+    c.check(node)




More information about the Mercurial mailing list