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.
- JIRA_USER, JIRA_PASSWORD -- developer's credentials.
- JIRA_TICKET_PATTERN -- pattern that will search ticket references.
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.
# 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);
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'
tickets = JIRA_TICKET_PATTERN.findall(message)
if not tickets:
if len(tickets) > 1:
ticket = tickets
issue = proxy.jira1.getIssue(auth, ticket)
except xmlrpclib.Fault, e:
if e.faultString.find(FAULT_MSG_ISSUE_NOT_FOUND) >= 0:
# Check if issue is subtask or task-split
if issue['type'] == '8' or issue['type'] == '5':
proxy = xmlrpclib.ServerProxy(JIRA_XMLRPC)
auth = proxy.jira1.login(JIRA_USER, JIRA_PASSWORD)
print >> sys.stderr, 'Cannot connect to Jira: ' + str(sys.exc_info())
msg_file = open(sys.argv, 'r')
msg = msg_file.read()
err_msg = check_message(msg)
print >> sys.stderr, 'Error: %s\nCommit message:\n%s' % (err_msg, msg)