Commit-msg Hook

Every developer must have this hook on his local machine in order to:

  • Commit codes locally several times then pushes it to the server.

  • Merge auto-commits with auto-messages without referencing to a Jira ticket.

The commit-msg hook is a python script file and it must be placed in the developer's local repository as: .git/hooks/commit-msg.  There is no server-side hook required.

The following settings must be configured in the script file:

  • JIRA_XMLRPC -- path to Jira.
    Example: https://jira.example.com/rpc/xmlrpc

  • JIRA_USERJIRA_PASSWORD -- developer's credentials.

  • JIRA_TICKET_PATTERN -- pattern that will search ticket references.
    Example: re.compile(r'\[(\w+7-\d+?)\]')

In Linux and OSX, this file must have executable permissions in the file system; in Windows, setting this permission is not necessary.  To use the hook in Windows without python installed, see Python on Windows FAQ ».

See the commit-msg hook code on the right panel or download the sample commit-msg file , make the necessary changes, and place it in the required folder.

The commit-msg hook is a python script file that must be located in the developer's local repository.

Sample contents of the commit-msg file:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 #!/usr/bin/python # # This script is intended to be run as a commit-msg script in a GIT # repository and check the presence of Jira ticket numbers in the log messages. # # - NO_Jira_TICKET_MESSAGE (an error message returned to the user when the # svn commit message doesn't contain a jira ticket); # - INVALID_JIRA_TICKET_MESSAGE (an error message returned to the user when # the svn commit message contains an invalid jira ticket); # - JIRA_XMLRPC (url of the Jira XML-RPC server); # - JIRA_USER (name of the Jira user who has permission to look up issues in # the Jira server); # - JIRA_PASSWORD (password of the Jira user described above); import sys import re import xmlrpclib NO_JIRA_TICKET_MESSAGE = \ 'No Jira ticket present in the commit message. \ Please include the Jira ticket enclosed in brackets: [ABC-789].' INVALID_JIRA_TICKET_MESSAGE = \ 'Proper Jira ticket syntax was found, but none were valid tickets. \ Please check the tickets and try again.' TOO_MANY_JIRA_TICKETS_MESSAGE = \ 'Only 1 Jira ticket is allowed per commit. Please commit only 1 change at a time.' INVALID_ISSUE_TYPE_MESSAGE = \ 'You may not commit against subtasks or task-splits. \ Please commit against the parent ticket.' JIRA_XMLRPC = 'https://jira.example.com/rpc/xmlrpc' JIRA_USER = 'user' JIRA_PASSWORD = 'password' JIRA_TICKET_PATTERN = re.compile(r'\[(\w+?-\d+?)\]') FAULT_MSG_ISSUE_NOT_FOUND = 'com.atlassian.jira.rpc.exception.RemotePermissionException' def check_message(message): tickets = JIRA_TICKET_PATTERN.findall(message) if not tickets: return NO_JIRA_TICKET_MESSAGE if len(tickets) > 1: return TOO_MANY_JIRA_TICKETS_MESSAGE ticket = tickets[0] try: issue = proxy.jira1.getIssue(auth, ticket) except xmlrpclib.Fault, e: if e.faultString.find(FAULT_MSG_ISSUE_NOT_FOUND) >= 0: return INVALID_JIRA_TICKET_MESSAGE else: raise # Check if issue is subtask or task-split if issue['type'] == '8' or issue['type'] == '5': return INVALID_ISSUE_TYPE_MESSAGE return None proxy = xmlrpclib.ServerProxy(JIRA_XMLRPC) try: auth = proxy.jira1.login(JIRA_USER, JIRA_PASSWORD) except: print >> sys.stderr, 'Cannot connect to Jira: ' + str(sys.exc_info()[1]) sys.exit(2) msg_file = open(sys.argv[1], 'r') msg = msg_file.read() err_msg = check_message(msg) if err_msg: print >> sys.stderr, 'Error: %s\nCommit message:\n%s' % (err_msg, msg) sys.exit(1)